[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

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


Generated : Mon Nov 2 08:20:36 2026 Cross-referenced by PHPXref