[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * WordPress Upgrade API 4 * 5 * Most of the functions are pluggable and can be overwritten. 6 * 7 * @package WordPress 8 * @subpackage Administration 9 */ 10 11 /** Include user installation customization script. */ 12 if ( file_exists( WP_CONTENT_DIR . '/install.php' ) ) { 13 require WP_CONTENT_DIR . '/install.php'; 14 } 15 16 /** WordPress Administration API */ 17 require_once ABSPATH . 'wp-admin/includes/admin.php'; 18 19 /** WordPress Schema API */ 20 require_once ABSPATH . 'wp-admin/includes/schema.php'; 21 22 if ( ! function_exists( 'wp_install' ) ) : 23 /** 24 * Installs the site. 25 * 26 * Runs the required functions to set up and populate the database, 27 * including primary admin user and initial options. 28 * 29 * @since 2.1.0 30 * 31 * @param string $blog_title Site title. 32 * @param string $user_name User's username. 33 * @param string $user_email User's email. 34 * @param bool $is_public Whether the site is public. 35 * @param string $deprecated Optional. Not used. 36 * @param string $user_password Optional. User's chosen password. Default empty (random password). 37 * @param string $language Optional. Language chosen. Default empty. 38 * @return array { 39 * Data for the newly installed site. 40 * 41 * @type string $url The URL of the site. 42 * @type int $user_id The ID of the site owner. 43 * @type string $password The password of the site owner, if their user account didn't already exist. 44 * @type string $password_message The explanatory message regarding the password. 45 * } 46 */ 47 function wp_install( 48 $blog_title, 49 $user_name, 50 $user_email, 51 $is_public, 52 $deprecated = '', 53 #[\SensitiveParameter] 54 $user_password = '', 55 $language = '' 56 ) { 57 if ( ! empty( $deprecated ) ) { 58 _deprecated_argument( __FUNCTION__, '2.6.0' ); 59 } 60 61 wp_check_mysql_version(); 62 wp_cache_flush(); 63 make_db_current_silent(); 64 65 /* 66 * Ensure update checks are delayed after installation. 67 * 68 * This prevents users being presented with a maintenance mode screen 69 * immediately after installation. 70 */ 71 wp_unschedule_hook( 'wp_version_check' ); 72 wp_unschedule_hook( 'wp_update_plugins' ); 73 wp_unschedule_hook( 'wp_update_themes' ); 74 75 wp_schedule_event( time() + HOUR_IN_SECONDS, 'twicedaily', 'wp_version_check' ); 76 wp_schedule_event( time() + ( 1.5 * HOUR_IN_SECONDS ), 'twicedaily', 'wp_update_plugins' ); 77 wp_schedule_event( time() + ( 2 * HOUR_IN_SECONDS ), 'twicedaily', 'wp_update_themes' ); 78 79 populate_options(); 80 populate_roles(); 81 82 update_option( 'blogname', $blog_title ); 83 update_option( 'admin_email', $user_email ); 84 update_option( 'blog_public', $is_public ); 85 86 // Freshness of site - in the future, this could get more specific about actions taken, perhaps. 87 update_option( 'fresh_site', 1, false ); 88 89 if ( $language ) { 90 update_option( 'WPLANG', $language ); 91 } 92 93 $guessurl = wp_guess_url(); 94 95 update_option( 'siteurl', $guessurl ); 96 97 // If not a public site, don't ping. 98 if ( ! $is_public ) { 99 update_option( 'default_pingback_flag', 0 ); 100 } 101 102 /* 103 * Create default user. If the user already exists, the user tables are 104 * being shared among sites. Just set the role in that case. 105 */ 106 $user_id = username_exists( $user_name ); 107 $user_password = trim( $user_password ); 108 $email_password = false; 109 $user_created = false; 110 111 if ( ! $user_id && empty( $user_password ) ) { 112 $user_password = wp_generate_password( 12, false ); 113 $message = __( '<strong><em>Note that password</em></strong> carefully! It is a <em>random</em> password that was generated just for you.' ); 114 $user_id = wp_create_user( $user_name, $user_password, $user_email ); 115 update_user_meta( $user_id, 'default_password_nag', true ); 116 $email_password = true; 117 $user_created = true; 118 } elseif ( ! $user_id ) { 119 // Password has been provided. 120 $message = '<em>' . __( 'Your chosen password.' ) . '</em>'; 121 $user_id = wp_create_user( $user_name, $user_password, $user_email ); 122 $user_created = true; 123 } else { 124 $message = __( 'User already exists. Password inherited.' ); 125 } 126 127 $user = new WP_User( $user_id ); 128 $user->set_role( 'administrator' ); 129 130 if ( $user_created ) { 131 $user->user_url = $guessurl; 132 wp_update_user( $user ); 133 } 134 135 wp_install_defaults( $user_id ); 136 137 wp_install_maybe_enable_pretty_permalinks(); 138 139 flush_rewrite_rules(); 140 141 wp_new_blog_notification( $blog_title, $guessurl, $user_id, ( $email_password ? $user_password : __( 'The password you chose during installation.' ) ) ); 142 143 wp_cache_flush(); 144 145 /** 146 * Fires after a site is fully installed. 147 * 148 * @since 3.9.0 149 * 150 * @param WP_User $user The site owner. 151 */ 152 do_action( 'wp_install', $user ); 153 154 return array( 155 'url' => $guessurl, 156 'user_id' => $user_id, 157 'password' => $user_password, 158 'password_message' => $message, 159 ); 160 } 161 endif; 162 163 if ( ! function_exists( 'wp_install_defaults' ) ) : 164 /** 165 * Creates the initial content for a newly-installed site. 166 * 167 * Adds the default "Uncategorized" category, the first post (with comment), 168 * first page, and default widgets for default theme for the current version. 169 * 170 * @since 2.1.0 171 * 172 * @global wpdb $wpdb WordPress database abstraction object. 173 * @global WP_Rewrite $wp_rewrite WordPress rewrite component. 174 * @global string $table_prefix The database table prefix. 175 * 176 * @param int $user_id User ID. 177 */ 178 function wp_install_defaults( $user_id ) { 179 global $wpdb, $wp_rewrite, $table_prefix; 180 181 // Default category. 182 $cat_name = __( 'Uncategorized' ); 183 /* translators: Default category slug. */ 184 $cat_slug = sanitize_title( _x( 'Uncategorized', 'Default category slug' ) ); 185 186 $cat_id = 1; 187 188 $wpdb->insert( 189 $wpdb->terms, 190 array( 191 'term_id' => $cat_id, 192 'name' => $cat_name, 193 'slug' => $cat_slug, 194 'term_group' => 0, 195 ) 196 ); 197 $wpdb->insert( 198 $wpdb->term_taxonomy, 199 array( 200 'term_id' => $cat_id, 201 'taxonomy' => 'category', 202 'description' => '', 203 'parent' => 0, 204 'count' => 1, 205 ) 206 ); 207 $cat_tt_id = $wpdb->insert_id; 208 209 // First post. 210 $now = current_time( 'mysql' ); 211 $now_gmt = current_time( 'mysql', true ); 212 $first_post_guid = get_option( 'home' ) . '/?p=1'; 213 214 if ( is_multisite() ) { 215 $first_post = get_site_option( 'first_post' ); 216 217 if ( ! $first_post ) { 218 $first_post = "<!-- wp:paragraph -->\n<p>" . 219 /* translators: First post content. %s: Site link. */ 220 __( 'Welcome to %s. This is your first post. Edit or delete it, then start writing!' ) . 221 "</p>\n<!-- /wp:paragraph -->"; 222 } 223 224 $first_post = sprintf( 225 $first_post, 226 sprintf( '<a href="%s">%s</a>', esc_url( network_home_url() ), get_network()->site_name ) 227 ); 228 229 // Back-compat for pre-4.4. 230 $first_post = str_replace( 'SITE_URL', esc_url( network_home_url() ), $first_post ); 231 $first_post = str_replace( 'SITE_NAME', get_network()->site_name, $first_post ); 232 } else { 233 $first_post = "<!-- wp:paragraph -->\n<p>" . 234 /* translators: First post content. %s: Site link. */ 235 __( 'Welcome to WordPress. This is your first post. Edit or delete it, then start writing!' ) . 236 "</p>\n<!-- /wp:paragraph -->"; 237 } 238 239 $wpdb->insert( 240 $wpdb->posts, 241 array( 242 'post_author' => $user_id, 243 'post_date' => $now, 244 'post_date_gmt' => $now_gmt, 245 'post_content' => $first_post, 246 'post_excerpt' => '', 247 'post_title' => __( 'Hello world!' ), 248 /* translators: Default post slug. */ 249 'post_name' => sanitize_title( _x( 'hello-world', 'Default post slug' ) ), 250 'post_modified' => $now, 251 'post_modified_gmt' => $now_gmt, 252 'guid' => $first_post_guid, 253 'comment_count' => 1, 254 'to_ping' => '', 255 'pinged' => '', 256 'post_content_filtered' => '', 257 ) 258 ); 259 260 if ( is_multisite() ) { 261 update_posts_count(); 262 } 263 264 $wpdb->insert( 265 $wpdb->term_relationships, 266 array( 267 'term_taxonomy_id' => $cat_tt_id, 268 'object_id' => 1, 269 ) 270 ); 271 272 // Default comment. 273 if ( is_multisite() ) { 274 $first_comment_author = get_site_option( 'first_comment_author' ); 275 $first_comment_email = get_site_option( 'first_comment_email' ); 276 $first_comment_url = get_site_option( 'first_comment_url', network_home_url() ); 277 $first_comment = get_site_option( 'first_comment' ); 278 } 279 280 $first_comment_author = ! empty( $first_comment_author ) ? $first_comment_author : __( 'A WordPress Commenter' ); 281 $first_comment_email = ! empty( $first_comment_email ) ? $first_comment_email : 'wapuu@wordpress.example'; 282 $first_comment_url = ! empty( $first_comment_url ) ? $first_comment_url : esc_url( __( 'https://wordpress.org/' ) ); 283 $first_comment = ! empty( $first_comment ) ? $first_comment : sprintf( 284 /* translators: %s: Gravatar URL. */ 285 __( 286 'Hi, this is a comment. 287 To get started with moderating, editing, and deleting comments, please visit the Comments screen in the dashboard. 288 Commenter avatars come from <a href="%s">Gravatar</a>.' 289 ), 290 /* translators: The localized Gravatar URL. */ 291 esc_url( __( 'https://gravatar.com/' ) ) 292 ); 293 $wpdb->insert( 294 $wpdb->comments, 295 array( 296 'comment_post_ID' => 1, 297 'comment_author' => $first_comment_author, 298 'comment_author_email' => $first_comment_email, 299 'comment_author_url' => $first_comment_url, 300 'comment_date' => $now, 301 'comment_date_gmt' => $now_gmt, 302 'comment_content' => $first_comment, 303 'comment_type' => 'comment', 304 ) 305 ); 306 307 // First page. 308 if ( is_multisite() ) { 309 $first_page = get_site_option( 'first_page' ); 310 } 311 312 if ( empty( $first_page ) ) { 313 $first_page = "<!-- wp:paragraph -->\n<p>"; 314 /* translators: First page content. */ 315 $first_page .= __( "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:" ); 316 $first_page .= "</p>\n<!-- /wp:paragraph -->\n\n"; 317 318 $first_page .= "<!-- wp:quote -->\n<blockquote class=\"wp-block-quote\">\n<!-- wp:paragraph -->\n<p>"; 319 /* translators: First page content. */ 320 $first_page .= __( "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.)" ); 321 $first_page .= "</p>\n<!-- /wp:paragraph -->\n</blockquote>\n<!-- /wp:quote -->\n\n"; 322 323 $first_page .= "<!-- wp:paragraph -->\n<p>"; 324 /* translators: First page content. */ 325 $first_page .= __( '...or something like this:' ); 326 $first_page .= "</p>\n<!-- /wp:paragraph -->\n\n"; 327 328 $first_page .= "<!-- wp:quote -->\n<blockquote class=\"wp-block-quote\">\n<!-- wp:paragraph -->\n<p>"; 329 /* translators: First page content. */ 330 $first_page .= __( '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.' ); 331 $first_page .= "</p>\n<!-- /wp:paragraph -->\n</blockquote>\n<!-- /wp:quote -->\n\n"; 332 333 $first_page .= "<!-- wp:paragraph -->\n<p>"; 334 $first_page .= sprintf( 335 /* translators: First page content. %s: Site admin URL. */ 336 __( '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!' ), 337 admin_url() 338 ); 339 $first_page .= "</p>\n<!-- /wp:paragraph -->"; 340 } 341 342 $first_post_guid = get_option( 'home' ) . '/?page_id=2'; 343 $wpdb->insert( 344 $wpdb->posts, 345 array( 346 'post_author' => $user_id, 347 'post_date' => $now, 348 'post_date_gmt' => $now_gmt, 349 'post_content' => $first_page, 350 'post_excerpt' => '', 351 'comment_status' => 'closed', 352 'post_title' => __( 'Sample Page' ), 353 /* translators: Default page slug. */ 354 'post_name' => __( 'sample-page' ), 355 'post_modified' => $now, 356 'post_modified_gmt' => $now_gmt, 357 'guid' => $first_post_guid, 358 'post_type' => 'page', 359 'to_ping' => '', 360 'pinged' => '', 361 'post_content_filtered' => '', 362 ) 363 ); 364 $wpdb->insert( 365 $wpdb->postmeta, 366 array( 367 'post_id' => 2, 368 'meta_key' => '_wp_page_template', 369 'meta_value' => 'default', 370 ) 371 ); 372 373 // Privacy Policy page. 374 if ( is_multisite() ) { 375 // Disable by default unless the suggested content is provided. 376 $privacy_policy_content = get_site_option( 'default_privacy_policy_content' ); 377 } else { 378 if ( ! class_exists( 'WP_Privacy_Policy_Content' ) ) { 379 require_once ABSPATH . 'wp-admin/includes/class-wp-privacy-policy-content.php'; 380 } 381 382 $privacy_policy_content = WP_Privacy_Policy_Content::get_default_content(); 383 } 384 385 if ( ! empty( $privacy_policy_content ) ) { 386 $privacy_policy_guid = get_option( 'home' ) . '/?page_id=3'; 387 388 $wpdb->insert( 389 $wpdb->posts, 390 array( 391 'post_author' => $user_id, 392 'post_date' => $now, 393 'post_date_gmt' => $now_gmt, 394 'post_content' => $privacy_policy_content, 395 'post_excerpt' => '', 396 'comment_status' => 'closed', 397 'post_title' => __( 'Privacy Policy' ), 398 /* translators: Privacy Policy page slug. */ 399 'post_name' => __( 'privacy-policy' ), 400 'post_modified' => $now, 401 'post_modified_gmt' => $now_gmt, 402 'guid' => $privacy_policy_guid, 403 'post_type' => 'page', 404 'post_status' => 'draft', 405 'to_ping' => '', 406 'pinged' => '', 407 'post_content_filtered' => '', 408 ) 409 ); 410 $wpdb->insert( 411 $wpdb->postmeta, 412 array( 413 'post_id' => 3, 414 'meta_key' => '_wp_page_template', 415 'meta_value' => 'default', 416 ) 417 ); 418 update_option( 'wp_page_for_privacy_policy', 3 ); 419 } 420 421 // Set up default widgets for default theme. 422 update_option( 423 'widget_block', 424 array( 425 2 => array( 'content' => '<!-- wp:search /-->' ), 426 3 => array( 'content' => '<!-- wp:group --><div class="wp-block-group"><!-- wp:heading --><h2>' . __( 'Recent Posts' ) . '</h2><!-- /wp:heading --><!-- wp:latest-posts /--></div><!-- /wp:group -->' ), 427 4 => array( 'content' => '<!-- wp:group --><div class="wp-block-group"><!-- wp:heading --><h2>' . __( 'Recent Comments' ) . '</h2><!-- /wp:heading --><!-- wp:latest-comments {"displayAvatar":false,"displayDate":false,"displayExcerpt":false} /--></div><!-- /wp:group -->' ), 428 5 => array( 'content' => '<!-- wp:group --><div class="wp-block-group"><!-- wp:heading --><h2>' . __( 'Archives' ) . '</h2><!-- /wp:heading --><!-- wp:archives /--></div><!-- /wp:group -->' ), 429 6 => array( 'content' => '<!-- wp:group --><div class="wp-block-group"><!-- wp:heading --><h2>' . __( 'Categories' ) . '</h2><!-- /wp:heading --><!-- wp:categories /--></div><!-- /wp:group -->' ), 430 '_multiwidget' => 1, 431 ) 432 ); 433 update_option( 434 'sidebars_widgets', 435 array( 436 'wp_inactive_widgets' => array(), 437 'sidebar-1' => array( 438 0 => 'block-2', 439 1 => 'block-3', 440 2 => 'block-4', 441 ), 442 'sidebar-2' => array( 443 0 => 'block-5', 444 1 => 'block-6', 445 ), 446 'array_version' => 3, 447 ) 448 ); 449 450 if ( ! is_multisite() ) { 451 update_user_meta( $user_id, 'show_welcome_panel', 1 ); 452 } elseif ( ! is_super_admin( $user_id ) && ! metadata_exists( 'user', $user_id, 'show_welcome_panel' ) ) { 453 update_user_meta( $user_id, 'show_welcome_panel', 2 ); 454 } 455 456 if ( is_multisite() ) { 457 // Flush rules to pick up the new page. 458 $wp_rewrite->init(); 459 $wp_rewrite->flush_rules(); 460 461 $user = new WP_User( $user_id ); 462 $wpdb->update( $wpdb->options, array( 'option_value' => $user->user_email ), array( 'option_name' => 'admin_email' ) ); 463 464 // Remove all perms except for the login user. 465 $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->usermeta WHERE user_id != %d AND meta_key = %s", $user_id, $table_prefix . 'user_level' ) ); 466 $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->usermeta WHERE user_id != %d AND meta_key = %s", $user_id, $table_prefix . 'capabilities' ) ); 467 468 /* 469 * Delete any caps that snuck into the previously active blog. (Hardcoded to blog 1 for now.) 470 * TODO: Get previous_blog_id. 471 */ 472 if ( ! is_super_admin( $user_id ) && 1 !== $user_id ) { 473 $wpdb->delete( 474 $wpdb->usermeta, 475 array( 476 'user_id' => $user_id, 477 'meta_key' => $wpdb->base_prefix . '1_capabilities', 478 ) 479 ); 480 } 481 } 482 } 483 endif; 484 485 /** 486 * Maybe enable pretty permalinks on installation. 487 * 488 * If after enabling pretty permalinks don't work, fallback to query-string permalinks. 489 * 490 * @since 4.2.0 491 * 492 * @global WP_Rewrite $wp_rewrite WordPress rewrite component. 493 * 494 * @return bool Whether pretty permalinks are enabled. False otherwise. 495 */ 496 function wp_install_maybe_enable_pretty_permalinks() { 497 global $wp_rewrite; 498 499 // Bail if a permalink structure is already enabled. 500 if ( get_option( 'permalink_structure' ) ) { 501 return true; 502 } 503 504 /* 505 * The Permalink structures to attempt. 506 * 507 * The first is designed for mod_rewrite or nginx rewriting. 508 * 509 * The second is PATHINFO-based permalinks for web server configurations 510 * without a true rewrite module enabled. 511 */ 512 $permalink_structures = array( 513 '/%year%/%monthnum%/%day%/%postname%/', 514 '/index.php/%year%/%monthnum%/%day%/%postname%/', 515 ); 516 517 foreach ( (array) $permalink_structures as $permalink_structure ) { 518 $wp_rewrite->set_permalink_structure( $permalink_structure ); 519 520 /* 521 * Flush rules with the hard option to force refresh of the web-server's 522 * rewrite config file (e.g. .htaccess or web.config). 523 */ 524 $wp_rewrite->flush_rules( true ); 525 526 $test_url = ''; 527 528 // Test against a real WordPress post. 529 $first_post = get_page_by_path( sanitize_title( _x( 'hello-world', 'Default post slug' ) ), OBJECT, 'post' ); 530 if ( $first_post ) { 531 $test_url = get_permalink( $first_post->ID ); 532 } 533 534 /* 535 * Send a request to the site, and check whether 536 * the 'X-Pingback' header is returned as expected. 537 * 538 * Uses wp_remote_get() instead of wp_remote_head() because web servers 539 * can block head requests. 540 */ 541 $response = wp_remote_get( $test_url, array( 'timeout' => 5 ) ); 542 $x_pingback_header = wp_remote_retrieve_header( $response, 'X-Pingback' ); 543 $pretty_permalinks = $x_pingback_header && get_bloginfo( 'pingback_url' ) === $x_pingback_header; 544 545 if ( $pretty_permalinks ) { 546 return true; 547 } 548 } 549 550 /* 551 * If it makes it this far, pretty permalinks failed. 552 * Fallback to query-string permalinks. 553 */ 554 $wp_rewrite->set_permalink_structure( '' ); 555 $wp_rewrite->flush_rules( true ); 556 557 return false; 558 } 559 560 if ( ! function_exists( 'wp_new_blog_notification' ) ) : 561 /** 562 * Notifies the site admin that the installation of WordPress is complete. 563 * 564 * Sends an email to the new administrator that the installation is complete 565 * and provides them with a record of their login credentials. 566 * 567 * @since 2.1.0 568 * 569 * @param string $blog_title Site title. 570 * @param string $blog_url Site URL. 571 * @param int $user_id Administrator's user ID. 572 * @param string $password Administrator's password. Note that a placeholder message is 573 * usually passed instead of the actual password. 574 */ 575 function wp_new_blog_notification( 576 $blog_title, 577 $blog_url, 578 $user_id, 579 #[\SensitiveParameter] 580 $password 581 ) { 582 $user = new WP_User( $user_id ); 583 $email = $user->user_email; 584 $name = $user->user_login; 585 $login_url = wp_login_url(); 586 587 $message = sprintf( 588 /* translators: New site notification email. 1: New site URL, 2: User login, 3: User password or password reset link, 4: Login URL. */ 589 __( 590 'Your new WordPress site has been successfully set up at: 591 592 %1$s 593 594 You can log in to the administrator account with the following information: 595 596 Username: %2$s 597 Password: %3$s 598 Log in here: %4$s 599 600 We hope you enjoy your new site. Thanks! 601 602 --The WordPress Team 603 https://wordpress.org/ 604 ' 605 ), 606 $blog_url, 607 $name, 608 $password, 609 $login_url 610 ); 611 612 $installed_email = array( 613 'to' => $email, 614 'subject' => __( 'New WordPress Site' ), 615 'message' => $message, 616 'headers' => '', 617 ); 618 619 /** 620 * Filters the contents of the email sent to the site administrator when WordPress is installed. 621 * 622 * @since 5.6.0 623 * 624 * @param array $installed_email { 625 * Used to build wp_mail(). 626 * 627 * @type string $to The email address of the recipient. 628 * @type string $subject The subject of the email. 629 * @type string $message The content of the email. 630 * @type string $headers Headers. 631 * } 632 * @param WP_User $user The site administrator user object. 633 * @param string $blog_title The site title. 634 * @param string $blog_url The site URL. 635 * @param string $password The site administrator's password. Note that a placeholder message 636 * is usually passed instead of the user's actual password. 637 */ 638 $installed_email = apply_filters( 'wp_installed_email', $installed_email, $user, $blog_title, $blog_url, $password ); 639 640 wp_mail( 641 $installed_email['to'], 642 $installed_email['subject'], 643 $installed_email['message'], 644 $installed_email['headers'] 645 ); 646 } 647 endif; 648 649 if ( ! function_exists( 'wp_upgrade' ) ) : 650 /** 651 * Runs WordPress Upgrade functions. 652 * 653 * Upgrades the database if needed during a site update. 654 * 655 * @since 2.1.0 656 * 657 * @global int $wp_current_db_version The old (current) database version. 658 * @global int $wp_db_version The new database version. 659 */ 660 function wp_upgrade() { 661 global $wp_current_db_version, $wp_db_version; 662 663 $wp_current_db_version = (int) __get_option( 'db_version' ); 664 665 // We are up to date. Nothing to do. 666 if ( $wp_db_version === $wp_current_db_version ) { 667 return; 668 } 669 670 if ( ! is_blog_installed() ) { 671 return; 672 } 673 674 wp_check_mysql_version(); 675 wp_cache_flush(); 676 pre_schema_upgrade(); 677 make_db_current_silent(); 678 upgrade_all(); 679 if ( is_multisite() && is_main_site() ) { 680 upgrade_network(); 681 } 682 wp_cache_flush(); 683 684 if ( is_multisite() ) { 685 update_site_meta( get_current_blog_id(), 'db_version', $wp_db_version ); 686 update_site_meta( get_current_blog_id(), 'db_last_updated', microtime() ); 687 } 688 689 delete_transient( 'wp_core_block_css_files' ); 690 691 /** 692 * Fires after a site is fully upgraded. 693 * 694 * @since 3.9.0 695 * 696 * @param int $wp_db_version The new $wp_db_version. 697 * @param int $wp_current_db_version The old (current) $wp_db_version. 698 */ 699 do_action( 'wp_upgrade', $wp_db_version, $wp_current_db_version ); 700 } 701 endif; 702 703 /** 704 * Functions to be called in installation and upgrade scripts. 705 * 706 * Contains conditional checks to determine which upgrade scripts to run, 707 * based on database version and WP version being updated-to. 708 * 709 * @ignore 710 * @since 1.0.1 711 * 712 * @global int $wp_current_db_version The old (current) database version. 713 * @global int $wp_db_version The new database version. 714 */ 715 function upgrade_all() { 716 global $wp_current_db_version, $wp_db_version; 717 718 $wp_current_db_version = (int) __get_option( 'db_version' ); 719 720 // We are up to date. Nothing to do. 721 if ( $wp_db_version === $wp_current_db_version ) { 722 return; 723 } 724 725 // If the version is not set in the DB, try to guess the version. 726 if ( empty( $wp_current_db_version ) ) { 727 $wp_current_db_version = 0; 728 729 // If the template option exists, we have 1.5. 730 $template = __get_option( 'template' ); 731 if ( ! empty( $template ) ) { 732 $wp_current_db_version = 2541; 733 } 734 } 735 736 if ( $wp_current_db_version < 6039 ) { 737 upgrade_230_options_table(); 738 } 739 740 populate_options(); 741 742 if ( $wp_current_db_version < 2541 ) { 743 upgrade_100(); 744 upgrade_101(); 745 upgrade_110(); 746 upgrade_130(); 747 } 748 749 if ( $wp_current_db_version < 3308 ) { 750 upgrade_160(); 751 } 752 753 if ( $wp_current_db_version < 4772 ) { 754 upgrade_210(); 755 } 756 757 if ( $wp_current_db_version < 4351 ) { 758 upgrade_old_slugs(); 759 } 760 761 if ( $wp_current_db_version < 5539 ) { 762 upgrade_230(); 763 } 764 765 if ( $wp_current_db_version < 6124 ) { 766 upgrade_230_old_tables(); 767 } 768 769 if ( $wp_current_db_version < 7499 ) { 770 upgrade_250(); 771 } 772 773 if ( $wp_current_db_version < 7935 ) { 774 upgrade_252(); 775 } 776 777 if ( $wp_current_db_version < 8201 ) { 778 upgrade_260(); 779 } 780 781 if ( $wp_current_db_version < 8989 ) { 782 upgrade_270(); 783 } 784 785 if ( $wp_current_db_version < 10360 ) { 786 upgrade_280(); 787 } 788 789 if ( $wp_current_db_version < 11958 ) { 790 upgrade_290(); 791 } 792 793 if ( $wp_current_db_version < 15260 ) { 794 upgrade_300(); 795 } 796 797 if ( $wp_current_db_version < 19389 ) { 798 upgrade_330(); 799 } 800 801 if ( $wp_current_db_version < 20080 ) { 802 upgrade_340(); 803 } 804 805 if ( $wp_current_db_version < 22422 ) { 806 upgrade_350(); 807 } 808 809 if ( $wp_current_db_version < 25824 ) { 810 upgrade_370(); 811 } 812 813 if ( $wp_current_db_version < 26148 ) { 814 upgrade_372(); 815 } 816 817 if ( $wp_current_db_version < 26691 ) { 818 upgrade_380(); 819 } 820 821 if ( $wp_current_db_version < 29630 ) { 822 upgrade_400(); 823 } 824 825 if ( $wp_current_db_version < 33055 ) { 826 upgrade_430(); 827 } 828 829 if ( $wp_current_db_version < 33056 ) { 830 upgrade_431(); 831 } 832 833 if ( $wp_current_db_version < 35700 ) { 834 upgrade_440(); 835 } 836 837 if ( $wp_current_db_version < 36686 ) { 838 upgrade_450(); 839 } 840 841 if ( $wp_current_db_version < 37965 ) { 842 upgrade_460(); 843 } 844 845 if ( $wp_current_db_version < 44719 ) { 846 upgrade_510(); 847 } 848 849 if ( $wp_current_db_version < 45744 ) { 850 upgrade_530(); 851 } 852 853 if ( $wp_current_db_version < 48575 ) { 854 upgrade_550(); 855 } 856 857 if ( $wp_current_db_version < 49752 ) { 858 upgrade_560(); 859 } 860 861 if ( $wp_current_db_version < 51917 ) { 862 upgrade_590(); 863 } 864 865 if ( $wp_current_db_version < 53011 ) { 866 upgrade_600(); 867 } 868 869 if ( $wp_current_db_version < 55853 ) { 870 upgrade_630(); 871 } 872 873 if ( $wp_current_db_version < 56657 ) { 874 upgrade_640(); 875 } 876 877 if ( $wp_current_db_version < 57155 ) { 878 upgrade_650(); 879 } 880 881 if ( $wp_current_db_version < 58975 ) { 882 upgrade_670(); 883 } 884 885 if ( $wp_current_db_version < 60421 ) { 886 upgrade_682(); 887 } 888 889 maybe_disable_link_manager(); 890 891 maybe_disable_automattic_widgets(); 892 893 update_option( 'db_version', $wp_db_version ); 894 update_option( 'db_upgraded', true ); 895 } 896 897 /** 898 * Execute changes made in WordPress 1.0. 899 * 900 * @ignore 901 * @since 1.0.0 902 * 903 * @global wpdb $wpdb WordPress database abstraction object. 904 */ 905 function upgrade_100() { 906 global $wpdb; 907 908 // Get the title and ID of every post, post_name to check if it already has a value. 909 $posts = $wpdb->get_results( "SELECT ID, post_title, post_name FROM $wpdb->posts WHERE post_name = ''" ); 910 if ( $posts ) { 911 foreach ( $posts as $post ) { 912 if ( '' === $post->post_name ) { 913 $newtitle = sanitize_title( $post->post_title ); 914 $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_name = %s WHERE ID = %d", $newtitle, $post->ID ) ); 915 } 916 } 917 } 918 919 $categories = $wpdb->get_results( "SELECT cat_ID, cat_name, category_nicename FROM $wpdb->categories" ); 920 foreach ( $categories as $category ) { 921 if ( '' === $category->category_nicename ) { 922 $newtitle = sanitize_title( $category->cat_name ); 923 $wpdb->update( $wpdb->categories, array( 'category_nicename' => $newtitle ), array( 'cat_ID' => $category->cat_ID ) ); 924 } 925 } 926 927 $sql = "UPDATE $wpdb->options 928 SET option_value = REPLACE(option_value, 'wp-links/links-images/', 'wp-images/links/') 929 WHERE option_name LIKE %s 930 AND option_value LIKE %s"; 931 $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( 'links_rating_image' ) . '%', $wpdb->esc_like( 'wp-links/links-images/' ) . '%' ) ); 932 933 $done_ids = $wpdb->get_results( "SELECT DISTINCT post_id FROM $wpdb->post2cat" ); 934 if ( $done_ids ) : 935 $done_posts = array(); 936 foreach ( $done_ids as $done_id ) : 937 $done_posts[] = $done_id->post_id; 938 endforeach; 939 $catwhere = ' AND ID NOT IN (' . implode( ',', $done_posts ) . ')'; 940 else : 941 $catwhere = ''; 942 endif; 943 944 $allposts = $wpdb->get_results( "SELECT ID, post_category FROM $wpdb->posts WHERE post_category != '0' $catwhere" ); 945 if ( $allposts ) : 946 foreach ( $allposts as $post ) { 947 // Check to see if it's already been imported. 948 $cat = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->post2cat WHERE post_id = %d AND category_id = %d", $post->ID, $post->post_category ) ); 949 if ( ! $cat && 0 !== (int) $post->post_category ) { // If there's no result. 950 $wpdb->insert( 951 $wpdb->post2cat, 952 array( 953 'post_id' => $post->ID, 954 'category_id' => $post->post_category, 955 ) 956 ); 957 } 958 } 959 endif; 960 } 961 962 /** 963 * Execute changes made in WordPress 1.0.1. 964 * 965 * @ignore 966 * @since 1.0.1 967 * 968 * @global wpdb $wpdb WordPress database abstraction object. 969 */ 970 function upgrade_101() { 971 global $wpdb; 972 973 // Clean up indices, add a few. 974 add_clean_index( $wpdb->posts, 'post_name' ); 975 add_clean_index( $wpdb->posts, 'post_status' ); 976 add_clean_index( $wpdb->categories, 'category_nicename' ); 977 add_clean_index( $wpdb->comments, 'comment_approved' ); 978 add_clean_index( $wpdb->comments, 'comment_post_ID' ); 979 add_clean_index( $wpdb->links, 'link_category' ); 980 add_clean_index( $wpdb->links, 'link_visible' ); 981 } 982 983 /** 984 * Execute changes made in WordPress 1.2. 985 * 986 * @ignore 987 * @since 1.2.0 988 * @since 6.8.0 User passwords are no longer hashed with md5. 989 * 990 * @global wpdb $wpdb WordPress database abstraction object. 991 */ 992 function upgrade_110() { 993 global $wpdb; 994 995 // Set user_nicename. 996 $users = $wpdb->get_results( "SELECT ID, user_nickname, user_nicename FROM $wpdb->users" ); 997 foreach ( $users as $user ) { 998 if ( '' === $user->user_nicename ) { 999 $newname = sanitize_title( $user->user_nickname ); 1000 $wpdb->update( $wpdb->users, array( 'user_nicename' => $newname ), array( 'ID' => $user->ID ) ); 1001 } 1002 } 1003 1004 // Get the GMT offset, we'll use that later on. 1005 $all_options = get_alloptions_110(); 1006 1007 $time_difference = $all_options->time_difference; 1008 1009 $server_time = time() + (int) gmdate( 'Z' ); 1010 $weblogger_time = $server_time + $time_difference * HOUR_IN_SECONDS; 1011 $gmt_time = time(); 1012 1013 $diff_gmt_server = ( $gmt_time - $server_time ) / HOUR_IN_SECONDS; 1014 $diff_weblogger_server = ( $weblogger_time - $server_time ) / HOUR_IN_SECONDS; 1015 $diff_gmt_weblogger = $diff_gmt_server - $diff_weblogger_server; 1016 $gmt_offset = -$diff_gmt_weblogger; 1017 1018 // Add a gmt_offset option, with value $gmt_offset. 1019 add_option( 'gmt_offset', $gmt_offset ); 1020 1021 /* 1022 * Check if we already set the GMT fields. If we did, then 1023 * MAX(post_date_gmt) can't be '0000-00-00 00:00:00'. 1024 * <michel_v> I just slapped myself silly for not thinking about it earlier. 1025 */ 1026 $got_gmt_fields = ( '0000-00-00 00:00:00' !== $wpdb->get_var( "SELECT MAX(post_date_gmt) FROM $wpdb->posts" ) ); 1027 1028 if ( ! $got_gmt_fields ) { 1029 1030 // Add or subtract time to all dates, to get GMT dates. 1031 $add_hours = (int) $diff_gmt_weblogger; 1032 $add_minutes = (int) ( 60 * ( $diff_gmt_weblogger - $add_hours ) ); 1033 $wpdb->query( "UPDATE $wpdb->posts SET post_date_gmt = DATE_ADD(post_date, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)" ); 1034 $wpdb->query( "UPDATE $wpdb->posts SET post_modified = post_date" ); 1035 $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'" ); 1036 $wpdb->query( "UPDATE $wpdb->comments SET comment_date_gmt = DATE_ADD(comment_date, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)" ); 1037 $wpdb->query( "UPDATE $wpdb->users SET user_registered = DATE_ADD(user_registered, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)" ); 1038 } 1039 } 1040 1041 /** 1042 * Execute changes made in WordPress 1.5. 1043 * 1044 * @ignore 1045 * @since 1.5.0 1046 * 1047 * @global wpdb $wpdb WordPress database abstraction object. 1048 */ 1049 function upgrade_130() { 1050 global $wpdb; 1051 1052 // Remove extraneous backslashes. 1053 $posts = $wpdb->get_results( "SELECT ID, post_title, post_content, post_excerpt, guid, post_date, post_name, post_status, post_author FROM $wpdb->posts" ); 1054 if ( $posts ) { 1055 foreach ( $posts as $post ) { 1056 $post_content = addslashes( deslash( $post->post_content ) ); 1057 $post_title = addslashes( deslash( $post->post_title ) ); 1058 $post_excerpt = addslashes( deslash( $post->post_excerpt ) ); 1059 if ( empty( $post->guid ) ) { 1060 $guid = get_permalink( $post->ID ); 1061 } else { 1062 $guid = $post->guid; 1063 } 1064 1065 $wpdb->update( $wpdb->posts, compact( 'post_title', 'post_content', 'post_excerpt', 'guid' ), array( 'ID' => $post->ID ) ); 1066 1067 } 1068 } 1069 1070 // Remove extraneous backslashes. 1071 $comments = $wpdb->get_results( "SELECT comment_ID, comment_author, comment_content FROM $wpdb->comments" ); 1072 if ( $comments ) { 1073 foreach ( $comments as $comment ) { 1074 $comment_content = deslash( $comment->comment_content ); 1075 $comment_author = deslash( $comment->comment_author ); 1076 1077 $wpdb->update( $wpdb->comments, compact( 'comment_content', 'comment_author' ), array( 'comment_ID' => $comment->comment_ID ) ); 1078 } 1079 } 1080 1081 // Remove extraneous backslashes. 1082 $links = $wpdb->get_results( "SELECT link_id, link_name, link_description FROM $wpdb->links" ); 1083 if ( $links ) { 1084 foreach ( $links as $link ) { 1085 $link_name = deslash( $link->link_name ); 1086 $link_description = deslash( $link->link_description ); 1087 1088 $wpdb->update( $wpdb->links, compact( 'link_name', 'link_description' ), array( 'link_id' => $link->link_id ) ); 1089 } 1090 } 1091 1092 $active_plugins = __get_option( 'active_plugins' ); 1093 1094 /* 1095 * If plugins are not stored in an array, they're stored in the old 1096 * newline separated format. Convert to new format. 1097 */ 1098 if ( ! is_array( $active_plugins ) ) { 1099 $active_plugins = explode( "\n", trim( $active_plugins ) ); 1100 update_option( 'active_plugins', $active_plugins ); 1101 } 1102 1103 // Obsolete tables. 1104 $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optionvalues' ); 1105 $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiontypes' ); 1106 $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiongroups' ); 1107 $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiongroup_options' ); 1108 1109 // Update comments table to use comment_type. 1110 $wpdb->query( "UPDATE $wpdb->comments SET comment_type='trackback', comment_content = REPLACE(comment_content, '<trackback />', '') WHERE comment_content LIKE '<trackback />%'" ); 1111 $wpdb->query( "UPDATE $wpdb->comments SET comment_type='pingback', comment_content = REPLACE(comment_content, '<pingback />', '') WHERE comment_content LIKE '<pingback />%'" ); 1112 1113 // Some versions have multiple duplicate option_name rows with the same values. 1114 $options = $wpdb->get_results( "SELECT option_name, COUNT(option_name) AS dupes FROM `$wpdb->options` GROUP BY option_name" ); 1115 foreach ( $options as $option ) { 1116 if ( $option->dupes > 1 ) { // Could this be done in the query? 1117 $limit = $option->dupes - 1; 1118 $dupe_ids = $wpdb->get_col( $wpdb->prepare( "SELECT option_id FROM $wpdb->options WHERE option_name = %s LIMIT %d", $option->option_name, $limit ) ); 1119 if ( $dupe_ids ) { 1120 $dupe_ids = implode( ',', $dupe_ids ); 1121 $wpdb->query( "DELETE FROM $wpdb->options WHERE option_id IN ($dupe_ids)" ); 1122 } 1123 } 1124 } 1125 1126 make_site_theme(); 1127 } 1128 1129 /** 1130 * Execute changes made in WordPress 2.0. 1131 * 1132 * @ignore 1133 * @since 2.0.0 1134 * 1135 * @global wpdb $wpdb WordPress database abstraction object. 1136 * @global int $wp_current_db_version The old (current) database version. 1137 */ 1138 function upgrade_160() { 1139 global $wpdb, $wp_current_db_version; 1140 1141 populate_roles_160(); 1142 1143 $users = $wpdb->get_results( "SELECT * FROM $wpdb->users" ); 1144 foreach ( $users as $user ) : 1145 if ( ! empty( $user->user_firstname ) ) { 1146 update_user_meta( $user->ID, 'first_name', wp_slash( $user->user_firstname ) ); 1147 } 1148 if ( ! empty( $user->user_lastname ) ) { 1149 update_user_meta( $user->ID, 'last_name', wp_slash( $user->user_lastname ) ); 1150 } 1151 if ( ! empty( $user->user_nickname ) ) { 1152 update_user_meta( $user->ID, 'nickname', wp_slash( $user->user_nickname ) ); 1153 } 1154 if ( ! empty( $user->user_level ) ) { 1155 update_user_meta( $user->ID, $wpdb->prefix . 'user_level', $user->user_level ); 1156 } 1157 if ( ! empty( $user->user_icq ) ) { 1158 update_user_meta( $user->ID, 'icq', wp_slash( $user->user_icq ) ); 1159 } 1160 if ( ! empty( $user->user_aim ) ) { 1161 update_user_meta( $user->ID, 'aim', wp_slash( $user->user_aim ) ); 1162 } 1163 if ( ! empty( $user->user_msn ) ) { 1164 update_user_meta( $user->ID, 'msn', wp_slash( $user->user_msn ) ); 1165 } 1166 if ( ! empty( $user->user_yim ) ) { 1167 update_user_meta( $user->ID, 'yim', wp_slash( $user->user_icq ) ); 1168 } 1169 if ( ! empty( $user->user_description ) ) { 1170 update_user_meta( $user->ID, 'description', wp_slash( $user->user_description ) ); 1171 } 1172 1173 if ( isset( $user->user_idmode ) ) : 1174 $idmode = $user->user_idmode; 1175 if ( 'nickname' === $idmode ) { 1176 $id = $user->user_nickname; 1177 } 1178 if ( 'login' === $idmode ) { 1179 $id = $user->user_login; 1180 } 1181 if ( 'firstname' === $idmode ) { 1182 $id = $user->user_firstname; 1183 } 1184 if ( 'lastname' === $idmode ) { 1185 $id = $user->user_lastname; 1186 } 1187 if ( 'namefl' === $idmode ) { 1188 $id = $user->user_firstname . ' ' . $user->user_lastname; 1189 } 1190 if ( 'namelf' === $idmode ) { 1191 $id = $user->user_lastname . ' ' . $user->user_firstname; 1192 } 1193 if ( ! $idmode ) { 1194 $id = $user->user_nickname; 1195 } 1196 $wpdb->update( $wpdb->users, array( 'display_name' => $id ), array( 'ID' => $user->ID ) ); 1197 endif; 1198 1199 // FIXME: RESET_CAPS is temporary code to reset roles and caps if flag is set. 1200 $caps = get_user_meta( $user->ID, $wpdb->prefix . 'capabilities' ); 1201 if ( empty( $caps ) || defined( 'RESET_CAPS' ) ) { 1202 $level = get_user_meta( $user->ID, $wpdb->prefix . 'user_level', true ); 1203 $role = translate_level_to_role( $level ); 1204 update_user_meta( $user->ID, $wpdb->prefix . 'capabilities', array( $role => true ) ); 1205 } 1206 1207 endforeach; 1208 $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' ); 1209 $wpdb->hide_errors(); 1210 foreach ( $old_user_fields as $old ) { 1211 $wpdb->query( "ALTER TABLE $wpdb->users DROP $old" ); 1212 } 1213 $wpdb->show_errors(); 1214 1215 // Populate comment_count field of posts table. 1216 $comments = $wpdb->get_results( "SELECT comment_post_ID, COUNT(*) as c FROM $wpdb->comments WHERE comment_approved = '1' GROUP BY comment_post_ID" ); 1217 if ( is_array( $comments ) ) { 1218 foreach ( $comments as $comment ) { 1219 $wpdb->update( $wpdb->posts, array( 'comment_count' => $comment->c ), array( 'ID' => $comment->comment_post_ID ) ); 1220 } 1221 } 1222 1223 /* 1224 * Some alpha versions used a post status of object instead of attachment 1225 * and put the mime type in post_type instead of post_mime_type. 1226 */ 1227 if ( $wp_current_db_version > 2541 && $wp_current_db_version <= 3091 ) { 1228 $objects = $wpdb->get_results( "SELECT ID, post_type FROM $wpdb->posts WHERE post_status = 'object'" ); 1229 foreach ( $objects as $object ) { 1230 $wpdb->update( 1231 $wpdb->posts, 1232 array( 1233 'post_status' => 'attachment', 1234 'post_mime_type' => $object->post_type, 1235 'post_type' => '', 1236 ), 1237 array( 'ID' => $object->ID ) 1238 ); 1239 1240 $meta = get_post_meta( $object->ID, 'imagedata', true ); 1241 if ( ! empty( $meta['file'] ) ) { 1242 update_attached_file( $object->ID, $meta['file'] ); 1243 } 1244 } 1245 } 1246 } 1247 1248 /** 1249 * Execute changes made in WordPress 2.1. 1250 * 1251 * @ignore 1252 * @since 2.1.0 1253 * 1254 * @global int $wp_current_db_version The old (current) database version. 1255 * @global wpdb $wpdb WordPress database abstraction object. 1256 */ 1257 function upgrade_210() { 1258 global $wp_current_db_version, $wpdb; 1259 1260 if ( $wp_current_db_version < 3506 ) { 1261 // Update status and type. 1262 $posts = $wpdb->get_results( "SELECT ID, post_status FROM $wpdb->posts" ); 1263 1264 if ( ! empty( $posts ) ) { 1265 foreach ( $posts as $post ) { 1266 $status = $post->post_status; 1267 $type = 'post'; 1268 1269 if ( 'static' === $status ) { 1270 $status = 'publish'; 1271 $type = 'page'; 1272 } elseif ( 'attachment' === $status ) { 1273 $status = 'inherit'; 1274 $type = 'attachment'; 1275 } 1276 1277 $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_status = %s, post_type = %s WHERE ID = %d", $status, $type, $post->ID ) ); 1278 } 1279 } 1280 } 1281 1282 if ( $wp_current_db_version < 3845 ) { 1283 populate_roles_210(); 1284 } 1285 1286 if ( $wp_current_db_version < 3531 ) { 1287 // Give future posts a post_status of future. 1288 $now = gmdate( 'Y-m-d H:i:59' ); 1289 $wpdb->query( "UPDATE $wpdb->posts SET post_status = 'future' WHERE post_status = 'publish' AND post_date_gmt > '$now'" ); 1290 1291 $posts = $wpdb->get_results( "SELECT ID, post_date FROM $wpdb->posts WHERE post_status ='future'" ); 1292 if ( ! empty( $posts ) ) { 1293 foreach ( $posts as $post ) { 1294 wp_schedule_single_event( mysql2date( 'U', $post->post_date, false ), 'publish_future_post', array( $post->ID ) ); 1295 } 1296 } 1297 } 1298 } 1299 1300 /** 1301 * Execute changes made in WordPress 2.3. 1302 * 1303 * @ignore 1304 * @since 2.3.0 1305 * 1306 * @global int $wp_current_db_version The old (current) database version. 1307 * @global wpdb $wpdb WordPress database abstraction object. 1308 */ 1309 function upgrade_230() { 1310 global $wp_current_db_version, $wpdb; 1311 1312 if ( $wp_current_db_version < 5200 ) { 1313 populate_roles_230(); 1314 } 1315 1316 // Convert categories to terms. 1317 $tt_ids = array(); 1318 $have_tags = false; 1319 $categories = $wpdb->get_results( "SELECT * FROM $wpdb->categories ORDER BY cat_ID" ); 1320 foreach ( $categories as $category ) { 1321 $term_id = (int) $category->cat_ID; 1322 $name = $category->cat_name; 1323 $description = $category->category_description; 1324 $slug = $category->category_nicename; 1325 $parent = $category->category_parent; 1326 $term_group = 0; 1327 1328 // Associate terms with the same slug in a term group and make slugs unique. 1329 $exists = $wpdb->get_results( $wpdb->prepare( "SELECT term_id, term_group FROM $wpdb->terms WHERE slug = %s", $slug ) ); 1330 if ( $exists ) { 1331 $term_group = $exists[0]->term_group; 1332 $id = $exists[0]->term_id; 1333 $num = 2; 1334 do { 1335 $alt_slug = $slug . "-$num"; 1336 ++$num; 1337 $slug_check = $wpdb->get_var( $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s", $alt_slug ) ); 1338 } while ( $slug_check ); 1339 1340 $slug = $alt_slug; 1341 1342 if ( empty( $term_group ) ) { 1343 $term_group = $wpdb->get_var( "SELECT MAX(term_group) FROM $wpdb->terms GROUP BY term_group" ) + 1; 1344 $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->terms SET term_group = %d WHERE term_id = %d", $term_group, $id ) ); 1345 } 1346 } 1347 1348 $wpdb->query( 1349 $wpdb->prepare( 1350 "INSERT INTO $wpdb->terms (term_id, name, slug, term_group) VALUES 1351 (%d, %s, %s, %d)", 1352 $term_id, 1353 $name, 1354 $slug, 1355 $term_group 1356 ) 1357 ); 1358 1359 $count = 0; 1360 if ( ! empty( $category->category_count ) ) { 1361 $count = (int) $category->category_count; 1362 $taxonomy = 'category'; 1363 $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 ) ); 1364 $tt_ids[ $term_id ][ $taxonomy ] = (int) $wpdb->insert_id; 1365 } 1366 1367 if ( ! empty( $category->link_count ) ) { 1368 $count = (int) $category->link_count; 1369 $taxonomy = 'link_category'; 1370 $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 ) ); 1371 $tt_ids[ $term_id ][ $taxonomy ] = (int) $wpdb->insert_id; 1372 } 1373 1374 if ( ! empty( $category->tag_count ) ) { 1375 $have_tags = true; 1376 $count = (int) $category->tag_count; 1377 $taxonomy = 'post_tag'; 1378 $wpdb->insert( $wpdb->term_taxonomy, compact( 'term_id', 'taxonomy', 'description', 'parent', 'count' ) ); 1379 $tt_ids[ $term_id ][ $taxonomy ] = (int) $wpdb->insert_id; 1380 } 1381 1382 if ( empty( $count ) ) { 1383 $count = 0; 1384 $taxonomy = 'category'; 1385 $wpdb->insert( $wpdb->term_taxonomy, compact( 'term_id', 'taxonomy', 'description', 'parent', 'count' ) ); 1386 $tt_ids[ $term_id ][ $taxonomy ] = (int) $wpdb->insert_id; 1387 } 1388 } 1389 1390 $select = 'post_id, category_id'; 1391 if ( $have_tags ) { 1392 $select .= ', rel_type'; 1393 } 1394 1395 $posts = $wpdb->get_results( "SELECT $select FROM $wpdb->post2cat GROUP BY post_id, category_id" ); 1396 foreach ( $posts as $post ) { 1397 $post_id = (int) $post->post_id; 1398 $term_id = (int) $post->category_id; 1399 $taxonomy = 'category'; 1400 if ( ! empty( $post->rel_type ) && 'tag' === $post->rel_type ) { 1401 $taxonomy = 'tag'; 1402 } 1403 $tt_id = $tt_ids[ $term_id ][ $taxonomy ]; 1404 if ( empty( $tt_id ) ) { 1405 continue; 1406 } 1407 1408 $wpdb->insert( 1409 $wpdb->term_relationships, 1410 array( 1411 'object_id' => $post_id, 1412 'term_taxonomy_id' => $tt_id, 1413 ) 1414 ); 1415 } 1416 1417 // < 3570 we used linkcategories. >= 3570 we used categories and link2cat. 1418 if ( $wp_current_db_version < 3570 ) { 1419 /* 1420 * Create link_category terms for link categories. Create a map of link 1421 * category IDs to link_category terms. 1422 */ 1423 $link_cat_id_map = array(); 1424 $default_link_cat = 0; 1425 $tt_ids = array(); 1426 $link_cats = $wpdb->get_results( 'SELECT cat_id, cat_name FROM ' . $wpdb->prefix . 'linkcategories' ); 1427 foreach ( $link_cats as $category ) { 1428 $cat_id = (int) $category->cat_id; 1429 $term_id = 0; 1430 $name = wp_slash( $category->cat_name ); 1431 $slug = sanitize_title( $name ); 1432 $term_group = 0; 1433 1434 // Associate terms with the same slug in a term group and make slugs unique. 1435 $exists = $wpdb->get_results( $wpdb->prepare( "SELECT term_id, term_group FROM $wpdb->terms WHERE slug = %s", $slug ) ); 1436 if ( $exists ) { 1437 $term_group = $exists[0]->term_group; 1438 $term_id = $exists[0]->term_id; 1439 } 1440 1441 if ( empty( $term_id ) ) { 1442 $wpdb->insert( $wpdb->terms, compact( 'name', 'slug', 'term_group' ) ); 1443 $term_id = (int) $wpdb->insert_id; 1444 } 1445 1446 $link_cat_id_map[ $cat_id ] = $term_id; 1447 $default_link_cat = $term_id; 1448 1449 $wpdb->insert( 1450 $wpdb->term_taxonomy, 1451 array( 1452 'term_id' => $term_id, 1453 'taxonomy' => 'link_category', 1454 'description' => '', 1455 'parent' => 0, 1456 'count' => 0, 1457 ) 1458 ); 1459 $tt_ids[ $term_id ] = (int) $wpdb->insert_id; 1460 } 1461 1462 // Associate links to categories. 1463 $links = $wpdb->get_results( "SELECT link_id, link_category FROM $wpdb->links" ); 1464 if ( ! empty( $links ) ) { 1465 foreach ( $links as $link ) { 1466 if ( 0 === (int) $link->link_category ) { 1467 continue; 1468 } 1469 if ( ! isset( $link_cat_id_map[ $link->link_category ] ) ) { 1470 continue; 1471 } 1472 $term_id = $link_cat_id_map[ $link->link_category ]; 1473 $tt_id = $tt_ids[ $term_id ]; 1474 if ( empty( $tt_id ) ) { 1475 continue; 1476 } 1477 1478 $wpdb->insert( 1479 $wpdb->term_relationships, 1480 array( 1481 'object_id' => $link->link_id, 1482 'term_taxonomy_id' => $tt_id, 1483 ) 1484 ); 1485 } 1486 } 1487 1488 // Set default to the last category we grabbed during the upgrade loop. 1489 update_option( 'default_link_category', $default_link_cat ); 1490 } else { 1491 $links = $wpdb->get_results( "SELECT link_id, category_id FROM $wpdb->link2cat GROUP BY link_id, category_id" ); 1492 foreach ( $links as $link ) { 1493 $link_id = (int) $link->link_id; 1494 $term_id = (int) $link->category_id; 1495 $taxonomy = 'link_category'; 1496 $tt_id = $tt_ids[ $term_id ][ $taxonomy ]; 1497 if ( empty( $tt_id ) ) { 1498 continue; 1499 } 1500 $wpdb->insert( 1501 $wpdb->term_relationships, 1502 array( 1503 'object_id' => $link_id, 1504 'term_taxonomy_id' => $tt_id, 1505 ) 1506 ); 1507 } 1508 } 1509 1510 if ( $wp_current_db_version < 4772 ) { 1511 // Obsolete linkcategories table. 1512 $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . 'linkcategories' ); 1513 } 1514 1515 // Recalculate all counts. 1516 $terms = $wpdb->get_results( "SELECT term_taxonomy_id, taxonomy FROM $wpdb->term_taxonomy" ); 1517 foreach ( (array) $terms as $term ) { 1518 if ( 'post_tag' === $term->taxonomy || 'category' === $term->taxonomy ) { 1519 $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 ) ); 1520 } else { 1521 $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d", $term->term_taxonomy_id ) ); 1522 } 1523 $wpdb->update( $wpdb->term_taxonomy, array( 'count' => $count ), array( 'term_taxonomy_id' => $term->term_taxonomy_id ) ); 1524 } 1525 } 1526 1527 /** 1528 * Remove old options from the database. 1529 * 1530 * @ignore 1531 * @since 2.3.0 1532 * 1533 * @global wpdb $wpdb WordPress database abstraction object. 1534 */ 1535 function upgrade_230_options_table() { 1536 global $wpdb; 1537 $old_options_fields = array( 'option_can_override', 'option_type', 'option_width', 'option_height', 'option_description', 'option_admin_level' ); 1538 $wpdb->hide_errors(); 1539 foreach ( $old_options_fields as $old ) { 1540 $wpdb->query( "ALTER TABLE $wpdb->options DROP $old" ); 1541 } 1542 $wpdb->show_errors(); 1543 } 1544 1545 /** 1546 * Remove old categories, link2cat, and post2cat database tables. 1547 * 1548 * @ignore 1549 * @since 2.3.0 1550 * 1551 * @global wpdb $wpdb WordPress database abstraction object. 1552 */ 1553 function upgrade_230_old_tables() { 1554 global $wpdb; 1555 $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . 'categories' ); 1556 $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . 'link2cat' ); 1557 $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . 'post2cat' ); 1558 } 1559 1560 /** 1561 * Upgrade old slugs made in version 2.2. 1562 * 1563 * @ignore 1564 * @since 2.2.0 1565 * 1566 * @global wpdb $wpdb WordPress database abstraction object. 1567 */ 1568 function upgrade_old_slugs() { 1569 // Upgrade people who were using the Redirect Old Slugs plugin. 1570 global $wpdb; 1571 $wpdb->query( "UPDATE $wpdb->postmeta SET meta_key = '_wp_old_slug' WHERE meta_key = 'old_slug'" ); 1572 } 1573 1574 /** 1575 * Execute changes made in WordPress 2.5.0. 1576 * 1577 * @ignore 1578 * @since 2.5.0 1579 * 1580 * @global int $wp_current_db_version The old (current) database version. 1581 */ 1582 function upgrade_250() { 1583 global $wp_current_db_version; 1584 1585 if ( $wp_current_db_version < 6689 ) { 1586 populate_roles_250(); 1587 } 1588 } 1589 1590 /** 1591 * Execute changes made in WordPress 2.5.2. 1592 * 1593 * @ignore 1594 * @since 2.5.2 1595 * 1596 * @global wpdb $wpdb WordPress database abstraction object. 1597 */ 1598 function upgrade_252() { 1599 global $wpdb; 1600 1601 $wpdb->query( "UPDATE $wpdb->users SET user_activation_key = ''" ); 1602 } 1603 1604 /** 1605 * Execute changes made in WordPress 2.6. 1606 * 1607 * @ignore 1608 * @since 2.6.0 1609 * 1610 * @global int $wp_current_db_version The old (current) database version. 1611 */ 1612 function upgrade_260() { 1613 global $wp_current_db_version; 1614 1615 if ( $wp_current_db_version < 8000 ) { 1616 populate_roles_260(); 1617 } 1618 } 1619 1620 /** 1621 * Execute changes made in WordPress 2.7. 1622 * 1623 * @ignore 1624 * @since 2.7.0 1625 * 1626 * @global int $wp_current_db_version The old (current) database version. 1627 * @global wpdb $wpdb WordPress database abstraction object. 1628 */ 1629 function upgrade_270() { 1630 global $wp_current_db_version, $wpdb; 1631 1632 if ( $wp_current_db_version < 8980 ) { 1633 populate_roles_270(); 1634 } 1635 1636 // Update post_date for unpublished posts with empty timestamp. 1637 if ( $wp_current_db_version < 8921 ) { 1638 $wpdb->query( "UPDATE $wpdb->posts SET post_date = post_modified WHERE post_date = '0000-00-00 00:00:00'" ); 1639 } 1640 } 1641 1642 /** 1643 * Execute changes made in WordPress 2.8. 1644 * 1645 * @ignore 1646 * @since 2.8.0 1647 * 1648 * @global int $wp_current_db_version The old (current) database version. 1649 * @global wpdb $wpdb WordPress database abstraction object. 1650 */ 1651 function upgrade_280() { 1652 global $wp_current_db_version, $wpdb; 1653 1654 if ( $wp_current_db_version < 10360 ) { 1655 populate_roles_280(); 1656 } 1657 if ( is_multisite() ) { 1658 $start = 0; 1659 while ( $rows = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options ORDER BY option_id LIMIT $start, 20" ) ) { 1660 foreach ( $rows as $row ) { 1661 $value = maybe_unserialize( $row->option_value ); 1662 if ( $value === $row->option_value ) { 1663 $value = stripslashes( $value ); 1664 } 1665 if ( $value !== $row->option_value ) { 1666 update_option( $row->option_name, $value ); 1667 } 1668 } 1669 $start += 20; 1670 } 1671 clean_blog_cache( get_current_blog_id() ); 1672 } 1673 } 1674 1675 /** 1676 * Execute changes made in WordPress 2.9. 1677 * 1678 * @ignore 1679 * @since 2.9.0 1680 * 1681 * @global int $wp_current_db_version The old (current) database version. 1682 */ 1683 function upgrade_290() { 1684 global $wp_current_db_version; 1685 1686 if ( $wp_current_db_version < 11958 ) { 1687 /* 1688 * Previously, setting depth to 1 would redundantly disable threading, 1689 * but now 2 is the minimum depth to avoid confusion. 1690 */ 1691 if ( 1 === (int) get_option( 'thread_comments_depth' ) ) { 1692 update_option( 'thread_comments_depth', 2 ); 1693 update_option( 'thread_comments', 0 ); 1694 } 1695 } 1696 } 1697 1698 /** 1699 * Execute changes made in WordPress 3.0. 1700 * 1701 * @ignore 1702 * @since 3.0.0 1703 * 1704 * @global int $wp_current_db_version The old (current) database version. 1705 * @global wpdb $wpdb WordPress database abstraction object. 1706 */ 1707 function upgrade_300() { 1708 global $wp_current_db_version, $wpdb; 1709 1710 if ( $wp_current_db_version < 15093 ) { 1711 populate_roles_300(); 1712 } 1713 1714 if ( $wp_current_db_version < 14139 && is_multisite() && is_main_site() && ! defined( 'MULTISITE' ) && get_site_option( 'siteurl' ) === false ) { 1715 add_site_option( 'siteurl', '' ); 1716 } 1717 1718 // 3.0 screen options key name changes. 1719 if ( wp_should_upgrade_global_tables() ) { 1720 $sql = "DELETE FROM $wpdb->usermeta 1721 WHERE meta_key LIKE %s 1722 OR meta_key LIKE %s 1723 OR meta_key LIKE %s 1724 OR meta_key LIKE %s 1725 OR meta_key LIKE %s 1726 OR meta_key LIKE %s 1727 OR meta_key = 'manageedittagscolumnshidden' 1728 OR meta_key = 'managecategoriescolumnshidden' 1729 OR meta_key = 'manageedit-tagscolumnshidden' 1730 OR meta_key = 'manageeditcolumnshidden' 1731 OR meta_key = 'categories_per_page' 1732 OR meta_key = 'edit_tags_per_page'"; 1733 $prefix = $wpdb->esc_like( $wpdb->base_prefix ); 1734 $wpdb->query( 1735 $wpdb->prepare( 1736 $sql, 1737 $prefix . '%' . $wpdb->esc_like( 'meta-box-hidden' ) . '%', 1738 $prefix . '%' . $wpdb->esc_like( 'closedpostboxes' ) . '%', 1739 $prefix . '%' . $wpdb->esc_like( 'manage-' ) . '%' . $wpdb->esc_like( '-columns-hidden' ) . '%', 1740 $prefix . '%' . $wpdb->esc_like( 'meta-box-order' ) . '%', 1741 $prefix . '%' . $wpdb->esc_like( 'metaboxorder' ) . '%', 1742 $prefix . '%' . $wpdb->esc_like( 'screen_layout' ) . '%' 1743 ) 1744 ); 1745 } 1746 } 1747 1748 /** 1749 * Execute changes made in WordPress 3.3. 1750 * 1751 * @ignore 1752 * @since 3.3.0 1753 * 1754 * @global int $wp_current_db_version The old (current) database version. 1755 * @global wpdb $wpdb WordPress database abstraction object. 1756 * @global array $wp_registered_widgets 1757 * @global array $sidebars_widgets 1758 */ 1759 function upgrade_330() { 1760 global $wp_current_db_version, $wpdb, $wp_registered_widgets, $sidebars_widgets; 1761 1762 if ( $wp_current_db_version < 19061 && wp_should_upgrade_global_tables() ) { 1763 $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key IN ('show_admin_bar_admin', 'plugins_last_view')" ); 1764 } 1765 1766 if ( $wp_current_db_version >= 11548 ) { 1767 return; 1768 } 1769 1770 $sidebars_widgets = get_option( 'sidebars_widgets', array() ); 1771 $_sidebars_widgets = array(); 1772 1773 if ( isset( $sidebars_widgets['wp_inactive_widgets'] ) || empty( $sidebars_widgets ) ) { 1774 $sidebars_widgets['array_version'] = 3; 1775 } elseif ( ! isset( $sidebars_widgets['array_version'] ) ) { 1776 $sidebars_widgets['array_version'] = 1; 1777 } 1778 1779 switch ( $sidebars_widgets['array_version'] ) { 1780 case 1: 1781 foreach ( (array) $sidebars_widgets as $index => $sidebar ) { 1782 if ( is_array( $sidebar ) ) { 1783 foreach ( (array) $sidebar as $i => $name ) { 1784 $id = strtolower( $name ); 1785 if ( isset( $wp_registered_widgets[ $id ] ) ) { 1786 $_sidebars_widgets[ $index ][ $i ] = $id; 1787 continue; 1788 } 1789 1790 $id = sanitize_title( $name ); 1791 if ( isset( $wp_registered_widgets[ $id ] ) ) { 1792 $_sidebars_widgets[ $index ][ $i ] = $id; 1793 continue; 1794 } 1795 1796 $found = false; 1797 1798 foreach ( $wp_registered_widgets as $widget_id => $widget ) { 1799 if ( strtolower( $widget['name'] ) === strtolower( $name ) ) { 1800 $_sidebars_widgets[ $index ][ $i ] = $widget['id']; 1801 1802 $found = true; 1803 break; 1804 } elseif ( sanitize_title( $widget['name'] ) === sanitize_title( $name ) ) { 1805 $_sidebars_widgets[ $index ][ $i ] = $widget['id']; 1806 1807 $found = true; 1808 break; 1809 } 1810 } 1811 1812 if ( $found ) { 1813 continue; 1814 } 1815 1816 unset( $_sidebars_widgets[ $index ][ $i ] ); 1817 } 1818 } 1819 } 1820 $_sidebars_widgets['array_version'] = 2; 1821 $sidebars_widgets = $_sidebars_widgets; 1822 unset( $_sidebars_widgets ); 1823 1824 // Intentional fall-through to upgrade to the next version. 1825 case 2: 1826 $sidebars_widgets = retrieve_widgets(); 1827 $sidebars_widgets['array_version'] = 3; 1828 update_option( 'sidebars_widgets', $sidebars_widgets ); 1829 } 1830 } 1831 1832 /** 1833 * Execute changes made in WordPress 3.4. 1834 * 1835 * @ignore 1836 * @since 3.4.0 1837 * 1838 * @global int $wp_current_db_version The old (current) database version. 1839 * @global wpdb $wpdb WordPress database abstraction object. 1840 */ 1841 function upgrade_340() { 1842 global $wp_current_db_version, $wpdb; 1843 1844 if ( $wp_current_db_version < 19798 ) { 1845 $wpdb->hide_errors(); 1846 $wpdb->query( "ALTER TABLE $wpdb->options DROP COLUMN blog_id" ); 1847 $wpdb->show_errors(); 1848 } 1849 1850 if ( $wp_current_db_version < 19799 ) { 1851 $wpdb->hide_errors(); 1852 $wpdb->query( "ALTER TABLE $wpdb->comments DROP INDEX comment_approved" ); 1853 $wpdb->show_errors(); 1854 } 1855 1856 if ( $wp_current_db_version < 20022 && wp_should_upgrade_global_tables() ) { 1857 $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key = 'themes_last_view'" ); 1858 } 1859 1860 if ( $wp_current_db_version < 20080 ) { 1861 if ( 'yes' === $wpdb->get_var( "SELECT autoload FROM $wpdb->options WHERE option_name = 'uninstall_plugins'" ) ) { 1862 $uninstall_plugins = get_option( 'uninstall_plugins' ); 1863 delete_option( 'uninstall_plugins' ); 1864 add_option( 'uninstall_plugins', $uninstall_plugins, null, false ); 1865 } 1866 } 1867 } 1868 1869 /** 1870 * Execute changes made in WordPress 3.5. 1871 * 1872 * @ignore 1873 * @since 3.5.0 1874 * 1875 * @global int $wp_current_db_version The old (current) database version. 1876 * @global wpdb $wpdb WordPress database abstraction object. 1877 */ 1878 function upgrade_350() { 1879 global $wp_current_db_version, $wpdb; 1880 1881 if ( $wp_current_db_version < 22006 && $wpdb->get_var( "SELECT link_id FROM $wpdb->links LIMIT 1" ) ) { 1882 update_option( 'link_manager_enabled', 1 ); // Previously set to 0 by populate_options(). 1883 } 1884 1885 if ( $wp_current_db_version < 21811 && wp_should_upgrade_global_tables() ) { 1886 $meta_keys = array(); 1887 foreach ( array_merge( get_post_types(), get_taxonomies() ) as $name ) { 1888 if ( str_contains( $name, '-' ) ) { 1889 $meta_keys[] = 'edit_' . str_replace( '-', '_', $name ) . '_per_page'; 1890 } 1891 } 1892 if ( $meta_keys ) { 1893 $meta_keys = implode( "', '", $meta_keys ); 1894 $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key IN ('$meta_keys')" ); 1895 } 1896 } 1897 1898 if ( $wp_current_db_version < 22422 ) { 1899 $term = get_term_by( 'slug', 'post-format-standard', 'post_format' ); 1900 if ( $term ) { 1901 wp_delete_term( $term->term_id, 'post_format' ); 1902 } 1903 } 1904 } 1905 1906 /** 1907 * Execute changes made in WordPress 3.7. 1908 * 1909 * @ignore 1910 * @since 3.7.0 1911 * 1912 * @global int $wp_current_db_version The old (current) database version. 1913 */ 1914 function upgrade_370() { 1915 global $wp_current_db_version; 1916 1917 if ( $wp_current_db_version < 25824 ) { 1918 wp_clear_scheduled_hook( 'wp_auto_updates_maybe_update' ); 1919 } 1920 } 1921 1922 /** 1923 * Execute changes made in WordPress 3.7.2. 1924 * 1925 * @ignore 1926 * @since 3.7.2 1927 * 1928 * @global int $wp_current_db_version The old (current) database version. 1929 */ 1930 function upgrade_372() { 1931 global $wp_current_db_version; 1932 1933 if ( $wp_current_db_version < 26148 ) { 1934 wp_clear_scheduled_hook( 'wp_maybe_auto_update' ); 1935 } 1936 } 1937 1938 /** 1939 * Execute changes made in WordPress 3.8.0. 1940 * 1941 * @ignore 1942 * @since 3.8.0 1943 * 1944 * @global int $wp_current_db_version The old (current) database version. 1945 */ 1946 function upgrade_380() { 1947 global $wp_current_db_version; 1948 1949 if ( $wp_current_db_version < 26691 ) { 1950 deactivate_plugins( array( 'mp6/mp6.php' ), true ); 1951 } 1952 } 1953 1954 /** 1955 * Execute changes made in WordPress 4.0.0. 1956 * 1957 * @ignore 1958 * @since 4.0.0 1959 * 1960 * @global int $wp_current_db_version The old (current) database version. 1961 */ 1962 function upgrade_400() { 1963 global $wp_current_db_version; 1964 1965 if ( $wp_current_db_version < 29630 ) { 1966 if ( ! is_multisite() && false === get_option( 'WPLANG' ) ) { 1967 if ( defined( 'WPLANG' ) && ( '' !== WPLANG ) && in_array( WPLANG, get_available_languages(), true ) ) { 1968 update_option( 'WPLANG', WPLANG ); 1969 } else { 1970 update_option( 'WPLANG', '' ); 1971 } 1972 } 1973 } 1974 } 1975 1976 /** 1977 * Execute changes made in WordPress 4.2.0. 1978 * 1979 * @ignore 1980 * @since 4.2.0 1981 */ 1982 function upgrade_420() {} 1983 1984 /** 1985 * Executes changes made in WordPress 4.3.0. 1986 * 1987 * @ignore 1988 * @since 4.3.0 1989 * 1990 * @global int $wp_current_db_version The old (current) database version. 1991 * @global wpdb $wpdb WordPress database abstraction object. 1992 */ 1993 function upgrade_430() { 1994 global $wp_current_db_version, $wpdb; 1995 1996 if ( $wp_current_db_version < 32364 ) { 1997 upgrade_430_fix_comments(); 1998 } 1999 2000 // Shared terms are split in a separate process. 2001 if ( $wp_current_db_version < 32814 ) { 2002 update_option( 'finished_splitting_shared_terms', 0 ); 2003 wp_schedule_single_event( time() + ( 1 * MINUTE_IN_SECONDS ), 'wp_split_shared_term_batch' ); 2004 } 2005 2006 if ( $wp_current_db_version < 33055 && 'utf8mb4' === $wpdb->charset ) { 2007 if ( is_multisite() ) { 2008 $tables = $wpdb->tables( 'blog' ); 2009 } else { 2010 $tables = $wpdb->tables( 'all' ); 2011 if ( ! wp_should_upgrade_global_tables() ) { 2012 $global_tables = $wpdb->tables( 'global' ); 2013 $tables = array_diff_assoc( $tables, $global_tables ); 2014 } 2015 } 2016 2017 foreach ( $tables as $table ) { 2018 maybe_convert_table_to_utf8mb4( $table ); 2019 } 2020 } 2021 } 2022 2023 /** 2024 * Executes comments changes made in WordPress 4.3.0. 2025 * 2026 * @ignore 2027 * @since 4.3.0 2028 * 2029 * @global wpdb $wpdb WordPress database abstraction object. 2030 */ 2031 function upgrade_430_fix_comments() { 2032 global $wpdb; 2033 2034 $content_length = $wpdb->get_col_length( $wpdb->comments, 'comment_content' ); 2035 2036 if ( is_wp_error( $content_length ) ) { 2037 return; 2038 } 2039 2040 if ( false === $content_length ) { 2041 $content_length = array( 2042 'type' => 'byte', 2043 'length' => 65535, 2044 ); 2045 } elseif ( ! is_array( $content_length ) ) { 2046 $length = (int) $content_length > 0 ? (int) $content_length : 65535; 2047 $content_length = array( 2048 'type' => 'byte', 2049 'length' => $length, 2050 ); 2051 } 2052 2053 if ( 'byte' !== $content_length['type'] || 0 === $content_length['length'] ) { 2054 // Sites with malformed DB schemas are on their own. 2055 return; 2056 } 2057 2058 $allowed_length = (int) $content_length['length'] - 10; 2059 2060 $comments = $wpdb->get_results( 2061 "SELECT `comment_ID` FROM `{$wpdb->comments}` 2062 WHERE `comment_date_gmt` > '2015-04-26' 2063 AND LENGTH( `comment_content` ) >= {$allowed_length} 2064 AND ( `comment_content` LIKE '%<%' OR `comment_content` LIKE '%>%' )" 2065 ); 2066 2067 foreach ( $comments as $comment ) { 2068 wp_delete_comment( $comment->comment_ID, true ); 2069 } 2070 } 2071 2072 /** 2073 * Executes changes made in WordPress 4.3.1. 2074 * 2075 * @ignore 2076 * @since 4.3.1 2077 */ 2078 function upgrade_431() { 2079 // Fix incorrect cron entries for term splitting. 2080 $cron_array = _get_cron_array(); 2081 if ( isset( $cron_array['wp_batch_split_terms'] ) ) { 2082 unset( $cron_array['wp_batch_split_terms'] ); 2083 _set_cron_array( $cron_array ); 2084 } 2085 } 2086 2087 /** 2088 * Executes changes made in WordPress 4.4.0. 2089 * 2090 * @ignore 2091 * @since 4.4.0 2092 * 2093 * @global int $wp_current_db_version The old (current) database version. 2094 * @global wpdb $wpdb WordPress database abstraction object. 2095 */ 2096 function upgrade_440() { 2097 global $wp_current_db_version, $wpdb; 2098 2099 if ( $wp_current_db_version < 34030 ) { 2100 $wpdb->query( "ALTER TABLE {$wpdb->options} MODIFY option_name VARCHAR(191)" ); 2101 } 2102 2103 // Remove the unused 'add_users' role. 2104 $roles = wp_roles(); 2105 foreach ( $roles->role_objects as $role ) { 2106 if ( $role->has_cap( 'add_users' ) ) { 2107 $role->remove_cap( 'add_users' ); 2108 } 2109 } 2110 } 2111 2112 /** 2113 * Executes changes made in WordPress 4.5.0. 2114 * 2115 * @ignore 2116 * @since 4.5.0 2117 * 2118 * @global int $wp_current_db_version The old (current) database version. 2119 * @global wpdb $wpdb WordPress database abstraction object. 2120 */ 2121 function upgrade_450() { 2122 global $wp_current_db_version, $wpdb; 2123 2124 if ( $wp_current_db_version < 36180 ) { 2125 wp_clear_scheduled_hook( 'wp_maybe_auto_update' ); 2126 } 2127 2128 // Remove unused email confirmation options, moved to usermeta. 2129 if ( $wp_current_db_version < 36679 && is_multisite() ) { 2130 $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name REGEXP '^[0-9]+_new_email$'" ); 2131 } 2132 2133 // Remove unused user setting for wpLink. 2134 delete_user_setting( 'wplink' ); 2135 } 2136 2137 /** 2138 * Executes changes made in WordPress 4.6.0. 2139 * 2140 * @ignore 2141 * @since 4.6.0 2142 * 2143 * @global int $wp_current_db_version The old (current) database version. 2144 */ 2145 function upgrade_460() { 2146 global $wp_current_db_version; 2147 2148 // Remove unused post meta. 2149 if ( $wp_current_db_version < 37854 ) { 2150 delete_post_meta_by_key( '_post_restored_from' ); 2151 } 2152 2153 // Remove plugins with callback as an array object/method as the uninstall hook, see #13786. 2154 if ( $wp_current_db_version < 37965 ) { 2155 $uninstall_plugins = get_option( 'uninstall_plugins', array() ); 2156 2157 if ( ! empty( $uninstall_plugins ) ) { 2158 foreach ( $uninstall_plugins as $basename => $callback ) { 2159 if ( is_array( $callback ) && is_object( $callback[0] ) ) { 2160 unset( $uninstall_plugins[ $basename ] ); 2161 } 2162 } 2163 2164 update_option( 'uninstall_plugins', $uninstall_plugins ); 2165 } 2166 } 2167 } 2168 2169 /** 2170 * Executes changes made in WordPress 5.0.0. 2171 * 2172 * @ignore 2173 * @since 5.0.0 2174 * @deprecated 5.1.0 2175 */ 2176 function upgrade_500() { 2177 } 2178 2179 /** 2180 * Executes changes made in WordPress 5.1.0. 2181 * 2182 * @ignore 2183 * @since 5.1.0 2184 */ 2185 function upgrade_510() { 2186 delete_site_option( 'upgrade_500_was_gutenberg_active' ); 2187 } 2188 2189 /** 2190 * Executes changes made in WordPress 5.3.0. 2191 * 2192 * @ignore 2193 * @since 5.3.0 2194 */ 2195 function upgrade_530() { 2196 /* 2197 * The `admin_email_lifespan` option may have been set by an admin that just logged in, 2198 * saw the verification screen, clicked on a button there, and is now upgrading the db, 2199 * or by populate_options() that is called earlier in upgrade_all(). 2200 * In the second case `admin_email_lifespan` should be reset so the verification screen 2201 * is shown next time an admin logs in. 2202 */ 2203 if ( function_exists( 'current_user_can' ) && ! current_user_can( 'manage_options' ) ) { 2204 update_option( 'admin_email_lifespan', 0 ); 2205 } 2206 } 2207 2208 /** 2209 * Executes changes made in WordPress 5.5.0. 2210 * 2211 * @ignore 2212 * @since 5.5.0 2213 * 2214 * @global int $wp_current_db_version The old (current) database version. 2215 */ 2216 function upgrade_550() { 2217 global $wp_current_db_version; 2218 2219 if ( $wp_current_db_version < 48121 ) { 2220 $comment_previously_approved = get_option( 'comment_whitelist', '' ); 2221 update_option( 'comment_previously_approved', $comment_previously_approved ); 2222 delete_option( 'comment_whitelist' ); 2223 } 2224 2225 if ( $wp_current_db_version < 48575 ) { 2226 // Use more clear and inclusive language. 2227 $disallowed_list = get_option( 'blacklist_keys' ); 2228 2229 /* 2230 * This option key was briefly renamed `blocklist_keys`. 2231 * Account for sites that have this key present when the original key does not exist. 2232 */ 2233 if ( false === $disallowed_list ) { 2234 $disallowed_list = get_option( 'blocklist_keys' ); 2235 } 2236 2237 update_option( 'disallowed_keys', $disallowed_list ); 2238 delete_option( 'blacklist_keys' ); 2239 delete_option( 'blocklist_keys' ); 2240 } 2241 2242 if ( $wp_current_db_version < 48748 ) { 2243 update_option( 'finished_updating_comment_type', 0 ); 2244 wp_schedule_single_event( time() + ( 1 * MINUTE_IN_SECONDS ), 'wp_update_comment_type_batch' ); 2245 } 2246 } 2247 2248 /** 2249 * Executes changes made in WordPress 5.6.0. 2250 * 2251 * @ignore 2252 * @since 5.6.0 2253 * 2254 * @global int $wp_current_db_version The old (current) database version. 2255 * @global wpdb $wpdb WordPress database abstraction object. 2256 */ 2257 function upgrade_560() { 2258 global $wp_current_db_version, $wpdb; 2259 2260 if ( $wp_current_db_version < 49572 ) { 2261 /* 2262 * Clean up the `post_category` column removed from schema in version 2.8.0. 2263 * Its presence may conflict with `WP_Post::__get()`. 2264 */ 2265 $post_category_exists = $wpdb->get_var( "SHOW COLUMNS FROM $wpdb->posts LIKE 'post_category'" ); 2266 if ( ! is_null( $post_category_exists ) ) { 2267 $wpdb->query( "ALTER TABLE $wpdb->posts DROP COLUMN `post_category`" ); 2268 } 2269 2270 /* 2271 * When upgrading from WP < 5.6.0 set the core major auto-updates option to `unset` by default. 2272 * This overrides the same option from populate_options() that is intended for new installs. 2273 * See https://core.trac.wordpress.org/ticket/51742. 2274 */ 2275 update_option( 'auto_update_core_major', 'unset' ); 2276 } 2277 2278 if ( $wp_current_db_version < 49632 ) { 2279 /* 2280 * Regenerate the .htaccess file to add the `HTTP_AUTHORIZATION` rewrite rule. 2281 * See https://core.trac.wordpress.org/ticket/51723. 2282 */ 2283 save_mod_rewrite_rules(); 2284 } 2285 2286 if ( $wp_current_db_version < 49735 ) { 2287 delete_transient( 'dirsize_cache' ); 2288 } 2289 2290 if ( $wp_current_db_version < 49752 ) { 2291 $results = $wpdb->get_results( 2292 $wpdb->prepare( 2293 "SELECT 1 FROM {$wpdb->usermeta} WHERE meta_key = %s LIMIT 1", 2294 WP_Application_Passwords::USERMETA_KEY_APPLICATION_PASSWORDS 2295 ) 2296 ); 2297 2298 if ( ! empty( $results ) ) { 2299 $network_id = get_main_network_id(); 2300 update_network_option( $network_id, WP_Application_Passwords::OPTION_KEY_IN_USE, 1 ); 2301 } 2302 } 2303 } 2304 2305 /** 2306 * Executes changes made in WordPress 5.9.0. 2307 * 2308 * @ignore 2309 * @since 5.9.0 2310 * 2311 * @global int $wp_current_db_version The old (current) database version. 2312 */ 2313 function upgrade_590() { 2314 global $wp_current_db_version; 2315 2316 if ( $wp_current_db_version < 51917 ) { 2317 $crons = _get_cron_array(); 2318 2319 if ( $crons && is_array( $crons ) ) { 2320 // Remove errant `false` values, see #53950, #54906. 2321 $crons = array_filter( $crons ); 2322 _set_cron_array( $crons ); 2323 } 2324 } 2325 } 2326 2327 /** 2328 * Executes changes made in WordPress 6.0.0. 2329 * 2330 * @ignore 2331 * @since 6.0.0 2332 * 2333 * @global int $wp_current_db_version The old (current) database version. 2334 */ 2335 function upgrade_600() { 2336 global $wp_current_db_version; 2337 2338 if ( $wp_current_db_version < 53011 ) { 2339 wp_update_user_counts(); 2340 } 2341 } 2342 2343 /** 2344 * Executes changes made in WordPress 6.3.0. 2345 * 2346 * @ignore 2347 * @since 6.3.0 2348 * 2349 * @global int $wp_current_db_version The old (current) database version. 2350 */ 2351 function upgrade_630() { 2352 global $wp_current_db_version; 2353 2354 if ( $wp_current_db_version < 55853 ) { 2355 if ( ! is_multisite() ) { 2356 // Replace non-autoload option can_compress_scripts with autoload option, see #55270 2357 $can_compress_scripts = get_option( 'can_compress_scripts', false ); 2358 if ( false !== $can_compress_scripts ) { 2359 delete_option( 'can_compress_scripts' ); 2360 add_option( 'can_compress_scripts', $can_compress_scripts, '', true ); 2361 } 2362 } 2363 } 2364 } 2365 2366 /** 2367 * Executes changes made in WordPress 6.4.0. 2368 * 2369 * @ignore 2370 * @since 6.4.0 2371 * 2372 * @global int $wp_current_db_version The old (current) database version. 2373 */ 2374 function upgrade_640() { 2375 global $wp_current_db_version; 2376 2377 if ( $wp_current_db_version < 56657 ) { 2378 // Enable attachment pages. 2379 update_option( 'wp_attachment_pages_enabled', 1 ); 2380 2381 // Remove the wp_https_detection cron. Https status is checked directly in an async Site Health check. 2382 $scheduled = wp_get_scheduled_event( 'wp_https_detection' ); 2383 if ( $scheduled ) { 2384 wp_clear_scheduled_hook( 'wp_https_detection' ); 2385 } 2386 } 2387 } 2388 2389 /** 2390 * Executes changes made in WordPress 6.5.0. 2391 * 2392 * @ignore 2393 * @since 6.5.0 2394 * 2395 * @global int $wp_current_db_version The old (current) database version. 2396 * @global wpdb $wpdb WordPress database abstraction object. 2397 */ 2398 function upgrade_650() { 2399 global $wp_current_db_version, $wpdb; 2400 2401 if ( $wp_current_db_version < 57155 ) { 2402 $stylesheet = get_stylesheet(); 2403 2404 // Set autoload=no for all themes except the current one. 2405 $theme_mods_options = $wpdb->get_col( 2406 $wpdb->prepare( 2407 "SELECT option_name FROM $wpdb->options WHERE autoload = 'yes' AND option_name != %s AND option_name LIKE %s", 2408 "theme_mods_$stylesheet", 2409 $wpdb->esc_like( 'theme_mods_' ) . '%' 2410 ) 2411 ); 2412 2413 $autoload = array_fill_keys( $theme_mods_options, false ); 2414 wp_set_option_autoload_values( $autoload ); 2415 } 2416 } 2417 /** 2418 * Executes changes made in WordPress 6.7.0. 2419 * 2420 * @ignore 2421 * @since 6.7.0 2422 * 2423 * @global int $wp_current_db_version The old (current) database version. 2424 */ 2425 function upgrade_670() { 2426 global $wp_current_db_version; 2427 2428 if ( $wp_current_db_version < 58975 ) { 2429 $options = array( 2430 'recently_activated', 2431 '_wp_suggested_policy_text_has_changed', 2432 'dashboard_widget_options', 2433 'ftp_credentials', 2434 'adminhash', 2435 'nav_menu_options', 2436 'wp_force_deactivated_plugins', 2437 'delete_blog_hash', 2438 'allowedthemes', 2439 'recovery_keys', 2440 'https_detection_errors', 2441 'fresh_site', 2442 ); 2443 2444 wp_set_options_autoload( $options, false ); 2445 } 2446 } 2447 2448 /** 2449 * Executes changes made in WordPress 6.8.2. 2450 * 2451 * @ignore 2452 * @since 6.8.2 2453 * 2454 * @global int $wp_current_db_version The old (current) database version. 2455 */ 2456 function upgrade_682() { 2457 global $wp_current_db_version; 2458 2459 if ( $wp_current_db_version < 60421 ) { 2460 // Upgrade Ping-O-Matic and Twingly to use HTTPS. 2461 $ping_sites_value = get_option( 'ping_sites' ); 2462 $ping_sites_value = explode( "\n", $ping_sites_value ); 2463 $ping_sites_value = array_map( 2464 function ( $url ) { 2465 $url = trim( $url ); 2466 $url = sanitize_url( $url ); 2467 if ( 2468 str_ends_with( trailingslashit( $url ), '://rpc.pingomatic.com/' ) 2469 || str_ends_with( trailingslashit( $url ), '://rpc.twingly.com/' ) 2470 ) { 2471 $url = set_url_scheme( $url, 'https' ); 2472 } 2473 return $url; 2474 }, 2475 $ping_sites_value 2476 ); 2477 $ping_sites_value = array_filter( $ping_sites_value ); 2478 $ping_sites_value = implode( "\n", $ping_sites_value ); 2479 update_option( 'ping_sites', $ping_sites_value ); 2480 } 2481 } 2482 2483 /** 2484 * Executes network-level upgrade routines. 2485 * 2486 * @since 3.0.0 2487 * 2488 * @global int $wp_current_db_version The old (current) database version. 2489 * @global wpdb $wpdb WordPress database abstraction object. 2490 */ 2491 function upgrade_network() { 2492 global $wp_current_db_version, $wpdb; 2493 2494 // Always clear expired transients. 2495 delete_expired_transients( true ); 2496 2497 // 2.8.0 2498 if ( $wp_current_db_version < 11549 ) { 2499 $wpmu_sitewide_plugins = get_site_option( 'wpmu_sitewide_plugins' ); 2500 $active_sitewide_plugins = get_site_option( 'active_sitewide_plugins' ); 2501 if ( $wpmu_sitewide_plugins ) { 2502 if ( ! $active_sitewide_plugins ) { 2503 $sitewide_plugins = (array) $wpmu_sitewide_plugins; 2504 } else { 2505 $sitewide_plugins = array_merge( (array) $active_sitewide_plugins, (array) $wpmu_sitewide_plugins ); 2506 } 2507 2508 update_site_option( 'active_sitewide_plugins', $sitewide_plugins ); 2509 } 2510 delete_site_option( 'wpmu_sitewide_plugins' ); 2511 delete_site_option( 'deactivated_sitewide_plugins' ); 2512 2513 $start = 0; 2514 while ( $rows = $wpdb->get_results( "SELECT meta_key, meta_value FROM {$wpdb->sitemeta} ORDER BY meta_id LIMIT $start, 20" ) ) { 2515 foreach ( $rows as $row ) { 2516 $value = $row->meta_value; 2517 if ( ! @unserialize( $value ) ) { 2518 $value = stripslashes( $value ); 2519 } 2520 if ( $value !== $row->meta_value ) { 2521 update_site_option( $row->meta_key, $value ); 2522 } 2523 } 2524 $start += 20; 2525 } 2526 } 2527 2528 // 3.0.0 2529 if ( $wp_current_db_version < 13576 ) { 2530 update_site_option( 'global_terms_enabled', '1' ); 2531 } 2532 2533 // 3.3.0 2534 if ( $wp_current_db_version < 19390 ) { 2535 update_site_option( 'initial_db_version', $wp_current_db_version ); 2536 } 2537 2538 if ( $wp_current_db_version < 19470 ) { 2539 if ( false === get_site_option( 'active_sitewide_plugins' ) ) { 2540 update_site_option( 'active_sitewide_plugins', array() ); 2541 } 2542 } 2543 2544 // 3.4.0 2545 if ( $wp_current_db_version < 20148 ) { 2546 // 'allowedthemes' keys things by stylesheet. 'allowed_themes' keyed things by name. 2547 $allowedthemes = get_site_option( 'allowedthemes' ); 2548 $allowed_themes = get_site_option( 'allowed_themes' ); 2549 if ( false === $allowedthemes && is_array( $allowed_themes ) && $allowed_themes ) { 2550 $converted = array(); 2551 $themes = wp_get_themes(); 2552 foreach ( $themes as $stylesheet => $theme_data ) { 2553 if ( isset( $allowed_themes[ $theme_data->get( 'Name' ) ] ) ) { 2554 $converted[ $stylesheet ] = true; 2555 } 2556 } 2557 update_site_option( 'allowedthemes', $converted ); 2558 delete_site_option( 'allowed_themes' ); 2559 } 2560 } 2561 2562 // 3.5.0 2563 if ( $wp_current_db_version < 21823 ) { 2564 update_site_option( 'ms_files_rewriting', '1' ); 2565 } 2566 2567 // 3.5.2 2568 if ( $wp_current_db_version < 24448 ) { 2569 $illegal_names = get_site_option( 'illegal_names' ); 2570 if ( is_array( $illegal_names ) && count( $illegal_names ) === 1 ) { 2571 $illegal_name = reset( $illegal_names ); 2572 $illegal_names = explode( ' ', $illegal_name ); 2573 update_site_option( 'illegal_names', $illegal_names ); 2574 } 2575 } 2576 2577 // 4.2.0 2578 if ( $wp_current_db_version < 31351 && 'utf8mb4' === $wpdb->charset ) { 2579 if ( wp_should_upgrade_global_tables() ) { 2580 $wpdb->query( "ALTER TABLE $wpdb->usermeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" ); 2581 $wpdb->query( "ALTER TABLE $wpdb->site DROP INDEX domain, ADD INDEX domain(domain(140),path(51))" ); 2582 $wpdb->query( "ALTER TABLE $wpdb->sitemeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" ); 2583 $wpdb->query( "ALTER TABLE $wpdb->signups DROP INDEX domain_path, ADD INDEX domain_path(domain(140),path(51))" ); 2584 2585 $tables = $wpdb->tables( 'global' ); 2586 2587 // sitecategories may not exist. 2588 if ( ! $wpdb->get_var( "SHOW TABLES LIKE '{$tables['sitecategories']}'" ) ) { 2589 unset( $tables['sitecategories'] ); 2590 } 2591 2592 foreach ( $tables as $table ) { 2593 maybe_convert_table_to_utf8mb4( $table ); 2594 } 2595 } 2596 } 2597 2598 // 4.3.0 2599 if ( $wp_current_db_version < 33055 && 'utf8mb4' === $wpdb->charset ) { 2600 if ( wp_should_upgrade_global_tables() ) { 2601 $upgrade = false; 2602 $indexes = $wpdb->get_results( "SHOW INDEXES FROM $wpdb->signups" ); 2603 foreach ( $indexes as $index ) { 2604 if ( 'domain_path' === $index->Key_name && 'domain' === $index->Column_name && '140' !== $index->Sub_part ) { 2605 $upgrade = true; 2606 break; 2607 } 2608 } 2609 2610 if ( $upgrade ) { 2611 $wpdb->query( "ALTER TABLE $wpdb->signups DROP INDEX domain_path, ADD INDEX domain_path(domain(140),path(51))" ); 2612 } 2613 2614 $tables = $wpdb->tables( 'global' ); 2615 2616 // sitecategories may not exist. 2617 if ( ! $wpdb->get_var( "SHOW TABLES LIKE '{$tables['sitecategories']}'" ) ) { 2618 unset( $tables['sitecategories'] ); 2619 } 2620 2621 foreach ( $tables as $table ) { 2622 maybe_convert_table_to_utf8mb4( $table ); 2623 } 2624 } 2625 } 2626 2627 // 5.1.0 2628 if ( $wp_current_db_version < 44467 ) { 2629 $network_id = get_main_network_id(); 2630 delete_network_option( $network_id, 'site_meta_supported' ); 2631 is_site_meta_supported(); 2632 } 2633 } 2634 2635 // 2636 // General functions we use to actually do stuff. 2637 // 2638 2639 /** 2640 * Creates a table in the database, if it doesn't already exist. 2641 * 2642 * This method checks for an existing database table and creates a new one if it's not 2643 * already present. It doesn't rely on MySQL's "IF NOT EXISTS" statement, but chooses 2644 * to query all tables first and then run the SQL statement creating the table. 2645 * 2646 * @since 1.0.0 2647 * 2648 * @global wpdb $wpdb WordPress database abstraction object. 2649 * 2650 * @param string $table_name Database table name. 2651 * @param string $create_ddl SQL statement to create table. 2652 * @return bool True on success or if the table already exists. False on failure. 2653 */ 2654 function maybe_create_table( $table_name, $create_ddl ) { 2655 global $wpdb; 2656 2657 $query = $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $table_name ) ); 2658 2659 if ( $wpdb->get_var( $query ) === $table_name ) { 2660 return true; 2661 } 2662 2663 // Didn't find it, so try to create it. 2664 $wpdb->query( $create_ddl ); 2665 2666 // We cannot directly tell that whether this succeeded! 2667 if ( $wpdb->get_var( $query ) === $table_name ) { 2668 return true; 2669 } 2670 2671 return false; 2672 } 2673 2674 /** 2675 * Drops a specified index from a table. 2676 * 2677 * @since 1.0.1 2678 * 2679 * @global wpdb $wpdb WordPress database abstraction object. 2680 * 2681 * @param string $table Database table name. 2682 * @param string $index Index name to drop. 2683 * @return true True, when finished. 2684 */ 2685 function drop_index( $table, $index ) { 2686 global $wpdb; 2687 2688 $wpdb->hide_errors(); 2689 2690 $wpdb->query( "ALTER TABLE `$table` DROP INDEX `$index`" ); 2691 2692 // Now we need to take out all the extra ones we may have created. 2693 for ( $i = 0; $i < 25; $i++ ) { 2694 $wpdb->query( "ALTER TABLE `$table` DROP INDEX `{$index}_$i`" ); 2695 } 2696 2697 $wpdb->show_errors(); 2698 2699 return true; 2700 } 2701 2702 /** 2703 * Adds an index to a specified table. 2704 * 2705 * @since 1.0.1 2706 * 2707 * @global wpdb $wpdb WordPress database abstraction object. 2708 * 2709 * @param string $table Database table name. 2710 * @param string $index Database table index column. 2711 * @return true True, when done with execution. 2712 */ 2713 function add_clean_index( $table, $index ) { 2714 global $wpdb; 2715 2716 drop_index( $table, $index ); 2717 $wpdb->query( "ALTER TABLE `$table` ADD INDEX ( `$index` )" ); 2718 2719 return true; 2720 } 2721 2722 /** 2723 * Adds column to a database table, if it doesn't already exist. 2724 * 2725 * @since 1.3.0 2726 * 2727 * @global wpdb $wpdb WordPress database abstraction object. 2728 * 2729 * @param string $table_name Database table name. 2730 * @param string $column_name Table column name. 2731 * @param string $create_ddl SQL statement to add column. 2732 * @return bool True on success or if the column already exists. False on failure. 2733 */ 2734 function maybe_add_column( $table_name, $column_name, $create_ddl ) { 2735 global $wpdb; 2736 2737 foreach ( $wpdb->get_col( "DESC $table_name", 0 ) as $column ) { 2738 if ( $column === $column_name ) { 2739 return true; 2740 } 2741 } 2742 2743 // Didn't find it, so try to create it. 2744 $wpdb->query( $create_ddl ); 2745 2746 // We cannot directly tell that whether this succeeded! 2747 foreach ( $wpdb->get_col( "DESC $table_name", 0 ) as $column ) { 2748 if ( $column === $column_name ) { 2749 return true; 2750 } 2751 } 2752 2753 return false; 2754 } 2755 2756 /** 2757 * If a table only contains utf8 or utf8mb4 columns, convert it to utf8mb4. 2758 * 2759 * @since 4.2.0 2760 * 2761 * @global wpdb $wpdb WordPress database abstraction object. 2762 * 2763 * @param string $table The table to convert. 2764 * @return bool True if the table was converted, false if it wasn't. 2765 */ 2766 function maybe_convert_table_to_utf8mb4( $table ) { 2767 global $wpdb; 2768 2769 $results = $wpdb->get_results( "SHOW FULL COLUMNS FROM `$table`" ); 2770 if ( ! $results ) { 2771 return false; 2772 } 2773 2774 foreach ( $results as $column ) { 2775 if ( $column->Collation ) { 2776 list( $charset ) = explode( '_', $column->Collation ); 2777 $charset = strtolower( $charset ); 2778 if ( 'utf8' !== $charset && 'utf8mb4' !== $charset ) { 2779 // Don't upgrade tables that have non-utf8 columns. 2780 return false; 2781 } 2782 } 2783 } 2784 2785 $table_details = $wpdb->get_row( "SHOW TABLE STATUS LIKE '$table'" ); 2786 if ( ! $table_details ) { 2787 return false; 2788 } 2789 2790 list( $table_charset ) = explode( '_', $table_details->Collation ); 2791 $table_charset = strtolower( $table_charset ); 2792 if ( 'utf8mb4' === $table_charset ) { 2793 return true; 2794 } 2795 2796 return $wpdb->query( "ALTER TABLE $table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci" ); 2797 } 2798 2799 /** 2800 * Retrieve all options as it was for 1.2. 2801 * 2802 * @since 1.2.0 2803 * 2804 * @global wpdb $wpdb WordPress database abstraction object. 2805 * 2806 * @return stdClass List of options. 2807 */ 2808 function get_alloptions_110() { 2809 global $wpdb; 2810 $all_options = new stdClass(); 2811 $options = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options" ); 2812 if ( $options ) { 2813 foreach ( $options as $option ) { 2814 if ( 'siteurl' === $option->option_name || 'home' === $option->option_name || 'category_base' === $option->option_name ) { 2815 $option->option_value = untrailingslashit( $option->option_value ); 2816 } 2817 $all_options->{$option->option_name} = stripslashes( $option->option_value ); 2818 } 2819 } 2820 return $all_options; 2821 } 2822 2823 /** 2824 * Utility version of get_option that is private to installation/upgrade. 2825 * 2826 * @ignore 2827 * @since 1.5.1 2828 * @access private 2829 * 2830 * @global wpdb $wpdb WordPress database abstraction object. 2831 * 2832 * @param string $setting Option name. 2833 * @return mixed 2834 */ 2835 function __get_option( $setting ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionDoubleUnderscore,PHPCompatibility.FunctionNameRestrictions.ReservedFunctionNames.FunctionDoubleUnderscore 2836 global $wpdb; 2837 2838 if ( 'home' === $setting && defined( 'WP_HOME' ) ) { 2839 return untrailingslashit( WP_HOME ); 2840 } 2841 2842 if ( 'siteurl' === $setting && defined( 'WP_SITEURL' ) ) { 2843 return untrailingslashit( WP_SITEURL ); 2844 } 2845 2846 $option = $wpdb->get_var( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s", $setting ) ); 2847 2848 if ( 'home' === $setting && ! $option ) { 2849 return __get_option( 'siteurl' ); 2850 } 2851 2852 if ( in_array( $setting, array( 'siteurl', 'home', 'category_base', 'tag_base' ), true ) ) { 2853 $option = untrailingslashit( $option ); 2854 } 2855 2856 return maybe_unserialize( $option ); 2857 } 2858 2859 /** 2860 * Filters for content to remove unnecessary slashes. 2861 * 2862 * @since 1.5.0 2863 * 2864 * @param string $content The content to modify. 2865 * @return string The de-slashed content. 2866 */ 2867 function deslash( $content ) { 2868 // Note: \\\ inside a regex denotes a single backslash. 2869 2870 /* 2871 * Replace one or more backslashes followed by a single quote with 2872 * a single quote. 2873 */ 2874 $content = preg_replace( "/\\\+'/", "'", $content ); 2875 2876 /* 2877 * Replace one or more backslashes followed by a double quote with 2878 * a double quote. 2879 */ 2880 $content = preg_replace( '/\\\+"/', '"', $content ); 2881 2882 // Replace one or more backslashes with one backslash. 2883 $content = preg_replace( '/\\\+/', '\\', $content ); 2884 2885 return $content; 2886 } 2887 2888 /** 2889 * Modifies the database based on specified SQL statements. 2890 * 2891 * Useful for creating new tables and updating existing tables to a new structure. 2892 * 2893 * @since 1.5.0 2894 * @since 6.1.0 Ignores display width for integer data types on MySQL 8.0.17 or later, 2895 * to match MySQL behavior. Note: This does not affect MariaDB. 2896 * 2897 * @global wpdb $wpdb WordPress database abstraction object. 2898 * 2899 * @param string[]|string $queries Optional. The query to run. Can be multiple queries 2900 * in an array, or a string of queries separated by 2901 * semicolons. Default empty string. 2902 * @param bool $execute Optional. Whether or not to execute the query right away. 2903 * Default true. 2904 * @return string[] Strings containing the results of the various update queries. 2905 */ 2906 function dbDelta( $queries = '', $execute = true ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid 2907 global $wpdb; 2908 2909 if ( in_array( $queries, array( '', 'all', 'blog', 'global', 'ms_global' ), true ) ) { 2910 $queries = wp_get_db_schema( $queries ); 2911 } 2912 2913 // Separate individual queries into an array. 2914 if ( ! is_array( $queries ) ) { 2915 $queries = explode( ';', $queries ); 2916 $queries = array_filter( $queries ); 2917 } 2918 2919 /** 2920 * Filters the dbDelta SQL queries. 2921 * 2922 * @since 3.3.0 2923 * 2924 * @param string[] $queries An array of dbDelta SQL queries. 2925 */ 2926 $queries = apply_filters( 'dbdelta_queries', $queries ); 2927 2928 $cqueries = array(); // Creation queries. 2929 $iqueries = array(); // Insertion queries. 2930 $for_update = array(); 2931 2932 // Create a tablename index for an array ($cqueries) of recognized query types. 2933 foreach ( $queries as $qry ) { 2934 if ( preg_match( '|CREATE TABLE ([^ ]*)|', $qry, $matches ) ) { 2935 $cqueries[ trim( $matches[1], '`' ) ] = $qry; 2936 $for_update[ $matches[1] ] = 'Created table ' . $matches[1]; 2937 continue; 2938 } 2939 2940 if ( preg_match( '|CREATE DATABASE ([^ ]*)|', $qry, $matches ) ) { 2941 array_unshift( $cqueries, $qry ); 2942 continue; 2943 } 2944 2945 if ( preg_match( '|INSERT INTO ([^ ]*)|', $qry, $matches ) ) { 2946 $iqueries[] = $qry; 2947 continue; 2948 } 2949 2950 if ( preg_match( '|UPDATE ([^ ]*)|', $qry, $matches ) ) { 2951 $iqueries[] = $qry; 2952 continue; 2953 } 2954 } 2955 2956 /** 2957 * Filters the dbDelta SQL queries for creating tables and/or databases. 2958 * 2959 * Queries filterable via this hook contain "CREATE TABLE" or "CREATE DATABASE". 2960 * 2961 * @since 3.3.0 2962 * 2963 * @param string[] $cqueries An array of dbDelta create SQL queries. 2964 */ 2965 $cqueries = apply_filters( 'dbdelta_create_queries', $cqueries ); 2966 2967 /** 2968 * Filters the dbDelta SQL queries for inserting or updating. 2969 * 2970 * Queries filterable via this hook contain "INSERT INTO" or "UPDATE". 2971 * 2972 * @since 3.3.0 2973 * 2974 * @param string[] $iqueries An array of dbDelta insert or update SQL queries. 2975 */ 2976 $iqueries = apply_filters( 'dbdelta_insert_queries', $iqueries ); 2977 2978 $text_fields = array( 'tinytext', 'text', 'mediumtext', 'longtext' ); 2979 $blob_fields = array( 'tinyblob', 'blob', 'mediumblob', 'longblob' ); 2980 $int_fields = array( 'tinyint', 'smallint', 'mediumint', 'int', 'integer', 'bigint' ); 2981 2982 $global_tables = $wpdb->tables( 'global' ); 2983 $db_version = $wpdb->db_version(); 2984 $db_server_info = $wpdb->db_server_info(); 2985 2986 foreach ( $cqueries as $table => $qry ) { 2987 // Upgrade global tables only for the main site. Don't upgrade at all if conditions are not optimal. 2988 if ( in_array( $table, $global_tables, true ) && ! wp_should_upgrade_global_tables() ) { 2989 unset( $cqueries[ $table ], $for_update[ $table ] ); 2990 continue; 2991 } 2992 2993 // Fetch the table column structure from the database. 2994 $suppress = $wpdb->suppress_errors(); 2995 $tablefields = $wpdb->get_results( "DESCRIBE {$table};" ); 2996 $wpdb->suppress_errors( $suppress ); 2997 2998 if ( ! $tablefields ) { 2999 continue; 3000 } 3001 3002 // Clear the field and index arrays. 3003 $cfields = array(); 3004 $indices = array(); 3005 $indices_without_subparts = array(); 3006 3007 // Get all of the field names in the query from between the parentheses. 3008 preg_match( '|\((.*)\)|ms', $qry, $match2 ); 3009 $qryline = trim( $match2[1] ); 3010 3011 // Separate field lines into an array. 3012 $flds = explode( "\n", $qryline ); 3013 3014 // For every field line specified in the query. 3015 foreach ( $flds as $fld ) { 3016 $fld = trim( $fld, " \t\n\r\0\x0B," ); // Default trim characters, plus ','. 3017 3018 // Extract the field name. 3019 preg_match( '|^([^ ]*)|', $fld, $fvals ); 3020 $fieldname = trim( $fvals[1], '`' ); 3021 $fieldname_lowercased = strtolower( $fieldname ); 3022 3023 // Verify the found field name. 3024 $validfield = true; 3025 switch ( $fieldname_lowercased ) { 3026 case '': 3027 case 'primary': 3028 case 'index': 3029 case 'fulltext': 3030 case 'unique': 3031 case 'key': 3032 case 'spatial': 3033 $validfield = false; 3034 3035 /* 3036 * Normalize the index definition. 3037 * 3038 * This is done so the definition can be compared against the result of a 3039 * `SHOW INDEX FROM $table_name` query which returns the current table 3040 * index information. 3041 */ 3042 3043 // Extract type, name and columns from the definition. 3044 preg_match( 3045 '/^ 3046 (?P<index_type> # 1) Type of the index. 3047 PRIMARY\s+KEY|(?:UNIQUE|FULLTEXT|SPATIAL)\s+(?:KEY|INDEX)|KEY|INDEX 3048 ) 3049 \s+ # Followed by at least one white space character. 3050 (?: # Name of the index. Optional if type is PRIMARY KEY. 3051 `? # Name can be escaped with a backtick. 3052 (?P<index_name> # 2) Name of the index. 3053 (?:[0-9a-zA-Z$_-]|[\xC2-\xDF][\x80-\xBF])+ 3054 ) 3055 `? # Name can be escaped with a backtick. 3056 \s+ # Followed by at least one white space character. 3057 )* 3058 \( # Opening bracket for the columns. 3059 (?P<index_columns> 3060 .+? # 3) Column names, index prefixes, and orders. 3061 ) 3062 \) # Closing bracket for the columns. 3063 $/imx', 3064 $fld, 3065 $index_matches 3066 ); 3067 3068 // Uppercase the index type and normalize space characters. 3069 $index_type = strtoupper( preg_replace( '/\s+/', ' ', trim( $index_matches['index_type'] ) ) ); 3070 3071 // 'INDEX' is a synonym for 'KEY', standardize on 'KEY'. 3072 $index_type = str_replace( 'INDEX', 'KEY', $index_type ); 3073 3074 // Escape the index name with backticks. An index for a primary key has no name. 3075 $index_name = ( 'PRIMARY KEY' === $index_type ) ? '' : '`' . strtolower( $index_matches['index_name'] ) . '`'; 3076 3077 // Parse the columns. Multiple columns are separated by a comma. 3078 $index_columns = array_map( 'trim', explode( ',', $index_matches['index_columns'] ) ); 3079 $index_columns_without_subparts = $index_columns; 3080 3081 // Normalize columns. 3082 foreach ( $index_columns as $id => &$index_column ) { 3083 // Extract column name and number of indexed characters (sub_part). 3084 preg_match( 3085 '/ 3086 `? # Name can be escaped with a backtick. 3087 (?P<column_name> # 1) Name of the column. 3088 (?:[0-9a-zA-Z$_-]|[\xC2-\xDF][\x80-\xBF])+ 3089 ) 3090 `? # Name can be escaped with a backtick. 3091 (?: # Optional sub part. 3092 \s* # Optional white space character between name and opening bracket. 3093 \( # Opening bracket for the sub part. 3094 \s* # Optional white space character after opening bracket. 3095 (?P<sub_part> 3096 \d+ # 2) Number of indexed characters. 3097 ) 3098 \s* # Optional white space character before closing bracket. 3099 \) # Closing bracket for the sub part. 3100 )? 3101 /x', 3102 $index_column, 3103 $index_column_matches 3104 ); 3105 3106 // Escape the column name with backticks. 3107 $index_column = '`' . $index_column_matches['column_name'] . '`'; 3108 3109 // We don't need to add the subpart to $index_columns_without_subparts 3110 $index_columns_without_subparts[ $id ] = $index_column; 3111 3112 // Append the optional sup part with the number of indexed characters. 3113 if ( isset( $index_column_matches['sub_part'] ) ) { 3114 $index_column .= '(' . $index_column_matches['sub_part'] . ')'; 3115 } 3116 } 3117 3118 // Build the normalized index definition and add it to the list of indices. 3119 $indices[] = "{$index_type} {$index_name} (" . implode( ',', $index_columns ) . ')'; 3120 $indices_without_subparts[] = "{$index_type} {$index_name} (" . implode( ',', $index_columns_without_subparts ) . ')'; 3121 3122 // Destroy no longer needed variables. 3123 unset( $index_column, $index_column_matches, $index_matches, $index_type, $index_name, $index_columns, $index_columns_without_subparts ); 3124 3125 break; 3126 } 3127 3128 // If it's a valid field, add it to the field array. 3129 if ( $validfield ) { 3130 $cfields[ $fieldname_lowercased ] = $fld; 3131 } 3132 } 3133 3134 // For every field in the table. 3135 foreach ( $tablefields as $tablefield ) { 3136 $tablefield_field_lowercased = strtolower( $tablefield->Field ); 3137 $tablefield_type_lowercased = strtolower( $tablefield->Type ); 3138 3139 $tablefield_type_without_parentheses = preg_replace( 3140 '/' 3141 . '(.+)' // Field type, e.g. `int`. 3142 . '\(\d*\)' // Display width. 3143 . '(.*)' // Optional attributes, e.g. `unsigned`. 3144 . '/', 3145 '$1$2', 3146 $tablefield_type_lowercased 3147 ); 3148 3149 // Get the type without attributes, e.g. `int`. 3150 $tablefield_type_base = strtok( $tablefield_type_without_parentheses, ' ' ); 3151 3152 // If the table field exists in the field array... 3153 if ( array_key_exists( $tablefield_field_lowercased, $cfields ) ) { 3154 3155 // Get the field type from the query. 3156 preg_match( '|`?' . $tablefield->Field . '`? ([^ ]*( unsigned)?)|i', $cfields[ $tablefield_field_lowercased ], $matches ); 3157 $fieldtype = $matches[1]; 3158 $fieldtype_lowercased = strtolower( $fieldtype ); 3159 3160 $fieldtype_without_parentheses = preg_replace( 3161 '/' 3162 . '(.+)' // Field type, e.g. `int`. 3163 . '\(\d*\)' // Display width. 3164 . '(.*)' // Optional attributes, e.g. `unsigned`. 3165 . '/', 3166 '$1$2', 3167 $fieldtype_lowercased 3168 ); 3169 3170 // Get the type without attributes, e.g. `int`. 3171 $fieldtype_base = strtok( $fieldtype_without_parentheses, ' ' ); 3172 3173 // Is actual field type different from the field type in query? 3174 if ( $tablefield->Type !== $fieldtype ) { 3175 $do_change = true; 3176 if ( in_array( $fieldtype_lowercased, $text_fields, true ) && in_array( $tablefield_type_lowercased, $text_fields, true ) ) { 3177 if ( array_search( $fieldtype_lowercased, $text_fields, true ) < array_search( $tablefield_type_lowercased, $text_fields, true ) ) { 3178 $do_change = false; 3179 } 3180 } 3181 3182 if ( in_array( $fieldtype_lowercased, $blob_fields, true ) && in_array( $tablefield_type_lowercased, $blob_fields, true ) ) { 3183 if ( array_search( $fieldtype_lowercased, $blob_fields, true ) < array_search( $tablefield_type_lowercased, $blob_fields, true ) ) { 3184 $do_change = false; 3185 } 3186 } 3187 3188 if ( in_array( $fieldtype_base, $int_fields, true ) && in_array( $tablefield_type_base, $int_fields, true ) 3189 && $fieldtype_without_parentheses === $tablefield_type_without_parentheses 3190 ) { 3191 /* 3192 * MySQL 8.0.17 or later does not support display width for integer data types, 3193 * so if display width is the only difference, it can be safely ignored. 3194 * Note: This is specific to MySQL and does not affect MariaDB. 3195 */ 3196 if ( version_compare( $db_version, '8.0.17', '>=' ) 3197 && ! str_contains( $db_server_info, 'MariaDB' ) 3198 ) { 3199 $do_change = false; 3200 } 3201 } 3202 3203 if ( $do_change ) { 3204 // Add a query to change the column type. 3205 $cqueries[] = "ALTER TABLE {$table} CHANGE COLUMN `{$tablefield->Field}` " . $cfields[ $tablefield_field_lowercased ]; 3206 3207 $for_update[ $table . '.' . $tablefield->Field ] = "Changed type of {$table}.{$tablefield->Field} from {$tablefield->Type} to {$fieldtype}"; 3208 } 3209 } 3210 3211 // Get the default value from the array. 3212 if ( preg_match( "| DEFAULT '(.*?)'|i", $cfields[ $tablefield_field_lowercased ], $matches ) ) { 3213 $default_value = $matches[1]; 3214 if ( $tablefield->Default !== $default_value ) { 3215 // Add a query to change the column's default value 3216 $cqueries[] = "ALTER TABLE {$table} ALTER COLUMN `{$tablefield->Field}` SET DEFAULT '{$default_value}'"; 3217 3218 $for_update[ $table . '.' . $tablefield->Field ] = "Changed default value of {$table}.{$tablefield->Field} from {$tablefield->Default} to {$default_value}"; 3219 } 3220 } 3221 3222 // Remove the field from the array (so it's not added). 3223 unset( $cfields[ $tablefield_field_lowercased ] ); 3224 } else { 3225 // This field exists in the table, but not in the creation queries? 3226 } 3227 } 3228 3229 // For every remaining field specified for the table. 3230 foreach ( $cfields as $fieldname => $fielddef ) { 3231 // Push a query line into $cqueries that adds the field to that table. 3232 $cqueries[] = "ALTER TABLE {$table} ADD COLUMN $fielddef"; 3233 3234 $for_update[ $table . '.' . $fieldname ] = 'Added column ' . $table . '.' . $fieldname; 3235 } 3236 3237 // Index stuff goes here. Fetch the table index structure from the database. 3238 $tableindices = $wpdb->get_results( "SHOW INDEX FROM {$table};" ); 3239 3240 if ( $tableindices ) { 3241 // Clear the index array. 3242 $index_ary = array(); 3243 3244 // For every index in the table. 3245 foreach ( $tableindices as $tableindex ) { 3246 $keyname = strtolower( $tableindex->Key_name ); 3247 3248 // Add the index to the index data array. 3249 $index_ary[ $keyname ]['columns'][] = array( 3250 'fieldname' => $tableindex->Column_name, 3251 'subpart' => $tableindex->Sub_part, 3252 ); 3253 $index_ary[ $keyname ]['unique'] = ( '0' === $tableindex->Non_unique ) ? true : false; 3254 $index_ary[ $keyname ]['index_type'] = $tableindex->Index_type; 3255 } 3256 3257 // For each actual index in the index array. 3258 foreach ( $index_ary as $index_name => $index_data ) { 3259 3260 // Build a create string to compare to the query. 3261 $index_string = ''; 3262 if ( 'primary' === $index_name ) { 3263 $index_string .= 'PRIMARY '; 3264 } elseif ( $index_data['unique'] ) { 3265 $index_string .= 'UNIQUE '; 3266 } 3267 3268 if ( 'FULLTEXT' === strtoupper( $index_data['index_type'] ) ) { 3269 $index_string .= 'FULLTEXT '; 3270 } 3271 3272 if ( 'SPATIAL' === strtoupper( $index_data['index_type'] ) ) { 3273 $index_string .= 'SPATIAL '; 3274 } 3275 3276 $index_string .= 'KEY '; 3277 if ( 'primary' !== $index_name ) { 3278 $index_string .= '`' . $index_name . '`'; 3279 } 3280 3281 $index_columns = ''; 3282 3283 // For each column in the index. 3284 foreach ( $index_data['columns'] as $column_data ) { 3285 if ( '' !== $index_columns ) { 3286 $index_columns .= ','; 3287 } 3288 3289 // Add the field to the column list string. 3290 $index_columns .= '`' . $column_data['fieldname'] . '`'; 3291 } 3292 3293 // Add the column list to the index create string. 3294 $index_string .= " ($index_columns)"; 3295 3296 // Check if the index definition exists, ignoring subparts. 3297 $aindex = array_search( $index_string, $indices_without_subparts, true ); 3298 if ( false !== $aindex ) { 3299 // If the index already exists (even with different subparts), we don't need to create it. 3300 unset( $indices_without_subparts[ $aindex ] ); 3301 unset( $indices[ $aindex ] ); 3302 } 3303 } 3304 } 3305 3306 // For every remaining index specified for the table. 3307 foreach ( (array) $indices as $index ) { 3308 // Push a query line into $cqueries that adds the index to that table. 3309 $cqueries[] = "ALTER TABLE {$table} ADD $index"; 3310 3311 $for_update[] = 'Added index ' . $table . ' ' . $index; 3312 } 3313 3314 // Remove the original table creation query from processing. 3315 unset( $cqueries[ $table ], $for_update[ $table ] ); 3316 } 3317 3318 $allqueries = array_merge( $cqueries, $iqueries ); 3319 if ( $execute ) { 3320 foreach ( $allqueries as $query ) { 3321 $wpdb->query( $query ); 3322 } 3323 } 3324 3325 return $for_update; 3326 } 3327 3328 /** 3329 * Updates the database tables to a new schema. 3330 * 3331 * By default, updates all the tables to use the latest defined schema, but can also 3332 * be used to update a specific set of tables in wp_get_db_schema(). 3333 * 3334 * @since 1.5.0 3335 * 3336 * @uses dbDelta 3337 * 3338 * @param string $tables Optional. Which set of tables to update. Default is 'all'. 3339 */ 3340 function make_db_current( $tables = 'all' ) { 3341 $alterations = dbDelta( $tables ); 3342 echo "<ol>\n"; 3343 foreach ( $alterations as $alteration ) { 3344 echo "<li>$alteration</li>\n"; 3345 } 3346 echo "</ol>\n"; 3347 } 3348 3349 /** 3350 * Updates the database tables to a new schema, but without displaying results. 3351 * 3352 * By default, updates all the tables to use the latest defined schema, but can 3353 * also be used to update a specific set of tables in wp_get_db_schema(). 3354 * 3355 * @since 1.5.0 3356 * 3357 * @see make_db_current() 3358 * 3359 * @param string $tables Optional. Which set of tables to update. Default is 'all'. 3360 */ 3361 function make_db_current_silent( $tables = 'all' ) { 3362 dbDelta( $tables ); 3363 } 3364 3365 /** 3366 * Creates a site theme from an existing theme. 3367 * 3368 * {@internal Missing Long Description}} 3369 * 3370 * @since 1.5.0 3371 * 3372 * @param string $theme_name The name of the theme. 3373 * @param string $template The directory name of the theme. 3374 * @return bool 3375 */ 3376 function make_site_theme_from_oldschool( $theme_name, $template ) { 3377 $home_path = get_home_path(); 3378 $site_dir = WP_CONTENT_DIR . "/themes/$template"; 3379 $default_dir = WP_CONTENT_DIR . '/themes/' . WP_DEFAULT_THEME; 3380 3381 if ( ! file_exists( "$home_path/index.php" ) ) { 3382 return false; 3383 } 3384 3385 /* 3386 * Copy files from the old locations to the site theme. 3387 * TODO: This does not copy arbitrary include dependencies. Only the standard WP files are copied. 3388 */ 3389 $files = array( 3390 'index.php' => 'index.php', 3391 'wp-layout.css' => 'style.css', 3392 'wp-comments.php' => 'comments.php', 3393 'wp-comments-popup.php' => 'comments-popup.php', 3394 ); 3395 3396 foreach ( $files as $oldfile => $newfile ) { 3397 if ( 'index.php' === $oldfile ) { 3398 $oldpath = $home_path; 3399 } else { 3400 $oldpath = ABSPATH; 3401 } 3402 3403 // Check to make sure it's not a new index. 3404 if ( 'index.php' === $oldfile ) { 3405 $index = implode( '', file( "$oldpath/$oldfile" ) ); 3406 if ( str_contains( $index, 'WP_USE_THEMES' ) ) { 3407 if ( ! copy( "$default_dir/$oldfile", "$site_dir/$newfile" ) ) { 3408 return false; 3409 } 3410 3411 // Don't copy anything. 3412 continue; 3413 } 3414 } 3415 3416 if ( ! copy( "$oldpath/$oldfile", "$site_dir/$newfile" ) ) { 3417 return false; 3418 } 3419 3420 chmod( "$site_dir/$newfile", 0777 ); 3421 3422 // Update the blog header include in each file. 3423 $lines = explode( "\n", implode( '', file( "$site_dir/$newfile" ) ) ); 3424 if ( $lines ) { 3425 $f = fopen( "$site_dir/$newfile", 'w' ); 3426 3427 foreach ( $lines as $line ) { 3428 if ( preg_match( '/require.*wp-blog-header/', $line ) ) { 3429 $line = '//' . $line; 3430 } 3431 3432 // Update stylesheet references. 3433 $line = str_replace( 3434 "<?php echo __get_option('siteurl'); ?>/wp-layout.css", 3435 "<?php bloginfo('stylesheet_url'); ?>", 3436 $line 3437 ); 3438 3439 // Update comments template inclusion. 3440 $line = str_replace( 3441 "<?php include(ABSPATH . 'wp-comments.php'); ?>", 3442 '<?php comments_template(); ?>', 3443 $line 3444 ); 3445 3446 fwrite( $f, "{$line}\n" ); 3447 } 3448 fclose( $f ); 3449 } 3450 } 3451 3452 // Add a theme header. 3453 $header = "/*\n" . 3454 "Theme Name: $theme_name\n" . 3455 'Theme URI: ' . __get_option( 'siteurl' ) . "\n" . 3456 "Description: A theme automatically created by the update.\n" . 3457 "Version: 1.0\n" . 3458 "Author: Moi\n" . 3459 "*/\n"; 3460 3461 $stylelines = file_get_contents( "$site_dir/style.css" ); 3462 if ( $stylelines ) { 3463 $f = fopen( "$site_dir/style.css", 'w' ); 3464 3465 fwrite( $f, $header ); 3466 fwrite( $f, $stylelines ); 3467 fclose( $f ); 3468 } 3469 3470 return true; 3471 } 3472 3473 /** 3474 * Creates a site theme from the default theme. 3475 * 3476 * {@internal Missing Long Description}} 3477 * 3478 * @since 1.5.0 3479 * 3480 * @param string $theme_name The name of the theme. 3481 * @param string $template The directory name of the theme. 3482 * @return void|false 3483 */ 3484 function make_site_theme_from_default( $theme_name, $template ) { 3485 $site_dir = WP_CONTENT_DIR . "/themes/$template"; 3486 $default_dir = WP_CONTENT_DIR . '/themes/' . WP_DEFAULT_THEME; 3487 3488 /* 3489 * Copy files from the default theme to the site theme. 3490 * $files = array( 'index.php', 'comments.php', 'comments-popup.php', 'footer.php', 'header.php', 'sidebar.php', 'style.css' ); 3491 */ 3492 3493 $theme_dir = @opendir( $default_dir ); 3494 if ( $theme_dir ) { 3495 while ( ( $theme_file = readdir( $theme_dir ) ) !== false ) { 3496 if ( is_dir( "$default_dir/$theme_file" ) ) { 3497 continue; 3498 } 3499 3500 if ( ! copy( "$default_dir/$theme_file", "$site_dir/$theme_file" ) ) { 3501 return; 3502 } 3503 3504 chmod( "$site_dir/$theme_file", 0777 ); 3505 } 3506 3507 closedir( $theme_dir ); 3508 } 3509 3510 // Rewrite the theme header. 3511 $stylelines = explode( "\n", implode( '', file( "$site_dir/style.css" ) ) ); 3512 if ( $stylelines ) { 3513 $f = fopen( "$site_dir/style.css", 'w' ); 3514 3515 $headers = array( 3516 'Theme Name:' => $theme_name, 3517 'Theme URI:' => __get_option( 'url' ), 3518 'Description:' => 'Your theme.', 3519 'Version:' => '1', 3520 'Author:' => 'You', 3521 ); 3522 3523 foreach ( $stylelines as $line ) { 3524 foreach ( $headers as $header => $value ) { 3525 if ( str_contains( $line, $header ) ) { 3526 $line = $header . ' ' . $value; 3527 break; 3528 } 3529 } 3530 3531 fwrite( $f, $line . "\n" ); 3532 } 3533 3534 fclose( $f ); 3535 } 3536 3537 // Copy the images. 3538 umask( 0 ); 3539 if ( ! mkdir( "$site_dir/images", 0777 ) ) { 3540 return false; 3541 } 3542 3543 $images_dir = @opendir( "$default_dir/images" ); 3544 if ( $images_dir ) { 3545 while ( ( $image = readdir( $images_dir ) ) !== false ) { 3546 if ( is_dir( "$default_dir/images/$image" ) ) { 3547 continue; 3548 } 3549 3550 if ( ! copy( "$default_dir/images/$image", "$site_dir/images/$image" ) ) { 3551 return; 3552 } 3553 3554 chmod( "$site_dir/images/$image", 0777 ); 3555 } 3556 3557 closedir( $images_dir ); 3558 } 3559 } 3560 3561 /** 3562 * Creates a site theme. 3563 * 3564 * {@internal Missing Long Description}} 3565 * 3566 * @since 1.5.0 3567 * 3568 * @return string|false 3569 */ 3570 function make_site_theme() { 3571 // Name the theme after the blog. 3572 $theme_name = __get_option( 'blogname' ); 3573 $template = sanitize_title( $theme_name ); 3574 $site_dir = WP_CONTENT_DIR . "/themes/$template"; 3575 3576 // If the theme already exists, nothing to do. 3577 if ( is_dir( $site_dir ) ) { 3578 return false; 3579 } 3580 3581 // We must be able to write to the themes dir. 3582 if ( ! is_writable( WP_CONTENT_DIR . '/themes' ) ) { 3583 return false; 3584 } 3585 3586 umask( 0 ); 3587 if ( ! mkdir( $site_dir, 0777 ) ) { 3588 return false; 3589 } 3590 3591 if ( file_exists( ABSPATH . 'wp-layout.css' ) ) { 3592 if ( ! make_site_theme_from_oldschool( $theme_name, $template ) ) { 3593 // TODO: rm -rf the site theme directory. 3594 return false; 3595 } 3596 } else { 3597 if ( ! make_site_theme_from_default( $theme_name, $template ) ) { 3598 // TODO: rm -rf the site theme directory. 3599 return false; 3600 } 3601 } 3602 3603 // Make the new site theme active. 3604 $current_template = __get_option( 'template' ); 3605 if ( WP_DEFAULT_THEME === $current_template ) { 3606 update_option( 'template', $template ); 3607 update_option( 'stylesheet', $template ); 3608 } 3609 return $template; 3610 } 3611 3612 /** 3613 * Translate user level to user role name. 3614 * 3615 * @since 2.0.0 3616 * 3617 * @param int $level User level. 3618 * @return string User role name. 3619 */ 3620 function translate_level_to_role( $level ) { 3621 switch ( $level ) { 3622 case 10: 3623 case 9: 3624 case 8: 3625 return 'administrator'; 3626 case 7: 3627 case 6: 3628 case 5: 3629 return 'editor'; 3630 case 4: 3631 case 3: 3632 case 2: 3633 return 'author'; 3634 case 1: 3635 return 'contributor'; 3636 case 0: 3637 default: 3638 return 'subscriber'; 3639 } 3640 } 3641 3642 /** 3643 * Checks the version of the installed MySQL binary. 3644 * 3645 * @since 2.1.0 3646 * 3647 * @global wpdb $wpdb WordPress database abstraction object. 3648 */ 3649 function wp_check_mysql_version() { 3650 global $wpdb; 3651 $result = $wpdb->check_database_version(); 3652 if ( is_wp_error( $result ) ) { 3653 wp_die( $result ); 3654 } 3655 } 3656 3657 /** 3658 * Disables the Automattic widgets plugin, which was merged into core. 3659 * 3660 * @since 2.2.0 3661 */ 3662 function maybe_disable_automattic_widgets() { 3663 $plugins = __get_option( 'active_plugins' ); 3664 3665 foreach ( (array) $plugins as $plugin ) { 3666 if ( 'widgets.php' === basename( $plugin ) ) { 3667 array_splice( $plugins, array_search( $plugin, $plugins, true ), 1 ); 3668 update_option( 'active_plugins', $plugins ); 3669 break; 3670 } 3671 } 3672 } 3673 3674 /** 3675 * Disables the Link Manager on upgrade if, at the time of upgrade, no links exist in the DB. 3676 * 3677 * @since 3.5.0 3678 * 3679 * @global int $wp_current_db_version The old (current) database version. 3680 * @global wpdb $wpdb WordPress database abstraction object. 3681 */ 3682 function maybe_disable_link_manager() { 3683 global $wp_current_db_version, $wpdb; 3684 3685 if ( $wp_current_db_version >= 22006 && get_option( 'link_manager_enabled' ) && ! $wpdb->get_var( "SELECT link_id FROM $wpdb->links LIMIT 1" ) ) { 3686 update_option( 'link_manager_enabled', 0 ); 3687 } 3688 } 3689 3690 /** 3691 * Runs before the schema is upgraded. 3692 * 3693 * @since 2.9.0 3694 * 3695 * @global int $wp_current_db_version The old (current) database version. 3696 * @global wpdb $wpdb WordPress database abstraction object. 3697 */ 3698 function pre_schema_upgrade() { 3699 global $wp_current_db_version, $wpdb; 3700 3701 // Upgrade versions prior to 2.9. 3702 if ( $wp_current_db_version < 11557 ) { 3703 // Delete duplicate options. Keep the option with the highest option_id. 3704 $wpdb->query( "DELETE o1 FROM $wpdb->options AS o1 JOIN $wpdb->options AS o2 USING (`option_name`) WHERE o2.option_id > o1.option_id" ); 3705 3706 // Drop the old primary key and add the new. 3707 $wpdb->query( "ALTER TABLE $wpdb->options DROP PRIMARY KEY, ADD PRIMARY KEY(option_id)" ); 3708 3709 // Drop the old option_name index. dbDelta() doesn't do the drop. 3710 $wpdb->query( "ALTER TABLE $wpdb->options DROP INDEX option_name" ); 3711 } 3712 3713 // Multisite schema upgrades. 3714 if ( $wp_current_db_version < 25448 && is_multisite() && wp_should_upgrade_global_tables() ) { 3715 3716 // Upgrade versions prior to 3.7. 3717 if ( $wp_current_db_version < 25179 ) { 3718 // New primary key for signups. 3719 $wpdb->query( "ALTER TABLE $wpdb->signups ADD signup_id BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST" ); 3720 $wpdb->query( "ALTER TABLE $wpdb->signups DROP INDEX domain" ); 3721 } 3722 3723 if ( $wp_current_db_version < 25448 ) { 3724 // Convert archived from enum to tinyint. 3725 $wpdb->query( "ALTER TABLE $wpdb->blogs CHANGE COLUMN archived archived varchar(1) NOT NULL default '0'" ); 3726 $wpdb->query( "ALTER TABLE $wpdb->blogs CHANGE COLUMN archived archived tinyint(2) NOT NULL default 0" ); 3727 } 3728 } 3729 3730 // Upgrade versions prior to 4.2. 3731 if ( $wp_current_db_version < 31351 ) { 3732 if ( ! is_multisite() && wp_should_upgrade_global_tables() ) { 3733 $wpdb->query( "ALTER TABLE $wpdb->usermeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" ); 3734 } 3735 $wpdb->query( "ALTER TABLE $wpdb->terms DROP INDEX slug, ADD INDEX slug(slug(191))" ); 3736 $wpdb->query( "ALTER TABLE $wpdb->terms DROP INDEX name, ADD INDEX name(name(191))" ); 3737 $wpdb->query( "ALTER TABLE $wpdb->commentmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" ); 3738 $wpdb->query( "ALTER TABLE $wpdb->postmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" ); 3739 $wpdb->query( "ALTER TABLE $wpdb->posts DROP INDEX post_name, ADD INDEX post_name(post_name(191))" ); 3740 } 3741 3742 // Upgrade versions prior to 4.4. 3743 if ( $wp_current_db_version < 34978 ) { 3744 // If compatible termmeta table is found, use it, but enforce a proper index and update collation. 3745 if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->termmeta}'" ) && $wpdb->get_results( "SHOW INDEX FROM {$wpdb->termmeta} WHERE Column_name = 'meta_key'" ) ) { 3746 $wpdb->query( "ALTER TABLE $wpdb->termmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" ); 3747 maybe_convert_table_to_utf8mb4( $wpdb->termmeta ); 3748 } 3749 } 3750 } 3751 3752 /** 3753 * Determine if global tables should be upgraded. 3754 * 3755 * This function performs a series of checks to ensure the environment allows 3756 * for the safe upgrading of global WordPress database tables. It is necessary 3757 * because global tables will commonly grow to millions of rows on large 3758 * installations, and the ability to control their upgrade routines can be 3759 * critical to the operation of large networks. 3760 * 3761 * In a future iteration, this function may use `wp_is_large_network()` to more- 3762 * intelligently prevent global table upgrades. Until then, we make sure 3763 * WordPress is on the main site of the main network, to avoid running queries 3764 * more than once in multi-site or multi-network environments. 3765 * 3766 * @since 4.3.0 3767 * 3768 * @return bool Whether to run the upgrade routines on global tables. 3769 */ 3770 function wp_should_upgrade_global_tables() { 3771 3772 // Return false early if explicitly not upgrading. 3773 if ( defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) { 3774 return false; 3775 } 3776 3777 // Assume global tables should be upgraded. 3778 $should_upgrade = true; 3779 3780 // Set to false if not on main network (does not matter if not multi-network). 3781 if ( ! is_main_network() ) { 3782 $should_upgrade = false; 3783 } 3784 3785 // Set to false if not on main site of current network (does not matter if not multi-site). 3786 if ( ! is_main_site() ) { 3787 $should_upgrade = false; 3788 } 3789 3790 /** 3791 * Filters if upgrade routines should be run on global tables. 3792 * 3793 * @since 4.3.0 3794 * 3795 * @param bool $should_upgrade Whether to run the upgrade routines on global tables. 3796 */ 3797 return apply_filters( 'wp_should_upgrade_global_tables', $should_upgrade ); 3798 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Sun Jul 13 08:20:01 2025 | Cross-referenced by PHPXref |