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