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


Generated: Mon Oct 26 01:00:02 2020 Cross-referenced by PHPXref 0.7.1