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