[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-admin/includes/ -> upgrade.php (source)

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


Generated: Fri Apr 23 01:00:05 2021 Cross-referenced by PHPXref 0.7.1