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


Generated: Tue Oct 19 01:00:04 2021 Cross-referenced by PHPXref 0.7.1