[ 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', 1 ); 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 maybe_disable_link_manager(); 885 886 maybe_disable_automattic_widgets(); 887 888 update_option( 'db_version', $wp_db_version ); 889 update_option( 'db_upgraded', true ); 890 } 891 892 /** 893 * Execute changes made in WordPress 1.0. 894 * 895 * @ignore 896 * @since 1.0.0 897 * 898 * @global wpdb $wpdb WordPress database abstraction object. 899 */ 900 function upgrade_100() { 901 global $wpdb; 902 903 // Get the title and ID of every post, post_name to check if it already has a value. 904 $posts = $wpdb->get_results( "SELECT ID, post_title, post_name FROM $wpdb->posts WHERE post_name = ''" ); 905 if ( $posts ) { 906 foreach ( $posts as $post ) { 907 if ( '' === $post->post_name ) { 908 $newtitle = sanitize_title( $post->post_title ); 909 $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_name = %s WHERE ID = %d", $newtitle, $post->ID ) ); 910 } 911 } 912 } 913 914 $categories = $wpdb->get_results( "SELECT cat_ID, cat_name, category_nicename FROM $wpdb->categories" ); 915 foreach ( $categories as $category ) { 916 if ( '' === $category->category_nicename ) { 917 $newtitle = sanitize_title( $category->cat_name ); 918 $wpdb->update( $wpdb->categories, array( 'category_nicename' => $newtitle ), array( 'cat_ID' => $category->cat_ID ) ); 919 } 920 } 921 922 $sql = "UPDATE $wpdb->options 923 SET option_value = REPLACE(option_value, 'wp-links/links-images/', 'wp-images/links/') 924 WHERE option_name LIKE %s 925 AND option_value LIKE %s"; 926 $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( 'links_rating_image' ) . '%', $wpdb->esc_like( 'wp-links/links-images/' ) . '%' ) ); 927 928 $done_ids = $wpdb->get_results( "SELECT DISTINCT post_id FROM $wpdb->post2cat" ); 929 if ( $done_ids ) : 930 $done_posts = array(); 931 foreach ( $done_ids as $done_id ) : 932 $done_posts[] = $done_id->post_id; 933 endforeach; 934 $catwhere = ' AND ID NOT IN (' . implode( ',', $done_posts ) . ')'; 935 else : 936 $catwhere = ''; 937 endif; 938 939 $allposts = $wpdb->get_results( "SELECT ID, post_category FROM $wpdb->posts WHERE post_category != '0' $catwhere" ); 940 if ( $allposts ) : 941 foreach ( $allposts as $post ) { 942 // Check to see if it's already been imported. 943 $cat = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->post2cat WHERE post_id = %d AND category_id = %d", $post->ID, $post->post_category ) ); 944 if ( ! $cat && 0 !== (int) $post->post_category ) { // If there's no result. 945 $wpdb->insert( 946 $wpdb->post2cat, 947 array( 948 'post_id' => $post->ID, 949 'category_id' => $post->post_category, 950 ) 951 ); 952 } 953 } 954 endif; 955 } 956 957 /** 958 * Execute changes made in WordPress 1.0.1. 959 * 960 * @ignore 961 * @since 1.0.1 962 * 963 * @global wpdb $wpdb WordPress database abstraction object. 964 */ 965 function upgrade_101() { 966 global $wpdb; 967 968 // Clean up indices, add a few. 969 add_clean_index( $wpdb->posts, 'post_name' ); 970 add_clean_index( $wpdb->posts, 'post_status' ); 971 add_clean_index( $wpdb->categories, 'category_nicename' ); 972 add_clean_index( $wpdb->comments, 'comment_approved' ); 973 add_clean_index( $wpdb->comments, 'comment_post_ID' ); 974 add_clean_index( $wpdb->links, 'link_category' ); 975 add_clean_index( $wpdb->links, 'link_visible' ); 976 } 977 978 /** 979 * Execute changes made in WordPress 1.2. 980 * 981 * @ignore 982 * @since 1.2.0 983 * @since 6.8.0 User passwords are no longer hashed with md5. 984 * 985 * @global wpdb $wpdb WordPress database abstraction object. 986 */ 987 function upgrade_110() { 988 global $wpdb; 989 990 // Set user_nicename. 991 $users = $wpdb->get_results( "SELECT ID, user_nickname, user_nicename FROM $wpdb->users" ); 992 foreach ( $users as $user ) { 993 if ( '' === $user->user_nicename ) { 994 $newname = sanitize_title( $user->user_nickname ); 995 $wpdb->update( $wpdb->users, array( 'user_nicename' => $newname ), array( 'ID' => $user->ID ) ); 996 } 997 } 998 999 // Get the GMT offset, we'll use that later on. 1000 $all_options = get_alloptions_110(); 1001 1002 $time_difference = $all_options->time_difference; 1003 1004 $server_time = time() + (int) gmdate( 'Z' ); 1005 $weblogger_time = $server_time + $time_difference * HOUR_IN_SECONDS; 1006 $gmt_time = time(); 1007 1008 $diff_gmt_server = ( $gmt_time - $server_time ) / HOUR_IN_SECONDS; 1009 $diff_weblogger_server = ( $weblogger_time - $server_time ) / HOUR_IN_SECONDS; 1010 $diff_gmt_weblogger = $diff_gmt_server - $diff_weblogger_server; 1011 $gmt_offset = -$diff_gmt_weblogger; 1012 1013 // Add a gmt_offset option, with value $gmt_offset. 1014 add_option( 'gmt_offset', $gmt_offset ); 1015 1016 /* 1017 * Check if we already set the GMT fields. If we did, then 1018 * MAX(post_date_gmt) can't be '0000-00-00 00:00:00'. 1019 * <michel_v> I just slapped myself silly for not thinking about it earlier. 1020 */ 1021 $got_gmt_fields = ( '0000-00-00 00:00:00' !== $wpdb->get_var( "SELECT MAX(post_date_gmt) FROM $wpdb->posts" ) ); 1022 1023 if ( ! $got_gmt_fields ) { 1024 1025 // Add or subtract time to all dates, to get GMT dates. 1026 $add_hours = (int) $diff_gmt_weblogger; 1027 $add_minutes = (int) ( 60 * ( $diff_gmt_weblogger - $add_hours ) ); 1028 $wpdb->query( "UPDATE $wpdb->posts SET post_date_gmt = DATE_ADD(post_date, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)" ); 1029 $wpdb->query( "UPDATE $wpdb->posts SET post_modified = post_date" ); 1030 $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'" ); 1031 $wpdb->query( "UPDATE $wpdb->comments SET comment_date_gmt = DATE_ADD(comment_date, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)" ); 1032 $wpdb->query( "UPDATE $wpdb->users SET user_registered = DATE_ADD(user_registered, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)" ); 1033 } 1034 } 1035 1036 /** 1037 * Execute changes made in WordPress 1.5. 1038 * 1039 * @ignore 1040 * @since 1.5.0 1041 * 1042 * @global wpdb $wpdb WordPress database abstraction object. 1043 */ 1044 function upgrade_130() { 1045 global $wpdb; 1046 1047 // Remove extraneous backslashes. 1048 $posts = $wpdb->get_results( "SELECT ID, post_title, post_content, post_excerpt, guid, post_date, post_name, post_status, post_author FROM $wpdb->posts" ); 1049 if ( $posts ) { 1050 foreach ( $posts as $post ) { 1051 $post_content = addslashes( deslash( $post->post_content ) ); 1052 $post_title = addslashes( deslash( $post->post_title ) ); 1053 $post_excerpt = addslashes( deslash( $post->post_excerpt ) ); 1054 if ( empty( $post->guid ) ) { 1055 $guid = get_permalink( $post->ID ); 1056 } else { 1057 $guid = $post->guid; 1058 } 1059 1060 $wpdb->update( $wpdb->posts, compact( 'post_title', 'post_content', 'post_excerpt', 'guid' ), array( 'ID' => $post->ID ) ); 1061 1062 } 1063 } 1064 1065 // Remove extraneous backslashes. 1066 $comments = $wpdb->get_results( "SELECT comment_ID, comment_author, comment_content FROM $wpdb->comments" ); 1067 if ( $comments ) { 1068 foreach ( $comments as $comment ) { 1069 $comment_content = deslash( $comment->comment_content ); 1070 $comment_author = deslash( $comment->comment_author ); 1071 1072 $wpdb->update( $wpdb->comments, compact( 'comment_content', 'comment_author' ), array( 'comment_ID' => $comment->comment_ID ) ); 1073 } 1074 } 1075 1076 // Remove extraneous backslashes. 1077 $links = $wpdb->get_results( "SELECT link_id, link_name, link_description FROM $wpdb->links" ); 1078 if ( $links ) { 1079 foreach ( $links as $link ) { 1080 $link_name = deslash( $link->link_name ); 1081 $link_description = deslash( $link->link_description ); 1082 1083 $wpdb->update( $wpdb->links, compact( 'link_name', 'link_description' ), array( 'link_id' => $link->link_id ) ); 1084 } 1085 } 1086 1087 $active_plugins = __get_option( 'active_plugins' ); 1088 1089 /* 1090 * If plugins are not stored in an array, they're stored in the old 1091 * newline separated format. Convert to new format. 1092 */ 1093 if ( ! is_array( $active_plugins ) ) { 1094 $active_plugins = explode( "\n", trim( $active_plugins ) ); 1095 update_option( 'active_plugins', $active_plugins ); 1096 } 1097 1098 // Obsolete tables. 1099 $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optionvalues' ); 1100 $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiontypes' ); 1101 $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiongroups' ); 1102 $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiongroup_options' ); 1103 1104 // Update comments table to use comment_type. 1105 $wpdb->query( "UPDATE $wpdb->comments SET comment_type='trackback', comment_content = REPLACE(comment_content, '<trackback />', '') WHERE comment_content LIKE '<trackback />%'" ); 1106 $wpdb->query( "UPDATE $wpdb->comments SET comment_type='pingback', comment_content = REPLACE(comment_content, '<pingback />', '') WHERE comment_content LIKE '<pingback />%'" ); 1107 1108 // Some versions have multiple duplicate option_name rows with the same values. 1109 $options = $wpdb->get_results( "SELECT option_name, COUNT(option_name) AS dupes FROM `$wpdb->options` GROUP BY option_name" ); 1110 foreach ( $options as $option ) { 1111 if ( $option->dupes > 1 ) { // Could this be done in the query? 1112 $limit = $option->dupes - 1; 1113 $dupe_ids = $wpdb->get_col( $wpdb->prepare( "SELECT option_id FROM $wpdb->options WHERE option_name = %s LIMIT %d", $option->option_name, $limit ) ); 1114 if ( $dupe_ids ) { 1115 $dupe_ids = implode( ',', $dupe_ids ); 1116 $wpdb->query( "DELETE FROM $wpdb->options WHERE option_id IN ($dupe_ids)" ); 1117 } 1118 } 1119 } 1120 1121 make_site_theme(); 1122 } 1123 1124 /** 1125 * Execute changes made in WordPress 2.0. 1126 * 1127 * @ignore 1128 * @since 2.0.0 1129 * 1130 * @global wpdb $wpdb WordPress database abstraction object. 1131 * @global int $wp_current_db_version The old (current) database version. 1132 */ 1133 function upgrade_160() { 1134 global $wpdb, $wp_current_db_version; 1135 1136 populate_roles_160(); 1137 1138 $users = $wpdb->get_results( "SELECT * FROM $wpdb->users" ); 1139 foreach ( $users as $user ) : 1140 if ( ! empty( $user->user_firstname ) ) { 1141 update_user_meta( $user->ID, 'first_name', wp_slash( $user->user_firstname ) ); 1142 } 1143 if ( ! empty( $user->user_lastname ) ) { 1144 update_user_meta( $user->ID, 'last_name', wp_slash( $user->user_lastname ) ); 1145 } 1146 if ( ! empty( $user->user_nickname ) ) { 1147 update_user_meta( $user->ID, 'nickname', wp_slash( $user->user_nickname ) ); 1148 } 1149 if ( ! empty( $user->user_level ) ) { 1150 update_user_meta( $user->ID, $wpdb->prefix . 'user_level', $user->user_level ); 1151 } 1152 if ( ! empty( $user->user_icq ) ) { 1153 update_user_meta( $user->ID, 'icq', wp_slash( $user->user_icq ) ); 1154 } 1155 if ( ! empty( $user->user_aim ) ) { 1156 update_user_meta( $user->ID, 'aim', wp_slash( $user->user_aim ) ); 1157 } 1158 if ( ! empty( $user->user_msn ) ) { 1159 update_user_meta( $user->ID, 'msn', wp_slash( $user->user_msn ) ); 1160 } 1161 if ( ! empty( $user->user_yim ) ) { 1162 update_user_meta( $user->ID, 'yim', wp_slash( $user->user_icq ) ); 1163 } 1164 if ( ! empty( $user->user_description ) ) { 1165 update_user_meta( $user->ID, 'description', wp_slash( $user->user_description ) ); 1166 } 1167 1168 if ( isset( $user->user_idmode ) ) : 1169 $idmode = $user->user_idmode; 1170 if ( 'nickname' === $idmode ) { 1171 $id = $user->user_nickname; 1172 } 1173 if ( 'login' === $idmode ) { 1174 $id = $user->user_login; 1175 } 1176 if ( 'firstname' === $idmode ) { 1177 $id = $user->user_firstname; 1178 } 1179 if ( 'lastname' === $idmode ) { 1180 $id = $user->user_lastname; 1181 } 1182 if ( 'namefl' === $idmode ) { 1183 $id = $user->user_firstname . ' ' . $user->user_lastname; 1184 } 1185 if ( 'namelf' === $idmode ) { 1186 $id = $user->user_lastname . ' ' . $user->user_firstname; 1187 } 1188 if ( ! $idmode ) { 1189 $id = $user->user_nickname; 1190 } 1191 $wpdb->update( $wpdb->users, array( 'display_name' => $id ), array( 'ID' => $user->ID ) ); 1192 endif; 1193 1194 // FIXME: RESET_CAPS is temporary code to reset roles and caps if flag is set. 1195 $caps = get_user_meta( $user->ID, $wpdb->prefix . 'capabilities' ); 1196 if ( empty( $caps ) || defined( 'RESET_CAPS' ) ) { 1197 $level = get_user_meta( $user->ID, $wpdb->prefix . 'user_level', true ); 1198 $role = translate_level_to_role( $level ); 1199 update_user_meta( $user->ID, $wpdb->prefix . 'capabilities', array( $role => true ) ); 1200 } 1201 1202 endforeach; 1203 $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' ); 1204 $wpdb->hide_errors(); 1205 foreach ( $old_user_fields as $old ) { 1206 $wpdb->query( "ALTER TABLE $wpdb->users DROP $old" ); 1207 } 1208 $wpdb->show_errors(); 1209 1210 // Populate comment_count field of posts table. 1211 $comments = $wpdb->get_results( "SELECT comment_post_ID, COUNT(*) as c FROM $wpdb->comments WHERE comment_approved = '1' GROUP BY comment_post_ID" ); 1212 if ( is_array( $comments ) ) { 1213 foreach ( $comments as $comment ) { 1214 $wpdb->update( $wpdb->posts, array( 'comment_count' => $comment->c ), array( 'ID' => $comment->comment_post_ID ) ); 1215 } 1216 } 1217 1218 /* 1219 * Some alpha versions used a post status of object instead of attachment 1220 * and put the mime type in post_type instead of post_mime_type. 1221 */ 1222 if ( $wp_current_db_version > 2541 && $wp_current_db_version <= 3091 ) { 1223 $objects = $wpdb->get_results( "SELECT ID, post_type FROM $wpdb->posts WHERE post_status = 'object'" ); 1224 foreach ( $objects as $object ) { 1225 $wpdb->update( 1226 $wpdb->posts, 1227 array( 1228 'post_status' => 'attachment', 1229 'post_mime_type' => $object->post_type, 1230 'post_type' => '', 1231 ), 1232 array( 'ID' => $object->ID ) 1233 ); 1234 1235 $meta = get_post_meta( $object->ID, 'imagedata', true ); 1236 if ( ! empty( $meta['file'] ) ) { 1237 update_attached_file( $object->ID, $meta['file'] ); 1238 } 1239 } 1240 } 1241 } 1242 1243 /** 1244 * Execute changes made in WordPress 2.1. 1245 * 1246 * @ignore 1247 * @since 2.1.0 1248 * 1249 * @global int $wp_current_db_version The old (current) database version. 1250 * @global wpdb $wpdb WordPress database abstraction object. 1251 */ 1252 function upgrade_210() { 1253 global $wp_current_db_version, $wpdb; 1254 1255 if ( $wp_current_db_version < 3506 ) { 1256 // Update status and type. 1257 $posts = $wpdb->get_results( "SELECT ID, post_status FROM $wpdb->posts" ); 1258 1259 if ( ! empty( $posts ) ) { 1260 foreach ( $posts as $post ) { 1261 $status = $post->post_status; 1262 $type = 'post'; 1263 1264 if ( 'static' === $status ) { 1265 $status = 'publish'; 1266 $type = 'page'; 1267 } elseif ( 'attachment' === $status ) { 1268 $status = 'inherit'; 1269 $type = 'attachment'; 1270 } 1271 1272 $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_status = %s, post_type = %s WHERE ID = %d", $status, $type, $post->ID ) ); 1273 } 1274 } 1275 } 1276 1277 if ( $wp_current_db_version < 3845 ) { 1278 populate_roles_210(); 1279 } 1280 1281 if ( $wp_current_db_version < 3531 ) { 1282 // Give future posts a post_status of future. 1283 $now = gmdate( 'Y-m-d H:i:59' ); 1284 $wpdb->query( "UPDATE $wpdb->posts SET post_status = 'future' WHERE post_status = 'publish' AND post_date_gmt > '$now'" ); 1285 1286 $posts = $wpdb->get_results( "SELECT ID, post_date FROM $wpdb->posts WHERE post_status ='future'" ); 1287 if ( ! empty( $posts ) ) { 1288 foreach ( $posts as $post ) { 1289 wp_schedule_single_event( mysql2date( 'U', $post->post_date, false ), 'publish_future_post', array( $post->ID ) ); 1290 } 1291 } 1292 } 1293 } 1294 1295 /** 1296 * Execute changes made in WordPress 2.3. 1297 * 1298 * @ignore 1299 * @since 2.3.0 1300 * 1301 * @global int $wp_current_db_version The old (current) database version. 1302 * @global wpdb $wpdb WordPress database abstraction object. 1303 */ 1304 function upgrade_230() { 1305 global $wp_current_db_version, $wpdb; 1306 1307 if ( $wp_current_db_version < 5200 ) { 1308 populate_roles_230(); 1309 } 1310 1311 // Convert categories to terms. 1312 $tt_ids = array(); 1313 $have_tags = false; 1314 $categories = $wpdb->get_results( "SELECT * FROM $wpdb->categories ORDER BY cat_ID" ); 1315 foreach ( $categories as $category ) { 1316 $term_id = (int) $category->cat_ID; 1317 $name = $category->cat_name; 1318 $description = $category->category_description; 1319 $slug = $category->category_nicename; 1320 $parent = $category->category_parent; 1321 $term_group = 0; 1322 1323 // Associate terms with the same slug in a term group and make slugs unique. 1324 $exists = $wpdb->get_results( $wpdb->prepare( "SELECT term_id, term_group FROM $wpdb->terms WHERE slug = %s", $slug ) ); 1325 if ( $exists ) { 1326 $term_group = $exists[0]->term_group; 1327 $id = $exists[0]->term_id; 1328 $num = 2; 1329 do { 1330 $alt_slug = $slug . "-$num"; 1331 ++$num; 1332 $slug_check = $wpdb->get_var( $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s", $alt_slug ) ); 1333 } while ( $slug_check ); 1334 1335 $slug = $alt_slug; 1336 1337 if ( empty( $term_group ) ) { 1338 $term_group = $wpdb->get_var( "SELECT MAX(term_group) FROM $wpdb->terms GROUP BY term_group" ) + 1; 1339 $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->terms SET term_group = %d WHERE term_id = %d", $term_group, $id ) ); 1340 } 1341 } 1342 1343 $wpdb->query( 1344 $wpdb->prepare( 1345 "INSERT INTO $wpdb->terms (term_id, name, slug, term_group) VALUES 1346 (%d, %s, %s, %d)", 1347 $term_id, 1348 $name, 1349 $slug, 1350 $term_group 1351 ) 1352 ); 1353 1354 $count = 0; 1355 if ( ! empty( $category->category_count ) ) { 1356 $count = (int) $category->category_count; 1357 $taxonomy = 'category'; 1358 $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 ) ); 1359 $tt_ids[ $term_id ][ $taxonomy ] = (int) $wpdb->insert_id; 1360 } 1361 1362 if ( ! empty( $category->link_count ) ) { 1363 $count = (int) $category->link_count; 1364 $taxonomy = 'link_category'; 1365 $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 ) ); 1366 $tt_ids[ $term_id ][ $taxonomy ] = (int) $wpdb->insert_id; 1367 } 1368 1369 if ( ! empty( $category->tag_count ) ) { 1370 $have_tags = true; 1371 $count = (int) $category->tag_count; 1372 $taxonomy = 'post_tag'; 1373 $wpdb->insert( $wpdb->term_taxonomy, compact( 'term_id', 'taxonomy', 'description', 'parent', 'count' ) ); 1374 $tt_ids[ $term_id ][ $taxonomy ] = (int) $wpdb->insert_id; 1375 } 1376 1377 if ( empty( $count ) ) { 1378 $count = 0; 1379 $taxonomy = 'category'; 1380 $wpdb->insert( $wpdb->term_taxonomy, compact( 'term_id', 'taxonomy', 'description', 'parent', 'count' ) ); 1381 $tt_ids[ $term_id ][ $taxonomy ] = (int) $wpdb->insert_id; 1382 } 1383 } 1384 1385 $select = 'post_id, category_id'; 1386 if ( $have_tags ) { 1387 $select .= ', rel_type'; 1388 } 1389 1390 $posts = $wpdb->get_results( "SELECT $select FROM $wpdb->post2cat GROUP BY post_id, category_id" ); 1391 foreach ( $posts as $post ) { 1392 $post_id = (int) $post->post_id; 1393 $term_id = (int) $post->category_id; 1394 $taxonomy = 'category'; 1395 if ( ! empty( $post->rel_type ) && 'tag' === $post->rel_type ) { 1396 $taxonomy = 'tag'; 1397 } 1398 $tt_id = $tt_ids[ $term_id ][ $taxonomy ]; 1399 if ( empty( $tt_id ) ) { 1400 continue; 1401 } 1402 1403 $wpdb->insert( 1404 $wpdb->term_relationships, 1405 array( 1406 'object_id' => $post_id, 1407 'term_taxonomy_id' => $tt_id, 1408 ) 1409 ); 1410 } 1411 1412 // < 3570 we used linkcategories. >= 3570 we used categories and link2cat. 1413 if ( $wp_current_db_version < 3570 ) { 1414 /* 1415 * Create link_category terms for link categories. Create a map of link 1416 * category IDs to link_category terms. 1417 */ 1418 $link_cat_id_map = array(); 1419 $default_link_cat = 0; 1420 $tt_ids = array(); 1421 $link_cats = $wpdb->get_results( 'SELECT cat_id, cat_name FROM ' . $wpdb->prefix . 'linkcategories' ); 1422 foreach ( $link_cats as $category ) { 1423 $cat_id = (int) $category->cat_id; 1424 $term_id = 0; 1425 $name = wp_slash( $category->cat_name ); 1426 $slug = sanitize_title( $name ); 1427 $term_group = 0; 1428 1429 // Associate terms with the same slug in a term group and make slugs unique. 1430 $exists = $wpdb->get_results( $wpdb->prepare( "SELECT term_id, term_group FROM $wpdb->terms WHERE slug = %s", $slug ) ); 1431 if ( $exists ) { 1432 $term_group = $exists[0]->term_group; 1433 $term_id = $exists[0]->term_id; 1434 } 1435 1436 if ( empty( $term_id ) ) { 1437 $wpdb->insert( $wpdb->terms, compact( 'name', 'slug', 'term_group' ) ); 1438 $term_id = (int) $wpdb->insert_id; 1439 } 1440 1441 $link_cat_id_map[ $cat_id ] = $term_id; 1442 $default_link_cat = $term_id; 1443 1444 $wpdb->insert( 1445 $wpdb->term_taxonomy, 1446 array( 1447 'term_id' => $term_id, 1448 'taxonomy' => 'link_category', 1449 'description' => '', 1450 'parent' => 0, 1451 'count' => 0, 1452 ) 1453 ); 1454 $tt_ids[ $term_id ] = (int) $wpdb->insert_id; 1455 } 1456 1457 // Associate links to categories. 1458 $links = $wpdb->get_results( "SELECT link_id, link_category FROM $wpdb->links" ); 1459 if ( ! empty( $links ) ) { 1460 foreach ( $links as $link ) { 1461 if ( 0 === (int) $link->link_category ) { 1462 continue; 1463 } 1464 if ( ! isset( $link_cat_id_map[ $link->link_category ] ) ) { 1465 continue; 1466 } 1467 $term_id = $link_cat_id_map[ $link->link_category ]; 1468 $tt_id = $tt_ids[ $term_id ]; 1469 if ( empty( $tt_id ) ) { 1470 continue; 1471 } 1472 1473 $wpdb->insert( 1474 $wpdb->term_relationships, 1475 array( 1476 'object_id' => $link->link_id, 1477 'term_taxonomy_id' => $tt_id, 1478 ) 1479 ); 1480 } 1481 } 1482 1483 // Set default to the last category we grabbed during the upgrade loop. 1484 update_option( 'default_link_category', $default_link_cat ); 1485 } else { 1486 $links = $wpdb->get_results( "SELECT link_id, category_id FROM $wpdb->link2cat GROUP BY link_id, category_id" ); 1487 foreach ( $links as $link ) { 1488 $link_id = (int) $link->link_id; 1489 $term_id = (int) $link->category_id; 1490 $taxonomy = 'link_category'; 1491 $tt_id = $tt_ids[ $term_id ][ $taxonomy ]; 1492 if ( empty( $tt_id ) ) { 1493 continue; 1494 } 1495 $wpdb->insert( 1496 $wpdb->term_relationships, 1497 array( 1498 'object_id' => $link_id, 1499 'term_taxonomy_id' => $tt_id, 1500 ) 1501 ); 1502 } 1503 } 1504 1505 if ( $wp_current_db_version < 4772 ) { 1506 // Obsolete linkcategories table. 1507 $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . 'linkcategories' ); 1508 } 1509 1510 // Recalculate all counts. 1511 $terms = $wpdb->get_results( "SELECT term_taxonomy_id, taxonomy FROM $wpdb->term_taxonomy" ); 1512 foreach ( (array) $terms as $term ) { 1513 if ( 'post_tag' === $term->taxonomy || 'category' === $term->taxonomy ) { 1514 $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 ) ); 1515 } else { 1516 $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d", $term->term_taxonomy_id ) ); 1517 } 1518 $wpdb->update( $wpdb->term_taxonomy, array( 'count' => $count ), array( 'term_taxonomy_id' => $term->term_taxonomy_id ) ); 1519 } 1520 } 1521 1522 /** 1523 * Remove old options from the database. 1524 * 1525 * @ignore 1526 * @since 2.3.0 1527 * 1528 * @global wpdb $wpdb WordPress database abstraction object. 1529 */ 1530 function upgrade_230_options_table() { 1531 global $wpdb; 1532 $old_options_fields = array( 'option_can_override', 'option_type', 'option_width', 'option_height', 'option_description', 'option_admin_level' ); 1533 $wpdb->hide_errors(); 1534 foreach ( $old_options_fields as $old ) { 1535 $wpdb->query( "ALTER TABLE $wpdb->options DROP $old" ); 1536 } 1537 $wpdb->show_errors(); 1538 } 1539 1540 /** 1541 * Remove old categories, link2cat, and post2cat database tables. 1542 * 1543 * @ignore 1544 * @since 2.3.0 1545 * 1546 * @global wpdb $wpdb WordPress database abstraction object. 1547 */ 1548 function upgrade_230_old_tables() { 1549 global $wpdb; 1550 $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . 'categories' ); 1551 $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . 'link2cat' ); 1552 $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . 'post2cat' ); 1553 } 1554 1555 /** 1556 * Upgrade old slugs made in version 2.2. 1557 * 1558 * @ignore 1559 * @since 2.2.0 1560 * 1561 * @global wpdb $wpdb WordPress database abstraction object. 1562 */ 1563 function upgrade_old_slugs() { 1564 // Upgrade people who were using the Redirect Old Slugs plugin. 1565 global $wpdb; 1566 $wpdb->query( "UPDATE $wpdb->postmeta SET meta_key = '_wp_old_slug' WHERE meta_key = 'old_slug'" ); 1567 } 1568 1569 /** 1570 * Execute changes made in WordPress 2.5.0. 1571 * 1572 * @ignore 1573 * @since 2.5.0 1574 * 1575 * @global int $wp_current_db_version The old (current) database version. 1576 */ 1577 function upgrade_250() { 1578 global $wp_current_db_version; 1579 1580 if ( $wp_current_db_version < 6689 ) { 1581 populate_roles_250(); 1582 } 1583 } 1584 1585 /** 1586 * Execute changes made in WordPress 2.5.2. 1587 * 1588 * @ignore 1589 * @since 2.5.2 1590 * 1591 * @global wpdb $wpdb WordPress database abstraction object. 1592 */ 1593 function upgrade_252() { 1594 global $wpdb; 1595 1596 $wpdb->query( "UPDATE $wpdb->users SET user_activation_key = ''" ); 1597 } 1598 1599 /** 1600 * Execute changes made in WordPress 2.6. 1601 * 1602 * @ignore 1603 * @since 2.6.0 1604 * 1605 * @global int $wp_current_db_version The old (current) database version. 1606 */ 1607 function upgrade_260() { 1608 global $wp_current_db_version; 1609 1610 if ( $wp_current_db_version < 8000 ) { 1611 populate_roles_260(); 1612 } 1613 } 1614 1615 /** 1616 * Execute changes made in WordPress 2.7. 1617 * 1618 * @ignore 1619 * @since 2.7.0 1620 * 1621 * @global int $wp_current_db_version The old (current) database version. 1622 * @global wpdb $wpdb WordPress database abstraction object. 1623 */ 1624 function upgrade_270() { 1625 global $wp_current_db_version, $wpdb; 1626 1627 if ( $wp_current_db_version < 8980 ) { 1628 populate_roles_270(); 1629 } 1630 1631 // Update post_date for unpublished posts with empty timestamp. 1632 if ( $wp_current_db_version < 8921 ) { 1633 $wpdb->query( "UPDATE $wpdb->posts SET post_date = post_modified WHERE post_date = '0000-00-00 00:00:00'" ); 1634 } 1635 } 1636 1637 /** 1638 * Execute changes made in WordPress 2.8. 1639 * 1640 * @ignore 1641 * @since 2.8.0 1642 * 1643 * @global int $wp_current_db_version The old (current) database version. 1644 * @global wpdb $wpdb WordPress database abstraction object. 1645 */ 1646 function upgrade_280() { 1647 global $wp_current_db_version, $wpdb; 1648 1649 if ( $wp_current_db_version < 10360 ) { 1650 populate_roles_280(); 1651 } 1652 if ( is_multisite() ) { 1653 $start = 0; 1654 while ( $rows = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options ORDER BY option_id LIMIT $start, 20" ) ) { 1655 foreach ( $rows as $row ) { 1656 $value = maybe_unserialize( $row->option_value ); 1657 if ( $value === $row->option_value ) { 1658 $value = stripslashes( $value ); 1659 } 1660 if ( $value !== $row->option_value ) { 1661 update_option( $row->option_name, $value ); 1662 } 1663 } 1664 $start += 20; 1665 } 1666 clean_blog_cache( get_current_blog_id() ); 1667 } 1668 } 1669 1670 /** 1671 * Execute changes made in WordPress 2.9. 1672 * 1673 * @ignore 1674 * @since 2.9.0 1675 * 1676 * @global int $wp_current_db_version The old (current) database version. 1677 */ 1678 function upgrade_290() { 1679 global $wp_current_db_version; 1680 1681 if ( $wp_current_db_version < 11958 ) { 1682 /* 1683 * Previously, setting depth to 1 would redundantly disable threading, 1684 * but now 2 is the minimum depth to avoid confusion. 1685 */ 1686 if ( 1 === (int) get_option( 'thread_comments_depth' ) ) { 1687 update_option( 'thread_comments_depth', 2 ); 1688 update_option( 'thread_comments', 0 ); 1689 } 1690 } 1691 } 1692 1693 /** 1694 * Execute changes made in WordPress 3.0. 1695 * 1696 * @ignore 1697 * @since 3.0.0 1698 * 1699 * @global int $wp_current_db_version The old (current) database version. 1700 * @global wpdb $wpdb WordPress database abstraction object. 1701 */ 1702 function upgrade_300() { 1703 global $wp_current_db_version, $wpdb; 1704 1705 if ( $wp_current_db_version < 15093 ) { 1706 populate_roles_300(); 1707 } 1708 1709 if ( $wp_current_db_version < 14139 && is_multisite() && is_main_site() && ! defined( 'MULTISITE' ) && get_site_option( 'siteurl' ) === false ) { 1710 add_site_option( 'siteurl', '' ); 1711 } 1712 1713 // 3.0 screen options key name changes. 1714 if ( wp_should_upgrade_global_tables() ) { 1715 $sql = "DELETE FROM $wpdb->usermeta 1716 WHERE meta_key LIKE %s 1717 OR meta_key LIKE %s 1718 OR meta_key LIKE %s 1719 OR meta_key LIKE %s 1720 OR meta_key LIKE %s 1721 OR meta_key LIKE %s 1722 OR meta_key = 'manageedittagscolumnshidden' 1723 OR meta_key = 'managecategoriescolumnshidden' 1724 OR meta_key = 'manageedit-tagscolumnshidden' 1725 OR meta_key = 'manageeditcolumnshidden' 1726 OR meta_key = 'categories_per_page' 1727 OR meta_key = 'edit_tags_per_page'"; 1728 $prefix = $wpdb->esc_like( $wpdb->base_prefix ); 1729 $wpdb->query( 1730 $wpdb->prepare( 1731 $sql, 1732 $prefix . '%' . $wpdb->esc_like( 'meta-box-hidden' ) . '%', 1733 $prefix . '%' . $wpdb->esc_like( 'closedpostboxes' ) . '%', 1734 $prefix . '%' . $wpdb->esc_like( 'manage-' ) . '%' . $wpdb->esc_like( '-columns-hidden' ) . '%', 1735 $prefix . '%' . $wpdb->esc_like( 'meta-box-order' ) . '%', 1736 $prefix . '%' . $wpdb->esc_like( 'metaboxorder' ) . '%', 1737 $prefix . '%' . $wpdb->esc_like( 'screen_layout' ) . '%' 1738 ) 1739 ); 1740 } 1741 } 1742 1743 /** 1744 * Execute changes made in WordPress 3.3. 1745 * 1746 * @ignore 1747 * @since 3.3.0 1748 * 1749 * @global int $wp_current_db_version The old (current) database version. 1750 * @global wpdb $wpdb WordPress database abstraction object. 1751 * @global array $wp_registered_widgets 1752 * @global array $sidebars_widgets 1753 */ 1754 function upgrade_330() { 1755 global $wp_current_db_version, $wpdb, $wp_registered_widgets, $sidebars_widgets; 1756 1757 if ( $wp_current_db_version < 19061 && wp_should_upgrade_global_tables() ) { 1758 $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key IN ('show_admin_bar_admin', 'plugins_last_view')" ); 1759 } 1760 1761 if ( $wp_current_db_version >= 11548 ) { 1762 return; 1763 } 1764 1765 $sidebars_widgets = get_option( 'sidebars_widgets', array() ); 1766 $_sidebars_widgets = array(); 1767 1768 if ( isset( $sidebars_widgets['wp_inactive_widgets'] ) || empty( $sidebars_widgets ) ) { 1769 $sidebars_widgets['array_version'] = 3; 1770 } elseif ( ! isset( $sidebars_widgets['array_version'] ) ) { 1771 $sidebars_widgets['array_version'] = 1; 1772 } 1773 1774 switch ( $sidebars_widgets['array_version'] ) { 1775 case 1: 1776 foreach ( (array) $sidebars_widgets as $index => $sidebar ) { 1777 if ( is_array( $sidebar ) ) { 1778 foreach ( (array) $sidebar as $i => $name ) { 1779 $id = strtolower( $name ); 1780 if ( isset( $wp_registered_widgets[ $id ] ) ) { 1781 $_sidebars_widgets[ $index ][ $i ] = $id; 1782 continue; 1783 } 1784 1785 $id = sanitize_title( $name ); 1786 if ( isset( $wp_registered_widgets[ $id ] ) ) { 1787 $_sidebars_widgets[ $index ][ $i ] = $id; 1788 continue; 1789 } 1790 1791 $found = false; 1792 1793 foreach ( $wp_registered_widgets as $widget_id => $widget ) { 1794 if ( strtolower( $widget['name'] ) === strtolower( $name ) ) { 1795 $_sidebars_widgets[ $index ][ $i ] = $widget['id']; 1796 1797 $found = true; 1798 break; 1799 } elseif ( sanitize_title( $widget['name'] ) === sanitize_title( $name ) ) { 1800 $_sidebars_widgets[ $index ][ $i ] = $widget['id']; 1801 1802 $found = true; 1803 break; 1804 } 1805 } 1806 1807 if ( $found ) { 1808 continue; 1809 } 1810 1811 unset( $_sidebars_widgets[ $index ][ $i ] ); 1812 } 1813 } 1814 } 1815 $_sidebars_widgets['array_version'] = 2; 1816 $sidebars_widgets = $_sidebars_widgets; 1817 unset( $_sidebars_widgets ); 1818 1819 // Intentional fall-through to upgrade to the next version. 1820 case 2: 1821 $sidebars_widgets = retrieve_widgets(); 1822 $sidebars_widgets['array_version'] = 3; 1823 update_option( 'sidebars_widgets', $sidebars_widgets ); 1824 } 1825 } 1826 1827 /** 1828 * Execute changes made in WordPress 3.4. 1829 * 1830 * @ignore 1831 * @since 3.4.0 1832 * 1833 * @global int $wp_current_db_version The old (current) database version. 1834 * @global wpdb $wpdb WordPress database abstraction object. 1835 */ 1836 function upgrade_340() { 1837 global $wp_current_db_version, $wpdb; 1838 1839 if ( $wp_current_db_version < 19798 ) { 1840 $wpdb->hide_errors(); 1841 $wpdb->query( "ALTER TABLE $wpdb->options DROP COLUMN blog_id" ); 1842 $wpdb->show_errors(); 1843 } 1844 1845 if ( $wp_current_db_version < 19799 ) { 1846 $wpdb->hide_errors(); 1847 $wpdb->query( "ALTER TABLE $wpdb->comments DROP INDEX comment_approved" ); 1848 $wpdb->show_errors(); 1849 } 1850 1851 if ( $wp_current_db_version < 20022 && wp_should_upgrade_global_tables() ) { 1852 $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key = 'themes_last_view'" ); 1853 } 1854 1855 if ( $wp_current_db_version < 20080 ) { 1856 if ( 'yes' === $wpdb->get_var( "SELECT autoload FROM $wpdb->options WHERE option_name = 'uninstall_plugins'" ) ) { 1857 $uninstall_plugins = get_option( 'uninstall_plugins' ); 1858 delete_option( 'uninstall_plugins' ); 1859 add_option( 'uninstall_plugins', $uninstall_plugins, null, false ); 1860 } 1861 } 1862 } 1863 1864 /** 1865 * Execute changes made in WordPress 3.5. 1866 * 1867 * @ignore 1868 * @since 3.5.0 1869 * 1870 * @global int $wp_current_db_version The old (current) database version. 1871 * @global wpdb $wpdb WordPress database abstraction object. 1872 */ 1873 function upgrade_350() { 1874 global $wp_current_db_version, $wpdb; 1875 1876 if ( $wp_current_db_version < 22006 && $wpdb->get_var( "SELECT link_id FROM $wpdb->links LIMIT 1" ) ) { 1877 update_option( 'link_manager_enabled', 1 ); // Previously set to 0 by populate_options(). 1878 } 1879 1880 if ( $wp_current_db_version < 21811 && wp_should_upgrade_global_tables() ) { 1881 $meta_keys = array(); 1882 foreach ( array_merge( get_post_types(), get_taxonomies() ) as $name ) { 1883 if ( str_contains( $name, '-' ) ) { 1884 $meta_keys[] = 'edit_' . str_replace( '-', '_', $name ) . '_per_page'; 1885 } 1886 } 1887 if ( $meta_keys ) { 1888 $meta_keys = implode( "', '", $meta_keys ); 1889 $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key IN ('$meta_keys')" ); 1890 } 1891 } 1892 1893 if ( $wp_current_db_version < 22422 ) { 1894 $term = get_term_by( 'slug', 'post-format-standard', 'post_format' ); 1895 if ( $term ) { 1896 wp_delete_term( $term->term_id, 'post_format' ); 1897 } 1898 } 1899 } 1900 1901 /** 1902 * Execute changes made in WordPress 3.7. 1903 * 1904 * @ignore 1905 * @since 3.7.0 1906 * 1907 * @global int $wp_current_db_version The old (current) database version. 1908 */ 1909 function upgrade_370() { 1910 global $wp_current_db_version; 1911 1912 if ( $wp_current_db_version < 25824 ) { 1913 wp_clear_scheduled_hook( 'wp_auto_updates_maybe_update' ); 1914 } 1915 } 1916 1917 /** 1918 * Execute changes made in WordPress 3.7.2. 1919 * 1920 * @ignore 1921 * @since 3.7.2 1922 * 1923 * @global int $wp_current_db_version The old (current) database version. 1924 */ 1925 function upgrade_372() { 1926 global $wp_current_db_version; 1927 1928 if ( $wp_current_db_version < 26148 ) { 1929 wp_clear_scheduled_hook( 'wp_maybe_auto_update' ); 1930 } 1931 } 1932 1933 /** 1934 * Execute changes made in WordPress 3.8.0. 1935 * 1936 * @ignore 1937 * @since 3.8.0 1938 * 1939 * @global int $wp_current_db_version The old (current) database version. 1940 */ 1941 function upgrade_380() { 1942 global $wp_current_db_version; 1943 1944 if ( $wp_current_db_version < 26691 ) { 1945 deactivate_plugins( array( 'mp6/mp6.php' ), true ); 1946 } 1947 } 1948 1949 /** 1950 * Execute changes made in WordPress 4.0.0. 1951 * 1952 * @ignore 1953 * @since 4.0.0 1954 * 1955 * @global int $wp_current_db_version The old (current) database version. 1956 */ 1957 function upgrade_400() { 1958 global $wp_current_db_version; 1959 1960 if ( $wp_current_db_version < 29630 ) { 1961 if ( ! is_multisite() && false === get_option( 'WPLANG' ) ) { 1962 if ( defined( 'WPLANG' ) && ( '' !== WPLANG ) && in_array( WPLANG, get_available_languages(), true ) ) { 1963 update_option( 'WPLANG', WPLANG ); 1964 } else { 1965 update_option( 'WPLANG', '' ); 1966 } 1967 } 1968 } 1969 } 1970 1971 /** 1972 * Execute changes made in WordPress 4.2.0. 1973 * 1974 * @ignore 1975 * @since 4.2.0 1976 */ 1977 function upgrade_420() {} 1978 1979 /** 1980 * Executes changes made in WordPress 4.3.0. 1981 * 1982 * @ignore 1983 * @since 4.3.0 1984 * 1985 * @global int $wp_current_db_version The old (current) database version. 1986 * @global wpdb $wpdb WordPress database abstraction object. 1987 */ 1988 function upgrade_430() { 1989 global $wp_current_db_version, $wpdb; 1990 1991 if ( $wp_current_db_version < 32364 ) { 1992 upgrade_430_fix_comments(); 1993 } 1994 1995 // Shared terms are split in a separate process. 1996 if ( $wp_current_db_version < 32814 ) { 1997 update_option( 'finished_splitting_shared_terms', 0 ); 1998 wp_schedule_single_event( time() + ( 1 * MINUTE_IN_SECONDS ), 'wp_split_shared_term_batch' ); 1999 } 2000 2001 if ( $wp_current_db_version < 33055 && 'utf8mb4' === $wpdb->charset ) { 2002 if ( is_multisite() ) { 2003 $tables = $wpdb->tables( 'blog' ); 2004 } else { 2005 $tables = $wpdb->tables( 'all' ); 2006 if ( ! wp_should_upgrade_global_tables() ) { 2007 $global_tables = $wpdb->tables( 'global' ); 2008 $tables = array_diff_assoc( $tables, $global_tables ); 2009 } 2010 } 2011 2012 foreach ( $tables as $table ) { 2013 maybe_convert_table_to_utf8mb4( $table ); 2014 } 2015 } 2016 } 2017 2018 /** 2019 * Executes comments changes made in WordPress 4.3.0. 2020 * 2021 * @ignore 2022 * @since 4.3.0 2023 * 2024 * @global wpdb $wpdb WordPress database abstraction object. 2025 */ 2026 function upgrade_430_fix_comments() { 2027 global $wpdb; 2028 2029 $content_length = $wpdb->get_col_length( $wpdb->comments, 'comment_content' ); 2030 2031 if ( is_wp_error( $content_length ) ) { 2032 return; 2033 } 2034 2035 if ( false === $content_length ) { 2036 $content_length = array( 2037 'type' => 'byte', 2038 'length' => 65535, 2039 ); 2040 } elseif ( ! is_array( $content_length ) ) { 2041 $length = (int) $content_length > 0 ? (int) $content_length : 65535; 2042 $content_length = array( 2043 'type' => 'byte', 2044 'length' => $length, 2045 ); 2046 } 2047 2048 if ( 'byte' !== $content_length['type'] || 0 === $content_length['length'] ) { 2049 // Sites with malformed DB schemas are on their own. 2050 return; 2051 } 2052 2053 $allowed_length = (int) $content_length['length'] - 10; 2054 2055 $comments = $wpdb->get_results( 2056 "SELECT `comment_ID` FROM `{$wpdb->comments}` 2057 WHERE `comment_date_gmt` > '2015-04-26' 2058 AND LENGTH( `comment_content` ) >= {$allowed_length} 2059 AND ( `comment_content` LIKE '%<%' OR `comment_content` LIKE '%>%' )" 2060 ); 2061 2062 foreach ( $comments as $comment ) { 2063 wp_delete_comment( $comment->comment_ID, true ); 2064 } 2065 } 2066 2067 /** 2068 * Executes changes made in WordPress 4.3.1. 2069 * 2070 * @ignore 2071 * @since 4.3.1 2072 */ 2073 function upgrade_431() { 2074 // Fix incorrect cron entries for term splitting. 2075 $cron_array = _get_cron_array(); 2076 if ( isset( $cron_array['wp_batch_split_terms'] ) ) { 2077 unset( $cron_array['wp_batch_split_terms'] ); 2078 _set_cron_array( $cron_array ); 2079 } 2080 } 2081 2082 /** 2083 * Executes changes made in WordPress 4.4.0. 2084 * 2085 * @ignore 2086 * @since 4.4.0 2087 * 2088 * @global int $wp_current_db_version The old (current) database version. 2089 * @global wpdb $wpdb WordPress database abstraction object. 2090 */ 2091 function upgrade_440() { 2092 global $wp_current_db_version, $wpdb; 2093 2094 if ( $wp_current_db_version < 34030 ) { 2095 $wpdb->query( "ALTER TABLE {$wpdb->options} MODIFY option_name VARCHAR(191)" ); 2096 } 2097 2098 // Remove the unused 'add_users' role. 2099 $roles = wp_roles(); 2100 foreach ( $roles->role_objects as $role ) { 2101 if ( $role->has_cap( 'add_users' ) ) { 2102 $role->remove_cap( 'add_users' ); 2103 } 2104 } 2105 } 2106 2107 /** 2108 * Executes changes made in WordPress 4.5.0. 2109 * 2110 * @ignore 2111 * @since 4.5.0 2112 * 2113 * @global int $wp_current_db_version The old (current) database version. 2114 * @global wpdb $wpdb WordPress database abstraction object. 2115 */ 2116 function upgrade_450() { 2117 global $wp_current_db_version, $wpdb; 2118 2119 if ( $wp_current_db_version < 36180 ) { 2120 wp_clear_scheduled_hook( 'wp_maybe_auto_update' ); 2121 } 2122 2123 // Remove unused email confirmation options, moved to usermeta. 2124 if ( $wp_current_db_version < 36679 && is_multisite() ) { 2125 $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name REGEXP '^[0-9]+_new_email$'" ); 2126 } 2127 2128 // Remove unused user setting for wpLink. 2129 delete_user_setting( 'wplink' ); 2130 } 2131 2132 /** 2133 * Executes changes made in WordPress 4.6.0. 2134 * 2135 * @ignore 2136 * @since 4.6.0 2137 * 2138 * @global int $wp_current_db_version The old (current) database version. 2139 */ 2140 function upgrade_460() { 2141 global $wp_current_db_version; 2142 2143 // Remove unused post meta. 2144 if ( $wp_current_db_version < 37854 ) { 2145 delete_post_meta_by_key( '_post_restored_from' ); 2146 } 2147 2148 // Remove plugins with callback as an array object/method as the uninstall hook, see #13786. 2149 if ( $wp_current_db_version < 37965 ) { 2150 $uninstall_plugins = get_option( 'uninstall_plugins', array() ); 2151 2152 if ( ! empty( $uninstall_plugins ) ) { 2153 foreach ( $uninstall_plugins as $basename => $callback ) { 2154 if ( is_array( $callback ) && is_object( $callback[0] ) ) { 2155 unset( $uninstall_plugins[ $basename ] ); 2156 } 2157 } 2158 2159 update_option( 'uninstall_plugins', $uninstall_plugins ); 2160 } 2161 } 2162 } 2163 2164 /** 2165 * Executes changes made in WordPress 5.0.0. 2166 * 2167 * @ignore 2168 * @since 5.0.0 2169 * @deprecated 5.1.0 2170 */ 2171 function upgrade_500() { 2172 } 2173 2174 /** 2175 * Executes changes made in WordPress 5.1.0. 2176 * 2177 * @ignore 2178 * @since 5.1.0 2179 */ 2180 function upgrade_510() { 2181 delete_site_option( 'upgrade_500_was_gutenberg_active' ); 2182 } 2183 2184 /** 2185 * Executes changes made in WordPress 5.3.0. 2186 * 2187 * @ignore 2188 * @since 5.3.0 2189 */ 2190 function upgrade_530() { 2191 /* 2192 * The `admin_email_lifespan` option may have been set by an admin that just logged in, 2193 * saw the verification screen, clicked on a button there, and is now upgrading the db, 2194 * or by populate_options() that is called earlier in upgrade_all(). 2195 * In the second case `admin_email_lifespan` should be reset so the verification screen 2196 * is shown next time an admin logs in. 2197 */ 2198 if ( function_exists( 'current_user_can' ) && ! current_user_can( 'manage_options' ) ) { 2199 update_option( 'admin_email_lifespan', 0 ); 2200 } 2201 } 2202 2203 /** 2204 * Executes changes made in WordPress 5.5.0. 2205 * 2206 * @ignore 2207 * @since 5.5.0 2208 * 2209 * @global int $wp_current_db_version The old (current) database version. 2210 */ 2211 function upgrade_550() { 2212 global $wp_current_db_version; 2213 2214 if ( $wp_current_db_version < 48121 ) { 2215 $comment_previously_approved = get_option( 'comment_whitelist', '' ); 2216 update_option( 'comment_previously_approved', $comment_previously_approved ); 2217 delete_option( 'comment_whitelist' ); 2218 } 2219 2220 if ( $wp_current_db_version < 48575 ) { 2221 // Use more clear and inclusive language. 2222 $disallowed_list = get_option( 'blacklist_keys' ); 2223 2224 /* 2225 * This option key was briefly renamed `blocklist_keys`. 2226 * Account for sites that have this key present when the original key does not exist. 2227 */ 2228 if ( false === $disallowed_list ) { 2229 $disallowed_list = get_option( 'blocklist_keys' ); 2230 } 2231 2232 update_option( 'disallowed_keys', $disallowed_list ); 2233 delete_option( 'blacklist_keys' ); 2234 delete_option( 'blocklist_keys' ); 2235 } 2236 2237 if ( $wp_current_db_version < 48748 ) { 2238 update_option( 'finished_updating_comment_type', 0 ); 2239 wp_schedule_single_event( time() + ( 1 * MINUTE_IN_SECONDS ), 'wp_update_comment_type_batch' ); 2240 } 2241 } 2242 2243 /** 2244 * Executes changes made in WordPress 5.6.0. 2245 * 2246 * @ignore 2247 * @since 5.6.0 2248 * 2249 * @global int $wp_current_db_version The old (current) database version. 2250 * @global wpdb $wpdb WordPress database abstraction object. 2251 */ 2252 function upgrade_560() { 2253 global $wp_current_db_version, $wpdb; 2254 2255 if ( $wp_current_db_version < 49572 ) { 2256 /* 2257 * Clean up the `post_category` column removed from schema in version 2.8.0. 2258 * Its presence may conflict with `WP_Post::__get()`. 2259 */ 2260 $post_category_exists = $wpdb->get_var( "SHOW COLUMNS FROM $wpdb->posts LIKE 'post_category'" ); 2261 if ( ! is_null( $post_category_exists ) ) { 2262 $wpdb->query( "ALTER TABLE $wpdb->posts DROP COLUMN `post_category`" ); 2263 } 2264 2265 /* 2266 * When upgrading from WP < 5.6.0 set the core major auto-updates option to `unset` by default. 2267 * This overrides the same option from populate_options() that is intended for new installs. 2268 * See https://core.trac.wordpress.org/ticket/51742. 2269 */ 2270 update_option( 'auto_update_core_major', 'unset' ); 2271 } 2272 2273 if ( $wp_current_db_version < 49632 ) { 2274 /* 2275 * Regenerate the .htaccess file to add the `HTTP_AUTHORIZATION` rewrite rule. 2276 * See https://core.trac.wordpress.org/ticket/51723. 2277 */ 2278 save_mod_rewrite_rules(); 2279 } 2280 2281 if ( $wp_current_db_version < 49735 ) { 2282 delete_transient( 'dirsize_cache' ); 2283 } 2284 2285 if ( $wp_current_db_version < 49752 ) { 2286 $results = $wpdb->get_results( 2287 $wpdb->prepare( 2288 "SELECT 1 FROM {$wpdb->usermeta} WHERE meta_key = %s LIMIT 1", 2289 WP_Application_Passwords::USERMETA_KEY_APPLICATION_PASSWORDS 2290 ) 2291 ); 2292 2293 if ( ! empty( $results ) ) { 2294 $network_id = get_main_network_id(); 2295 update_network_option( $network_id, WP_Application_Passwords::OPTION_KEY_IN_USE, 1 ); 2296 } 2297 } 2298 } 2299 2300 /** 2301 * Executes changes made in WordPress 5.9.0. 2302 * 2303 * @ignore 2304 * @since 5.9.0 2305 * 2306 * @global int $wp_current_db_version The old (current) database version. 2307 */ 2308 function upgrade_590() { 2309 global $wp_current_db_version; 2310 2311 if ( $wp_current_db_version < 51917 ) { 2312 $crons = _get_cron_array(); 2313 2314 if ( $crons && is_array( $crons ) ) { 2315 // Remove errant `false` values, see #53950, #54906. 2316 $crons = array_filter( $crons ); 2317 _set_cron_array( $crons ); 2318 } 2319 } 2320 } 2321 2322 /** 2323 * Executes changes made in WordPress 6.0.0. 2324 * 2325 * @ignore 2326 * @since 6.0.0 2327 * 2328 * @global int $wp_current_db_version The old (current) database version. 2329 */ 2330 function upgrade_600() { 2331 global $wp_current_db_version; 2332 2333 if ( $wp_current_db_version < 53011 ) { 2334 wp_update_user_counts(); 2335 } 2336 } 2337 2338 /** 2339 * Executes changes made in WordPress 6.3.0. 2340 * 2341 * @ignore 2342 * @since 6.3.0 2343 * 2344 * @global int $wp_current_db_version The old (current) database version. 2345 */ 2346 function upgrade_630() { 2347 global $wp_current_db_version; 2348 2349 if ( $wp_current_db_version < 55853 ) { 2350 if ( ! is_multisite() ) { 2351 // Replace non-autoload option can_compress_scripts with autoload option, see #55270 2352 $can_compress_scripts = get_option( 'can_compress_scripts', false ); 2353 if ( false !== $can_compress_scripts ) { 2354 delete_option( 'can_compress_scripts' ); 2355 add_option( 'can_compress_scripts', $can_compress_scripts, '', true ); 2356 } 2357 } 2358 } 2359 } 2360 2361 /** 2362 * Executes changes made in WordPress 6.4.0. 2363 * 2364 * @ignore 2365 * @since 6.4.0 2366 * 2367 * @global int $wp_current_db_version The old (current) database version. 2368 */ 2369 function upgrade_640() { 2370 global $wp_current_db_version; 2371 2372 if ( $wp_current_db_version < 56657 ) { 2373 // Enable attachment pages. 2374 update_option( 'wp_attachment_pages_enabled', 1 ); 2375 2376 // Remove the wp_https_detection cron. Https status is checked directly in an async Site Health check. 2377 $scheduled = wp_get_scheduled_event( 'wp_https_detection' ); 2378 if ( $scheduled ) { 2379 wp_clear_scheduled_hook( 'wp_https_detection' ); 2380 } 2381 } 2382 } 2383 2384 /** 2385 * Executes changes made in WordPress 6.5.0. 2386 * 2387 * @ignore 2388 * @since 6.5.0 2389 * 2390 * @global int $wp_current_db_version The old (current) database version. 2391 * @global wpdb $wpdb WordPress database abstraction object. 2392 */ 2393 function upgrade_650() { 2394 global $wp_current_db_version, $wpdb; 2395 2396 if ( $wp_current_db_version < 57155 ) { 2397 $stylesheet = get_stylesheet(); 2398 2399 // Set autoload=no for all themes except the current one. 2400 $theme_mods_options = $wpdb->get_col( 2401 $wpdb->prepare( 2402 "SELECT option_name FROM $wpdb->options WHERE autoload = 'yes' AND option_name != %s AND option_name LIKE %s", 2403 "theme_mods_$stylesheet", 2404 $wpdb->esc_like( 'theme_mods_' ) . '%' 2405 ) 2406 ); 2407 2408 $autoload = array_fill_keys( $theme_mods_options, false ); 2409 wp_set_option_autoload_values( $autoload ); 2410 } 2411 } 2412 /** 2413 * Executes changes made in WordPress 6.7.0. 2414 * 2415 * @ignore 2416 * @since 6.7.0 2417 * 2418 * @global int $wp_current_db_version The old (current) database version. 2419 */ 2420 function upgrade_670() { 2421 global $wp_current_db_version; 2422 2423 if ( $wp_current_db_version < 58975 ) { 2424 $options = array( 2425 'recently_activated', 2426 '_wp_suggested_policy_text_has_changed', 2427 'dashboard_widget_options', 2428 'ftp_credentials', 2429 'adminhash', 2430 'nav_menu_options', 2431 'wp_force_deactivated_plugins', 2432 'delete_blog_hash', 2433 'allowedthemes', 2434 'recovery_keys', 2435 'https_detection_errors', 2436 'fresh_site', 2437 ); 2438 2439 wp_set_options_autoload( $options, false ); 2440 } 2441 } 2442 /** 2443 * Executes network-level upgrade routines. 2444 * 2445 * @since 3.0.0 2446 * 2447 * @global int $wp_current_db_version The old (current) database version. 2448 * @global wpdb $wpdb WordPress database abstraction object. 2449 */ 2450 function upgrade_network() { 2451 global $wp_current_db_version, $wpdb; 2452 2453 // Always clear expired transients. 2454 delete_expired_transients( true ); 2455 2456 // 2.8.0 2457 if ( $wp_current_db_version < 11549 ) { 2458 $wpmu_sitewide_plugins = get_site_option( 'wpmu_sitewide_plugins' ); 2459 $active_sitewide_plugins = get_site_option( 'active_sitewide_plugins' ); 2460 if ( $wpmu_sitewide_plugins ) { 2461 if ( ! $active_sitewide_plugins ) { 2462 $sitewide_plugins = (array) $wpmu_sitewide_plugins; 2463 } else { 2464 $sitewide_plugins = array_merge( (array) $active_sitewide_plugins, (array) $wpmu_sitewide_plugins ); 2465 } 2466 2467 update_site_option( 'active_sitewide_plugins', $sitewide_plugins ); 2468 } 2469 delete_site_option( 'wpmu_sitewide_plugins' ); 2470 delete_site_option( 'deactivated_sitewide_plugins' ); 2471 2472 $start = 0; 2473 while ( $rows = $wpdb->get_results( "SELECT meta_key, meta_value FROM {$wpdb->sitemeta} ORDER BY meta_id LIMIT $start, 20" ) ) { 2474 foreach ( $rows as $row ) { 2475 $value = $row->meta_value; 2476 if ( ! @unserialize( $value ) ) { 2477 $value = stripslashes( $value ); 2478 } 2479 if ( $value !== $row->meta_value ) { 2480 update_site_option( $row->meta_key, $value ); 2481 } 2482 } 2483 $start += 20; 2484 } 2485 } 2486 2487 // 3.0.0 2488 if ( $wp_current_db_version < 13576 ) { 2489 update_site_option( 'global_terms_enabled', '1' ); 2490 } 2491 2492 // 3.3.0 2493 if ( $wp_current_db_version < 19390 ) { 2494 update_site_option( 'initial_db_version', $wp_current_db_version ); 2495 } 2496 2497 if ( $wp_current_db_version < 19470 ) { 2498 if ( false === get_site_option( 'active_sitewide_plugins' ) ) { 2499 update_site_option( 'active_sitewide_plugins', array() ); 2500 } 2501 } 2502 2503 // 3.4.0 2504 if ( $wp_current_db_version < 20148 ) { 2505 // 'allowedthemes' keys things by stylesheet. 'allowed_themes' keyed things by name. 2506 $allowedthemes = get_site_option( 'allowedthemes' ); 2507 $allowed_themes = get_site_option( 'allowed_themes' ); 2508 if ( false === $allowedthemes && is_array( $allowed_themes ) && $allowed_themes ) { 2509 $converted = array(); 2510 $themes = wp_get_themes(); 2511 foreach ( $themes as $stylesheet => $theme_data ) { 2512 if ( isset( $allowed_themes[ $theme_data->get( 'Name' ) ] ) ) { 2513 $converted[ $stylesheet ] = true; 2514 } 2515 } 2516 update_site_option( 'allowedthemes', $converted ); 2517 delete_site_option( 'allowed_themes' ); 2518 } 2519 } 2520 2521 // 3.5.0 2522 if ( $wp_current_db_version < 21823 ) { 2523 update_site_option( 'ms_files_rewriting', '1' ); 2524 } 2525 2526 // 3.5.2 2527 if ( $wp_current_db_version < 24448 ) { 2528 $illegal_names = get_site_option( 'illegal_names' ); 2529 if ( is_array( $illegal_names ) && count( $illegal_names ) === 1 ) { 2530 $illegal_name = reset( $illegal_names ); 2531 $illegal_names = explode( ' ', $illegal_name ); 2532 update_site_option( 'illegal_names', $illegal_names ); 2533 } 2534 } 2535 2536 // 4.2.0 2537 if ( $wp_current_db_version < 31351 && 'utf8mb4' === $wpdb->charset ) { 2538 if ( wp_should_upgrade_global_tables() ) { 2539 $wpdb->query( "ALTER TABLE $wpdb->usermeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" ); 2540 $wpdb->query( "ALTER TABLE $wpdb->site DROP INDEX domain, ADD INDEX domain(domain(140),path(51))" ); 2541 $wpdb->query( "ALTER TABLE $wpdb->sitemeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" ); 2542 $wpdb->query( "ALTER TABLE $wpdb->signups DROP INDEX domain_path, ADD INDEX domain_path(domain(140),path(51))" ); 2543 2544 $tables = $wpdb->tables( 'global' ); 2545 2546 // sitecategories may not exist. 2547 if ( ! $wpdb->get_var( "SHOW TABLES LIKE '{$tables['sitecategories']}'" ) ) { 2548 unset( $tables['sitecategories'] ); 2549 } 2550 2551 foreach ( $tables as $table ) { 2552 maybe_convert_table_to_utf8mb4( $table ); 2553 } 2554 } 2555 } 2556 2557 // 4.3.0 2558 if ( $wp_current_db_version < 33055 && 'utf8mb4' === $wpdb->charset ) { 2559 if ( wp_should_upgrade_global_tables() ) { 2560 $upgrade = false; 2561 $indexes = $wpdb->get_results( "SHOW INDEXES FROM $wpdb->signups" ); 2562 foreach ( $indexes as $index ) { 2563 if ( 'domain_path' === $index->Key_name && 'domain' === $index->Column_name && '140' !== $index->Sub_part ) { 2564 $upgrade = true; 2565 break; 2566 } 2567 } 2568 2569 if ( $upgrade ) { 2570 $wpdb->query( "ALTER TABLE $wpdb->signups DROP INDEX domain_path, ADD INDEX domain_path(domain(140),path(51))" ); 2571 } 2572 2573 $tables = $wpdb->tables( 'global' ); 2574 2575 // sitecategories may not exist. 2576 if ( ! $wpdb->get_var( "SHOW TABLES LIKE '{$tables['sitecategories']}'" ) ) { 2577 unset( $tables['sitecategories'] ); 2578 } 2579 2580 foreach ( $tables as $table ) { 2581 maybe_convert_table_to_utf8mb4( $table ); 2582 } 2583 } 2584 } 2585 2586 // 5.1.0 2587 if ( $wp_current_db_version < 44467 ) { 2588 $network_id = get_main_network_id(); 2589 delete_network_option( $network_id, 'site_meta_supported' ); 2590 is_site_meta_supported(); 2591 } 2592 } 2593 2594 // 2595 // General functions we use to actually do stuff. 2596 // 2597 2598 /** 2599 * Creates a table in the database, if it doesn't already exist. 2600 * 2601 * This method checks for an existing database table and creates a new one if it's not 2602 * already present. It doesn't rely on MySQL's "IF NOT EXISTS" statement, but chooses 2603 * to query all tables first and then run the SQL statement creating the table. 2604 * 2605 * @since 1.0.0 2606 * 2607 * @global wpdb $wpdb WordPress database abstraction object. 2608 * 2609 * @param string $table_name Database table name. 2610 * @param string $create_ddl SQL statement to create table. 2611 * @return bool True on success or if the table already exists. False on failure. 2612 */ 2613 function maybe_create_table( $table_name, $create_ddl ) { 2614 global $wpdb; 2615 2616 $query = $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $table_name ) ); 2617 2618 if ( $wpdb->get_var( $query ) === $table_name ) { 2619 return true; 2620 } 2621 2622 // Didn't find it, so try to create it. 2623 $wpdb->query( $create_ddl ); 2624 2625 // We cannot directly tell that whether this succeeded! 2626 if ( $wpdb->get_var( $query ) === $table_name ) { 2627 return true; 2628 } 2629 2630 return false; 2631 } 2632 2633 /** 2634 * Drops a specified index from a table. 2635 * 2636 * @since 1.0.1 2637 * 2638 * @global wpdb $wpdb WordPress database abstraction object. 2639 * 2640 * @param string $table Database table name. 2641 * @param string $index Index name to drop. 2642 * @return true True, when finished. 2643 */ 2644 function drop_index( $table, $index ) { 2645 global $wpdb; 2646 2647 $wpdb->hide_errors(); 2648 2649 $wpdb->query( "ALTER TABLE `$table` DROP INDEX `$index`" ); 2650 2651 // Now we need to take out all the extra ones we may have created. 2652 for ( $i = 0; $i < 25; $i++ ) { 2653 $wpdb->query( "ALTER TABLE `$table` DROP INDEX `{$index}_$i`" ); 2654 } 2655 2656 $wpdb->show_errors(); 2657 2658 return true; 2659 } 2660 2661 /** 2662 * Adds an index to a specified table. 2663 * 2664 * @since 1.0.1 2665 * 2666 * @global wpdb $wpdb WordPress database abstraction object. 2667 * 2668 * @param string $table Database table name. 2669 * @param string $index Database table index column. 2670 * @return true True, when done with execution. 2671 */ 2672 function add_clean_index( $table, $index ) { 2673 global $wpdb; 2674 2675 drop_index( $table, $index ); 2676 $wpdb->query( "ALTER TABLE `$table` ADD INDEX ( `$index` )" ); 2677 2678 return true; 2679 } 2680 2681 /** 2682 * Adds column to a database table, if it doesn't already exist. 2683 * 2684 * @since 1.3.0 2685 * 2686 * @global wpdb $wpdb WordPress database abstraction object. 2687 * 2688 * @param string $table_name Database table name. 2689 * @param string $column_name Table column name. 2690 * @param string $create_ddl SQL statement to add column. 2691 * @return bool True on success or if the column already exists. False on failure. 2692 */ 2693 function maybe_add_column( $table_name, $column_name, $create_ddl ) { 2694 global $wpdb; 2695 2696 foreach ( $wpdb->get_col( "DESC $table_name", 0 ) as $column ) { 2697 if ( $column === $column_name ) { 2698 return true; 2699 } 2700 } 2701 2702 // Didn't find it, so try to create it. 2703 $wpdb->query( $create_ddl ); 2704 2705 // We cannot directly tell that whether this succeeded! 2706 foreach ( $wpdb->get_col( "DESC $table_name", 0 ) as $column ) { 2707 if ( $column === $column_name ) { 2708 return true; 2709 } 2710 } 2711 2712 return false; 2713 } 2714 2715 /** 2716 * If a table only contains utf8 or utf8mb4 columns, convert it to utf8mb4. 2717 * 2718 * @since 4.2.0 2719 * 2720 * @global wpdb $wpdb WordPress database abstraction object. 2721 * 2722 * @param string $table The table to convert. 2723 * @return bool True if the table was converted, false if it wasn't. 2724 */ 2725 function maybe_convert_table_to_utf8mb4( $table ) { 2726 global $wpdb; 2727 2728 $results = $wpdb->get_results( "SHOW FULL COLUMNS FROM `$table`" ); 2729 if ( ! $results ) { 2730 return false; 2731 } 2732 2733 foreach ( $results as $column ) { 2734 if ( $column->Collation ) { 2735 list( $charset ) = explode( '_', $column->Collation ); 2736 $charset = strtolower( $charset ); 2737 if ( 'utf8' !== $charset && 'utf8mb4' !== $charset ) { 2738 // Don't upgrade tables that have non-utf8 columns. 2739 return false; 2740 } 2741 } 2742 } 2743 2744 $table_details = $wpdb->get_row( "SHOW TABLE STATUS LIKE '$table'" ); 2745 if ( ! $table_details ) { 2746 return false; 2747 } 2748 2749 list( $table_charset ) = explode( '_', $table_details->Collation ); 2750 $table_charset = strtolower( $table_charset ); 2751 if ( 'utf8mb4' === $table_charset ) { 2752 return true; 2753 } 2754 2755 return $wpdb->query( "ALTER TABLE $table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci" ); 2756 } 2757 2758 /** 2759 * Retrieve all options as it was for 1.2. 2760 * 2761 * @since 1.2.0 2762 * 2763 * @global wpdb $wpdb WordPress database abstraction object. 2764 * 2765 * @return stdClass List of options. 2766 */ 2767 function get_alloptions_110() { 2768 global $wpdb; 2769 $all_options = new stdClass(); 2770 $options = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options" ); 2771 if ( $options ) { 2772 foreach ( $options as $option ) { 2773 if ( 'siteurl' === $option->option_name || 'home' === $option->option_name || 'category_base' === $option->option_name ) { 2774 $option->option_value = untrailingslashit( $option->option_value ); 2775 } 2776 $all_options->{$option->option_name} = stripslashes( $option->option_value ); 2777 } 2778 } 2779 return $all_options; 2780 } 2781 2782 /** 2783 * Utility version of get_option that is private to installation/upgrade. 2784 * 2785 * @ignore 2786 * @since 1.5.1 2787 * @access private 2788 * 2789 * @global wpdb $wpdb WordPress database abstraction object. 2790 * 2791 * @param string $setting Option name. 2792 * @return mixed 2793 */ 2794 function __get_option( $setting ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionDoubleUnderscore,PHPCompatibility.FunctionNameRestrictions.ReservedFunctionNames.FunctionDoubleUnderscore 2795 global $wpdb; 2796 2797 if ( 'home' === $setting && defined( 'WP_HOME' ) ) { 2798 return untrailingslashit( WP_HOME ); 2799 } 2800 2801 if ( 'siteurl' === $setting && defined( 'WP_SITEURL' ) ) { 2802 return untrailingslashit( WP_SITEURL ); 2803 } 2804 2805 $option = $wpdb->get_var( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s", $setting ) ); 2806 2807 if ( 'home' === $setting && ! $option ) { 2808 return __get_option( 'siteurl' ); 2809 } 2810 2811 if ( in_array( $setting, array( 'siteurl', 'home', 'category_base', 'tag_base' ), true ) ) { 2812 $option = untrailingslashit( $option ); 2813 } 2814 2815 return maybe_unserialize( $option ); 2816 } 2817 2818 /** 2819 * Filters for content to remove unnecessary slashes. 2820 * 2821 * @since 1.5.0 2822 * 2823 * @param string $content The content to modify. 2824 * @return string The de-slashed content. 2825 */ 2826 function deslash( $content ) { 2827 // Note: \\\ inside a regex denotes a single backslash. 2828 2829 /* 2830 * Replace one or more backslashes followed by a single quote with 2831 * a single quote. 2832 */ 2833 $content = preg_replace( "/\\\+'/", "'", $content ); 2834 2835 /* 2836 * Replace one or more backslashes followed by a double quote with 2837 * a double quote. 2838 */ 2839 $content = preg_replace( '/\\\+"/', '"', $content ); 2840 2841 // Replace one or more backslashes with one backslash. 2842 $content = preg_replace( '/\\\+/', '\\', $content ); 2843 2844 return $content; 2845 } 2846 2847 /** 2848 * Modifies the database based on specified SQL statements. 2849 * 2850 * Useful for creating new tables and updating existing tables to a new structure. 2851 * 2852 * @since 1.5.0 2853 * @since 6.1.0 Ignores display width for integer data types on MySQL 8.0.17 or later, 2854 * to match MySQL behavior. Note: This does not affect MariaDB. 2855 * 2856 * @global wpdb $wpdb WordPress database abstraction object. 2857 * 2858 * @param string[]|string $queries Optional. The query to run. Can be multiple queries 2859 * in an array, or a string of queries separated by 2860 * semicolons. Default empty string. 2861 * @param bool $execute Optional. Whether or not to execute the query right away. 2862 * Default true. 2863 * @return string[] Strings containing the results of the various update queries. 2864 */ 2865 function dbDelta( $queries = '', $execute = true ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid 2866 global $wpdb; 2867 2868 if ( in_array( $queries, array( '', 'all', 'blog', 'global', 'ms_global' ), true ) ) { 2869 $queries = wp_get_db_schema( $queries ); 2870 } 2871 2872 // Separate individual queries into an array. 2873 if ( ! is_array( $queries ) ) { 2874 $queries = explode( ';', $queries ); 2875 $queries = array_filter( $queries ); 2876 } 2877 2878 /** 2879 * Filters the dbDelta SQL queries. 2880 * 2881 * @since 3.3.0 2882 * 2883 * @param string[] $queries An array of dbDelta SQL queries. 2884 */ 2885 $queries = apply_filters( 'dbdelta_queries', $queries ); 2886 2887 $cqueries = array(); // Creation queries. 2888 $iqueries = array(); // Insertion queries. 2889 $for_update = array(); 2890 2891 // Create a tablename index for an array ($cqueries) of recognized query types. 2892 foreach ( $queries as $qry ) { 2893 if ( preg_match( '|CREATE TABLE ([^ ]*)|', $qry, $matches ) ) { 2894 $cqueries[ trim( $matches[1], '`' ) ] = $qry; 2895 $for_update[ $matches[1] ] = 'Created table ' . $matches[1]; 2896 continue; 2897 } 2898 2899 if ( preg_match( '|CREATE DATABASE ([^ ]*)|', $qry, $matches ) ) { 2900 array_unshift( $cqueries, $qry ); 2901 continue; 2902 } 2903 2904 if ( preg_match( '|INSERT INTO ([^ ]*)|', $qry, $matches ) ) { 2905 $iqueries[] = $qry; 2906 continue; 2907 } 2908 2909 if ( preg_match( '|UPDATE ([^ ]*)|', $qry, $matches ) ) { 2910 $iqueries[] = $qry; 2911 continue; 2912 } 2913 } 2914 2915 /** 2916 * Filters the dbDelta SQL queries for creating tables and/or databases. 2917 * 2918 * Queries filterable via this hook contain "CREATE TABLE" or "CREATE DATABASE". 2919 * 2920 * @since 3.3.0 2921 * 2922 * @param string[] $cqueries An array of dbDelta create SQL queries. 2923 */ 2924 $cqueries = apply_filters( 'dbdelta_create_queries', $cqueries ); 2925 2926 /** 2927 * Filters the dbDelta SQL queries for inserting or updating. 2928 * 2929 * Queries filterable via this hook contain "INSERT INTO" or "UPDATE". 2930 * 2931 * @since 3.3.0 2932 * 2933 * @param string[] $iqueries An array of dbDelta insert or update SQL queries. 2934 */ 2935 $iqueries = apply_filters( 'dbdelta_insert_queries', $iqueries ); 2936 2937 $text_fields = array( 'tinytext', 'text', 'mediumtext', 'longtext' ); 2938 $blob_fields = array( 'tinyblob', 'blob', 'mediumblob', 'longblob' ); 2939 $int_fields = array( 'tinyint', 'smallint', 'mediumint', 'int', 'integer', 'bigint' ); 2940 2941 $global_tables = $wpdb->tables( 'global' ); 2942 $db_version = $wpdb->db_version(); 2943 $db_server_info = $wpdb->db_server_info(); 2944 2945 foreach ( $cqueries as $table => $qry ) { 2946 // Upgrade global tables only for the main site. Don't upgrade at all if conditions are not optimal. 2947 if ( in_array( $table, $global_tables, true ) && ! wp_should_upgrade_global_tables() ) { 2948 unset( $cqueries[ $table ], $for_update[ $table ] ); 2949 continue; 2950 } 2951 2952 // Fetch the table column structure from the database. 2953 $suppress = $wpdb->suppress_errors(); 2954 $tablefields = $wpdb->get_results( "DESCRIBE {$table};" ); 2955 $wpdb->suppress_errors( $suppress ); 2956 2957 if ( ! $tablefields ) { 2958 continue; 2959 } 2960 2961 // Clear the field and index arrays. 2962 $cfields = array(); 2963 $indices = array(); 2964 $indices_without_subparts = array(); 2965 2966 // Get all of the field names in the query from between the parentheses. 2967 preg_match( '|\((.*)\)|ms', $qry, $match2 ); 2968 $qryline = trim( $match2[1] ); 2969 2970 // Separate field lines into an array. 2971 $flds = explode( "\n", $qryline ); 2972 2973 // For every field line specified in the query. 2974 foreach ( $flds as $fld ) { 2975 $fld = trim( $fld, " \t\n\r\0\x0B," ); // Default trim characters, plus ','. 2976 2977 // Extract the field name. 2978 preg_match( '|^([^ ]*)|', $fld, $fvals ); 2979 $fieldname = trim( $fvals[1], '`' ); 2980 $fieldname_lowercased = strtolower( $fieldname ); 2981 2982 // Verify the found field name. 2983 $validfield = true; 2984 switch ( $fieldname_lowercased ) { 2985 case '': 2986 case 'primary': 2987 case 'index': 2988 case 'fulltext': 2989 case 'unique': 2990 case 'key': 2991 case 'spatial': 2992 $validfield = false; 2993 2994 /* 2995 * Normalize the index definition. 2996 * 2997 * This is done so the definition can be compared against the result of a 2998 * `SHOW INDEX FROM $table_name` query which returns the current table 2999 * index information. 3000 */ 3001 3002 // Extract type, name and columns from the definition. 3003 preg_match( 3004 '/^ 3005 (?P<index_type> # 1) Type of the index. 3006 PRIMARY\s+KEY|(?:UNIQUE|FULLTEXT|SPATIAL)\s+(?:KEY|INDEX)|KEY|INDEX 3007 ) 3008 \s+ # Followed by at least one white space character. 3009 (?: # Name of the index. Optional if type is PRIMARY KEY. 3010 `? # Name can be escaped with a backtick. 3011 (?P<index_name> # 2) Name of the index. 3012 (?:[0-9a-zA-Z$_-]|[\xC2-\xDF][\x80-\xBF])+ 3013 ) 3014 `? # Name can be escaped with a backtick. 3015 \s+ # Followed by at least one white space character. 3016 )* 3017 \( # Opening bracket for the columns. 3018 (?P<index_columns> 3019 .+? # 3) Column names, index prefixes, and orders. 3020 ) 3021 \) # Closing bracket for the columns. 3022 $/imx', 3023 $fld, 3024 $index_matches 3025 ); 3026 3027 // Uppercase the index type and normalize space characters. 3028 $index_type = strtoupper( preg_replace( '/\s+/', ' ', trim( $index_matches['index_type'] ) ) ); 3029 3030 // 'INDEX' is a synonym for 'KEY', standardize on 'KEY'. 3031 $index_type = str_replace( 'INDEX', 'KEY', $index_type ); 3032 3033 // Escape the index name with backticks. An index for a primary key has no name. 3034 $index_name = ( 'PRIMARY KEY' === $index_type ) ? '' : '`' . strtolower( $index_matches['index_name'] ) . '`'; 3035 3036 // Parse the columns. Multiple columns are separated by a comma. 3037 $index_columns = array_map( 'trim', explode( ',', $index_matches['index_columns'] ) ); 3038 $index_columns_without_subparts = $index_columns; 3039 3040 // Normalize columns. 3041 foreach ( $index_columns as $id => &$index_column ) { 3042 // Extract column name and number of indexed characters (sub_part). 3043 preg_match( 3044 '/ 3045 `? # Name can be escaped with a backtick. 3046 (?P<column_name> # 1) Name of the column. 3047 (?:[0-9a-zA-Z$_-]|[\xC2-\xDF][\x80-\xBF])+ 3048 ) 3049 `? # Name can be escaped with a backtick. 3050 (?: # Optional sub part. 3051 \s* # Optional white space character between name and opening bracket. 3052 \( # Opening bracket for the sub part. 3053 \s* # Optional white space character after opening bracket. 3054 (?P<sub_part> 3055 \d+ # 2) Number of indexed characters. 3056 ) 3057 \s* # Optional white space character before closing bracket. 3058 \) # Closing bracket for the sub part. 3059 )? 3060 /x', 3061 $index_column, 3062 $index_column_matches 3063 ); 3064 3065 // Escape the column name with backticks. 3066 $index_column = '`' . $index_column_matches['column_name'] . '`'; 3067 3068 // We don't need to add the subpart to $index_columns_without_subparts 3069 $index_columns_without_subparts[ $id ] = $index_column; 3070 3071 // Append the optional sup part with the number of indexed characters. 3072 if ( isset( $index_column_matches['sub_part'] ) ) { 3073 $index_column .= '(' . $index_column_matches['sub_part'] . ')'; 3074 } 3075 } 3076 3077 // Build the normalized index definition and add it to the list of indices. 3078 $indices[] = "{$index_type} {$index_name} (" . implode( ',', $index_columns ) . ')'; 3079 $indices_without_subparts[] = "{$index_type} {$index_name} (" . implode( ',', $index_columns_without_subparts ) . ')'; 3080 3081 // Destroy no longer needed variables. 3082 unset( $index_column, $index_column_matches, $index_matches, $index_type, $index_name, $index_columns, $index_columns_without_subparts ); 3083 3084 break; 3085 } 3086 3087 // If it's a valid field, add it to the field array. 3088 if ( $validfield ) { 3089 $cfields[ $fieldname_lowercased ] = $fld; 3090 } 3091 } 3092 3093 // For every field in the table. 3094 foreach ( $tablefields as $tablefield ) { 3095 $tablefield_field_lowercased = strtolower( $tablefield->Field ); 3096 $tablefield_type_lowercased = strtolower( $tablefield->Type ); 3097 3098 $tablefield_type_without_parentheses = preg_replace( 3099 '/' 3100 . '(.+)' // Field type, e.g. `int`. 3101 . '\(\d*\)' // Display width. 3102 . '(.*)' // Optional attributes, e.g. `unsigned`. 3103 . '/', 3104 '$1$2', 3105 $tablefield_type_lowercased 3106 ); 3107 3108 // Get the type without attributes, e.g. `int`. 3109 $tablefield_type_base = strtok( $tablefield_type_without_parentheses, ' ' ); 3110 3111 // If the table field exists in the field array... 3112 if ( array_key_exists( $tablefield_field_lowercased, $cfields ) ) { 3113 3114 // Get the field type from the query. 3115 preg_match( '|`?' . $tablefield->Field . '`? ([^ ]*( unsigned)?)|i', $cfields[ $tablefield_field_lowercased ], $matches ); 3116 $fieldtype = $matches[1]; 3117 $fieldtype_lowercased = strtolower( $fieldtype ); 3118 3119 $fieldtype_without_parentheses = preg_replace( 3120 '/' 3121 . '(.+)' // Field type, e.g. `int`. 3122 . '\(\d*\)' // Display width. 3123 . '(.*)' // Optional attributes, e.g. `unsigned`. 3124 . '/', 3125 '$1$2', 3126 $fieldtype_lowercased 3127 ); 3128 3129 // Get the type without attributes, e.g. `int`. 3130 $fieldtype_base = strtok( $fieldtype_without_parentheses, ' ' ); 3131 3132 // Is actual field type different from the field type in query? 3133 if ( $tablefield->Type !== $fieldtype ) { 3134 $do_change = true; 3135 if ( in_array( $fieldtype_lowercased, $text_fields, true ) && in_array( $tablefield_type_lowercased, $text_fields, true ) ) { 3136 if ( array_search( $fieldtype_lowercased, $text_fields, true ) < array_search( $tablefield_type_lowercased, $text_fields, true ) ) { 3137 $do_change = false; 3138 } 3139 } 3140 3141 if ( in_array( $fieldtype_lowercased, $blob_fields, true ) && in_array( $tablefield_type_lowercased, $blob_fields, true ) ) { 3142 if ( array_search( $fieldtype_lowercased, $blob_fields, true ) < array_search( $tablefield_type_lowercased, $blob_fields, true ) ) { 3143 $do_change = false; 3144 } 3145 } 3146 3147 if ( in_array( $fieldtype_base, $int_fields, true ) && in_array( $tablefield_type_base, $int_fields, true ) 3148 && $fieldtype_without_parentheses === $tablefield_type_without_parentheses 3149 ) { 3150 /* 3151 * MySQL 8.0.17 or later does not support display width for integer data types, 3152 * so if display width is the only difference, it can be safely ignored. 3153 * Note: This is specific to MySQL and does not affect MariaDB. 3154 */ 3155 if ( version_compare( $db_version, '8.0.17', '>=' ) 3156 && ! str_contains( $db_server_info, 'MariaDB' ) 3157 ) { 3158 $do_change = false; 3159 } 3160 } 3161 3162 if ( $do_change ) { 3163 // Add a query to change the column type. 3164 $cqueries[] = "ALTER TABLE {$table} CHANGE COLUMN `{$tablefield->Field}` " . $cfields[ $tablefield_field_lowercased ]; 3165 3166 $for_update[ $table . '.' . $tablefield->Field ] = "Changed type of {$table}.{$tablefield->Field} from {$tablefield->Type} to {$fieldtype}"; 3167 } 3168 } 3169 3170 // Get the default value from the array. 3171 if ( preg_match( "| DEFAULT '(.*?)'|i", $cfields[ $tablefield_field_lowercased ], $matches ) ) { 3172 $default_value = $matches[1]; 3173 if ( $tablefield->Default !== $default_value ) { 3174 // Add a query to change the column's default value 3175 $cqueries[] = "ALTER TABLE {$table} ALTER COLUMN `{$tablefield->Field}` SET DEFAULT '{$default_value}'"; 3176 3177 $for_update[ $table . '.' . $tablefield->Field ] = "Changed default value of {$table}.{$tablefield->Field} from {$tablefield->Default} to {$default_value}"; 3178 } 3179 } 3180 3181 // Remove the field from the array (so it's not added). 3182 unset( $cfields[ $tablefield_field_lowercased ] ); 3183 } else { 3184 // This field exists in the table, but not in the creation queries? 3185 } 3186 } 3187 3188 // For every remaining field specified for the table. 3189 foreach ( $cfields as $fieldname => $fielddef ) { 3190 // Push a query line into $cqueries that adds the field to that table. 3191 $cqueries[] = "ALTER TABLE {$table} ADD COLUMN $fielddef"; 3192 3193 $for_update[ $table . '.' . $fieldname ] = 'Added column ' . $table . '.' . $fieldname; 3194 } 3195 3196 // Index stuff goes here. Fetch the table index structure from the database. 3197 $tableindices = $wpdb->get_results( "SHOW INDEX FROM {$table};" ); 3198 3199 if ( $tableindices ) { 3200 // Clear the index array. 3201 $index_ary = array(); 3202 3203 // For every index in the table. 3204 foreach ( $tableindices as $tableindex ) { 3205 $keyname = strtolower( $tableindex->Key_name ); 3206 3207 // Add the index to the index data array. 3208 $index_ary[ $keyname ]['columns'][] = array( 3209 'fieldname' => $tableindex->Column_name, 3210 'subpart' => $tableindex->Sub_part, 3211 ); 3212 $index_ary[ $keyname ]['unique'] = ( '0' === $tableindex->Non_unique ) ? true : false; 3213 $index_ary[ $keyname ]['index_type'] = $tableindex->Index_type; 3214 } 3215 3216 // For each actual index in the index array. 3217 foreach ( $index_ary as $index_name => $index_data ) { 3218 3219 // Build a create string to compare to the query. 3220 $index_string = ''; 3221 if ( 'primary' === $index_name ) { 3222 $index_string .= 'PRIMARY '; 3223 } elseif ( $index_data['unique'] ) { 3224 $index_string .= 'UNIQUE '; 3225 } 3226 3227 if ( 'FULLTEXT' === strtoupper( $index_data['index_type'] ) ) { 3228 $index_string .= 'FULLTEXT '; 3229 } 3230 3231 if ( 'SPATIAL' === strtoupper( $index_data['index_type'] ) ) { 3232 $index_string .= 'SPATIAL '; 3233 } 3234 3235 $index_string .= 'KEY '; 3236 if ( 'primary' !== $index_name ) { 3237 $index_string .= '`' . $index_name . '`'; 3238 } 3239 3240 $index_columns = ''; 3241 3242 // For each column in the index. 3243 foreach ( $index_data['columns'] as $column_data ) { 3244 if ( '' !== $index_columns ) { 3245 $index_columns .= ','; 3246 } 3247 3248 // Add the field to the column list string. 3249 $index_columns .= '`' . $column_data['fieldname'] . '`'; 3250 } 3251 3252 // Add the column list to the index create string. 3253 $index_string .= " ($index_columns)"; 3254 3255 // Check if the index definition exists, ignoring subparts. 3256 $aindex = array_search( $index_string, $indices_without_subparts, true ); 3257 if ( false !== $aindex ) { 3258 // If the index already exists (even with different subparts), we don't need to create it. 3259 unset( $indices_without_subparts[ $aindex ] ); 3260 unset( $indices[ $aindex ] ); 3261 } 3262 } 3263 } 3264 3265 // For every remaining index specified for the table. 3266 foreach ( (array) $indices as $index ) { 3267 // Push a query line into $cqueries that adds the index to that table. 3268 $cqueries[] = "ALTER TABLE {$table} ADD $index"; 3269 3270 $for_update[] = 'Added index ' . $table . ' ' . $index; 3271 } 3272 3273 // Remove the original table creation query from processing. 3274 unset( $cqueries[ $table ], $for_update[ $table ] ); 3275 } 3276 3277 $allqueries = array_merge( $cqueries, $iqueries ); 3278 if ( $execute ) { 3279 foreach ( $allqueries as $query ) { 3280 $wpdb->query( $query ); 3281 } 3282 } 3283 3284 return $for_update; 3285 } 3286 3287 /** 3288 * Updates the database tables to a new schema. 3289 * 3290 * By default, updates all the tables to use the latest defined schema, but can also 3291 * be used to update a specific set of tables in wp_get_db_schema(). 3292 * 3293 * @since 1.5.0 3294 * 3295 * @uses dbDelta 3296 * 3297 * @param string $tables Optional. Which set of tables to update. Default is 'all'. 3298 */ 3299 function make_db_current( $tables = 'all' ) { 3300 $alterations = dbDelta( $tables ); 3301 echo "<ol>\n"; 3302 foreach ( $alterations as $alteration ) { 3303 echo "<li>$alteration</li>\n"; 3304 } 3305 echo "</ol>\n"; 3306 } 3307 3308 /** 3309 * Updates the database tables to a new schema, but without displaying results. 3310 * 3311 * By default, updates all the tables to use the latest defined schema, but can 3312 * also be used to update a specific set of tables in wp_get_db_schema(). 3313 * 3314 * @since 1.5.0 3315 * 3316 * @see make_db_current() 3317 * 3318 * @param string $tables Optional. Which set of tables to update. Default is 'all'. 3319 */ 3320 function make_db_current_silent( $tables = 'all' ) { 3321 dbDelta( $tables ); 3322 } 3323 3324 /** 3325 * Creates a site theme from an existing theme. 3326 * 3327 * {@internal Missing Long Description}} 3328 * 3329 * @since 1.5.0 3330 * 3331 * @param string $theme_name The name of the theme. 3332 * @param string $template The directory name of the theme. 3333 * @return bool 3334 */ 3335 function make_site_theme_from_oldschool( $theme_name, $template ) { 3336 $home_path = get_home_path(); 3337 $site_dir = WP_CONTENT_DIR . "/themes/$template"; 3338 $default_dir = WP_CONTENT_DIR . '/themes/' . WP_DEFAULT_THEME; 3339 3340 if ( ! file_exists( "$home_path/index.php" ) ) { 3341 return false; 3342 } 3343 3344 /* 3345 * Copy files from the old locations to the site theme. 3346 * TODO: This does not copy arbitrary include dependencies. Only the standard WP files are copied. 3347 */ 3348 $files = array( 3349 'index.php' => 'index.php', 3350 'wp-layout.css' => 'style.css', 3351 'wp-comments.php' => 'comments.php', 3352 'wp-comments-popup.php' => 'comments-popup.php', 3353 ); 3354 3355 foreach ( $files as $oldfile => $newfile ) { 3356 if ( 'index.php' === $oldfile ) { 3357 $oldpath = $home_path; 3358 } else { 3359 $oldpath = ABSPATH; 3360 } 3361 3362 // Check to make sure it's not a new index. 3363 if ( 'index.php' === $oldfile ) { 3364 $index = implode( '', file( "$oldpath/$oldfile" ) ); 3365 if ( str_contains( $index, 'WP_USE_THEMES' ) ) { 3366 if ( ! copy( "$default_dir/$oldfile", "$site_dir/$newfile" ) ) { 3367 return false; 3368 } 3369 3370 // Don't copy anything. 3371 continue; 3372 } 3373 } 3374 3375 if ( ! copy( "$oldpath/$oldfile", "$site_dir/$newfile" ) ) { 3376 return false; 3377 } 3378 3379 chmod( "$site_dir/$newfile", 0777 ); 3380 3381 // Update the blog header include in each file. 3382 $lines = explode( "\n", implode( '', file( "$site_dir/$newfile" ) ) ); 3383 if ( $lines ) { 3384 $f = fopen( "$site_dir/$newfile", 'w' ); 3385 3386 foreach ( $lines as $line ) { 3387 if ( preg_match( '/require.*wp-blog-header/', $line ) ) { 3388 $line = '//' . $line; 3389 } 3390 3391 // Update stylesheet references. 3392 $line = str_replace( 3393 "<?php echo __get_option('siteurl'); ?>/wp-layout.css", 3394 "<?php bloginfo('stylesheet_url'); ?>", 3395 $line 3396 ); 3397 3398 // Update comments template inclusion. 3399 $line = str_replace( 3400 "<?php include(ABSPATH . 'wp-comments.php'); ?>", 3401 '<?php comments_template(); ?>', 3402 $line 3403 ); 3404 3405 fwrite( $f, "{$line}\n" ); 3406 } 3407 fclose( $f ); 3408 } 3409 } 3410 3411 // Add a theme header. 3412 $header = "/*\n" . 3413 "Theme Name: $theme_name\n" . 3414 'Theme URI: ' . __get_option( 'siteurl' ) . "\n" . 3415 "Description: A theme automatically created by the update.\n" . 3416 "Version: 1.0\n" . 3417 "Author: Moi\n" . 3418 "*/\n"; 3419 3420 $stylelines = file_get_contents( "$site_dir/style.css" ); 3421 if ( $stylelines ) { 3422 $f = fopen( "$site_dir/style.css", 'w' ); 3423 3424 fwrite( $f, $header ); 3425 fwrite( $f, $stylelines ); 3426 fclose( $f ); 3427 } 3428 3429 return true; 3430 } 3431 3432 /** 3433 * Creates a site theme from the default theme. 3434 * 3435 * {@internal Missing Long Description}} 3436 * 3437 * @since 1.5.0 3438 * 3439 * @param string $theme_name The name of the theme. 3440 * @param string $template The directory name of the theme. 3441 * @return void|false 3442 */ 3443 function make_site_theme_from_default( $theme_name, $template ) { 3444 $site_dir = WP_CONTENT_DIR . "/themes/$template"; 3445 $default_dir = WP_CONTENT_DIR . '/themes/' . WP_DEFAULT_THEME; 3446 3447 /* 3448 * Copy files from the default theme to the site theme. 3449 * $files = array( 'index.php', 'comments.php', 'comments-popup.php', 'footer.php', 'header.php', 'sidebar.php', 'style.css' ); 3450 */ 3451 3452 $theme_dir = @opendir( $default_dir ); 3453 if ( $theme_dir ) { 3454 while ( ( $theme_file = readdir( $theme_dir ) ) !== false ) { 3455 if ( is_dir( "$default_dir/$theme_file" ) ) { 3456 continue; 3457 } 3458 3459 if ( ! copy( "$default_dir/$theme_file", "$site_dir/$theme_file" ) ) { 3460 return; 3461 } 3462 3463 chmod( "$site_dir/$theme_file", 0777 ); 3464 } 3465 3466 closedir( $theme_dir ); 3467 } 3468 3469 // Rewrite the theme header. 3470 $stylelines = explode( "\n", implode( '', file( "$site_dir/style.css" ) ) ); 3471 if ( $stylelines ) { 3472 $f = fopen( "$site_dir/style.css", 'w' ); 3473 3474 $headers = array( 3475 'Theme Name:' => $theme_name, 3476 'Theme URI:' => __get_option( 'url' ), 3477 'Description:' => 'Your theme.', 3478 'Version:' => '1', 3479 'Author:' => 'You', 3480 ); 3481 3482 foreach ( $stylelines as $line ) { 3483 foreach ( $headers as $header => $value ) { 3484 if ( str_contains( $line, $header ) ) { 3485 $line = $header . ' ' . $value; 3486 break; 3487 } 3488 } 3489 3490 fwrite( $f, $line . "\n" ); 3491 } 3492 3493 fclose( $f ); 3494 } 3495 3496 // Copy the images. 3497 umask( 0 ); 3498 if ( ! mkdir( "$site_dir/images", 0777 ) ) { 3499 return false; 3500 } 3501 3502 $images_dir = @opendir( "$default_dir/images" ); 3503 if ( $images_dir ) { 3504 while ( ( $image = readdir( $images_dir ) ) !== false ) { 3505 if ( is_dir( "$default_dir/images/$image" ) ) { 3506 continue; 3507 } 3508 3509 if ( ! copy( "$default_dir/images/$image", "$site_dir/images/$image" ) ) { 3510 return; 3511 } 3512 3513 chmod( "$site_dir/images/$image", 0777 ); 3514 } 3515 3516 closedir( $images_dir ); 3517 } 3518 } 3519 3520 /** 3521 * Creates a site theme. 3522 * 3523 * {@internal Missing Long Description}} 3524 * 3525 * @since 1.5.0 3526 * 3527 * @return string|false 3528 */ 3529 function make_site_theme() { 3530 // Name the theme after the blog. 3531 $theme_name = __get_option( 'blogname' ); 3532 $template = sanitize_title( $theme_name ); 3533 $site_dir = WP_CONTENT_DIR . "/themes/$template"; 3534 3535 // If the theme already exists, nothing to do. 3536 if ( is_dir( $site_dir ) ) { 3537 return false; 3538 } 3539 3540 // We must be able to write to the themes dir. 3541 if ( ! is_writable( WP_CONTENT_DIR . '/themes' ) ) { 3542 return false; 3543 } 3544 3545 umask( 0 ); 3546 if ( ! mkdir( $site_dir, 0777 ) ) { 3547 return false; 3548 } 3549 3550 if ( file_exists( ABSPATH . 'wp-layout.css' ) ) { 3551 if ( ! make_site_theme_from_oldschool( $theme_name, $template ) ) { 3552 // TODO: rm -rf the site theme directory. 3553 return false; 3554 } 3555 } else { 3556 if ( ! make_site_theme_from_default( $theme_name, $template ) ) { 3557 // TODO: rm -rf the site theme directory. 3558 return false; 3559 } 3560 } 3561 3562 // Make the new site theme active. 3563 $current_template = __get_option( 'template' ); 3564 if ( WP_DEFAULT_THEME === $current_template ) { 3565 update_option( 'template', $template ); 3566 update_option( 'stylesheet', $template ); 3567 } 3568 return $template; 3569 } 3570 3571 /** 3572 * Translate user level to user role name. 3573 * 3574 * @since 2.0.0 3575 * 3576 * @param int $level User level. 3577 * @return string User role name. 3578 */ 3579 function translate_level_to_role( $level ) { 3580 switch ( $level ) { 3581 case 10: 3582 case 9: 3583 case 8: 3584 return 'administrator'; 3585 case 7: 3586 case 6: 3587 case 5: 3588 return 'editor'; 3589 case 4: 3590 case 3: 3591 case 2: 3592 return 'author'; 3593 case 1: 3594 return 'contributor'; 3595 case 0: 3596 default: 3597 return 'subscriber'; 3598 } 3599 } 3600 3601 /** 3602 * Checks the version of the installed MySQL binary. 3603 * 3604 * @since 2.1.0 3605 * 3606 * @global wpdb $wpdb WordPress database abstraction object. 3607 */ 3608 function wp_check_mysql_version() { 3609 global $wpdb; 3610 $result = $wpdb->check_database_version(); 3611 if ( is_wp_error( $result ) ) { 3612 wp_die( $result ); 3613 } 3614 } 3615 3616 /** 3617 * Disables the Automattic widgets plugin, which was merged into core. 3618 * 3619 * @since 2.2.0 3620 */ 3621 function maybe_disable_automattic_widgets() { 3622 $plugins = __get_option( 'active_plugins' ); 3623 3624 foreach ( (array) $plugins as $plugin ) { 3625 if ( 'widgets.php' === basename( $plugin ) ) { 3626 array_splice( $plugins, array_search( $plugin, $plugins, true ), 1 ); 3627 update_option( 'active_plugins', $plugins ); 3628 break; 3629 } 3630 } 3631 } 3632 3633 /** 3634 * Disables the Link Manager on upgrade if, at the time of upgrade, no links exist in the DB. 3635 * 3636 * @since 3.5.0 3637 * 3638 * @global int $wp_current_db_version The old (current) database version. 3639 * @global wpdb $wpdb WordPress database abstraction object. 3640 */ 3641 function maybe_disable_link_manager() { 3642 global $wp_current_db_version, $wpdb; 3643 3644 if ( $wp_current_db_version >= 22006 && get_option( 'link_manager_enabled' ) && ! $wpdb->get_var( "SELECT link_id FROM $wpdb->links LIMIT 1" ) ) { 3645 update_option( 'link_manager_enabled', 0 ); 3646 } 3647 } 3648 3649 /** 3650 * Runs before the schema is upgraded. 3651 * 3652 * @since 2.9.0 3653 * 3654 * @global int $wp_current_db_version The old (current) database version. 3655 * @global wpdb $wpdb WordPress database abstraction object. 3656 */ 3657 function pre_schema_upgrade() { 3658 global $wp_current_db_version, $wpdb; 3659 3660 // Upgrade versions prior to 2.9. 3661 if ( $wp_current_db_version < 11557 ) { 3662 // Delete duplicate options. Keep the option with the highest option_id. 3663 $wpdb->query( "DELETE o1 FROM $wpdb->options AS o1 JOIN $wpdb->options AS o2 USING (`option_name`) WHERE o2.option_id > o1.option_id" ); 3664 3665 // Drop the old primary key and add the new. 3666 $wpdb->query( "ALTER TABLE $wpdb->options DROP PRIMARY KEY, ADD PRIMARY KEY(option_id)" ); 3667 3668 // Drop the old option_name index. dbDelta() doesn't do the drop. 3669 $wpdb->query( "ALTER TABLE $wpdb->options DROP INDEX option_name" ); 3670 } 3671 3672 // Multisite schema upgrades. 3673 if ( $wp_current_db_version < 25448 && is_multisite() && wp_should_upgrade_global_tables() ) { 3674 3675 // Upgrade versions prior to 3.7. 3676 if ( $wp_current_db_version < 25179 ) { 3677 // New primary key for signups. 3678 $wpdb->query( "ALTER TABLE $wpdb->signups ADD signup_id BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST" ); 3679 $wpdb->query( "ALTER TABLE $wpdb->signups DROP INDEX domain" ); 3680 } 3681 3682 if ( $wp_current_db_version < 25448 ) { 3683 // Convert archived from enum to tinyint. 3684 $wpdb->query( "ALTER TABLE $wpdb->blogs CHANGE COLUMN archived archived varchar(1) NOT NULL default '0'" ); 3685 $wpdb->query( "ALTER TABLE $wpdb->blogs CHANGE COLUMN archived archived tinyint(2) NOT NULL default 0" ); 3686 } 3687 } 3688 3689 // Upgrade versions prior to 4.2. 3690 if ( $wp_current_db_version < 31351 ) { 3691 if ( ! is_multisite() && wp_should_upgrade_global_tables() ) { 3692 $wpdb->query( "ALTER TABLE $wpdb->usermeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" ); 3693 } 3694 $wpdb->query( "ALTER TABLE $wpdb->terms DROP INDEX slug, ADD INDEX slug(slug(191))" ); 3695 $wpdb->query( "ALTER TABLE $wpdb->terms DROP INDEX name, ADD INDEX name(name(191))" ); 3696 $wpdb->query( "ALTER TABLE $wpdb->commentmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" ); 3697 $wpdb->query( "ALTER TABLE $wpdb->postmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" ); 3698 $wpdb->query( "ALTER TABLE $wpdb->posts DROP INDEX post_name, ADD INDEX post_name(post_name(191))" ); 3699 } 3700 3701 // Upgrade versions prior to 4.4. 3702 if ( $wp_current_db_version < 34978 ) { 3703 // If compatible termmeta table is found, use it, but enforce a proper index and update collation. 3704 if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->termmeta}'" ) && $wpdb->get_results( "SHOW INDEX FROM {$wpdb->termmeta} WHERE Column_name = 'meta_key'" ) ) { 3705 $wpdb->query( "ALTER TABLE $wpdb->termmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" ); 3706 maybe_convert_table_to_utf8mb4( $wpdb->termmeta ); 3707 } 3708 } 3709 } 3710 3711 /** 3712 * Determine if global tables should be upgraded. 3713 * 3714 * This function performs a series of checks to ensure the environment allows 3715 * for the safe upgrading of global WordPress database tables. It is necessary 3716 * because global tables will commonly grow to millions of rows on large 3717 * installations, and the ability to control their upgrade routines can be 3718 * critical to the operation of large networks. 3719 * 3720 * In a future iteration, this function may use `wp_is_large_network()` to more- 3721 * intelligently prevent global table upgrades. Until then, we make sure 3722 * WordPress is on the main site of the main network, to avoid running queries 3723 * more than once in multi-site or multi-network environments. 3724 * 3725 * @since 4.3.0 3726 * 3727 * @return bool Whether to run the upgrade routines on global tables. 3728 */ 3729 function wp_should_upgrade_global_tables() { 3730 3731 // Return false early if explicitly not upgrading. 3732 if ( defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) { 3733 return false; 3734 } 3735 3736 // Assume global tables should be upgraded. 3737 $should_upgrade = true; 3738 3739 // Set to false if not on main network (does not matter if not multi-network). 3740 if ( ! is_main_network() ) { 3741 $should_upgrade = false; 3742 } 3743 3744 // Set to false if not on main site of current network (does not matter if not multi-site). 3745 if ( ! is_main_site() ) { 3746 $should_upgrade = false; 3747 } 3748 3749 /** 3750 * Filters if upgrade routines should be run on global tables. 3751 * 3752 * @since 4.3.0 3753 * 3754 * @param bool $should_upgrade Whether to run the upgrade routines on global tables. 3755 */ 3756 return apply_filters( 'wp_should_upgrade_global_tables', $should_upgrade ); 3757 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Thu Apr 10 08:20:01 2025 | Cross-referenced by PHPXref |