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