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