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