// Clear the index array.
// For every index in the table.
foreach ( $tableindices as $tableindex ) {
$keyname = strtolower( $tableindex->Key_name );
// Add the index to the index data array.
$index_ary[ $keyname ]['columns'][] = array(
'fieldname' => $tableindex->Column_name,
'subpart' => $tableindex->Sub_part,
$index_ary[ $keyname ]['unique'] = ( 0 == $tableindex->Non_unique ) ? true : false;
$index_ary[ $keyname ]['index_type'] = $tableindex->Index_type;
// For each actual index in the index array.
foreach ( $index_ary as $index_name => $index_data ) {
// Build a create string to compare to the query.
if ( 'primary' === $index_name ) {
$index_string .= 'PRIMARY ';
} elseif ( $index_data['unique'] ) {
$index_string .= 'UNIQUE ';
if ( 'FULLTEXT' === strtoupper( $index_data['index_type'] ) ) {
$index_string .= 'FULLTEXT ';
if ( 'SPATIAL' === strtoupper( $index_data['index_type'] ) ) {
$index_string .= 'SPATIAL ';
if ( 'primary' !== $index_name ) {
$index_string .= '`' . $index_name . '`';
// For each column in the index.
foreach ( $index_data['columns'] as $column_data ) {
if ( '' !== $index_columns ) {
// Add the field to the column list string.
$index_columns .= '`' . $column_data['fieldname'] . '`';
// Add the column list to the index create string.
$index_string .= " ($index_columns)";
// Check if the index definition exists, ignoring subparts.
$aindex = array_search( $index_string, $indices_without_subparts, true );
if ( false !== $aindex ) {
// If the index already exists (even with different subparts), we don't need to create it.
unset( $indices_without_subparts[ $aindex ] );
unset( $indices[ $aindex ] );
// For every remaining index specified for the table.
foreach ( (array) $indices as $index ) {
// Push a query line into $cqueries that adds the index to that table.
$cqueries[] = "ALTER TABLE {$table} ADD $index";
$for_update[] = 'Added index ' . $table . ' ' . $index;
// Remove the original table creation query from processing.
unset( $cqueries[ $table ], $for_update[ $table ] );
$allqueries = array_merge( $cqueries, $iqueries );
foreach ( $allqueries as $query ) {
* Updates the database tables to a new schema.
* By default, updates all the tables to use the latest defined schema, but can also
* be used to update a specific set of tables in wp_get_db_schema().
* @param string $tables Optional. Which set of tables to update. Default is 'all'.
function make_db_current( $tables = 'all' ) {
$alterations = dbDelta( $tables );
foreach ( $alterations as $alteration ) {
echo "<li>$alteration</li>\n";
* Updates the database tables to a new schema, but without displaying results.
* By default, updates all the tables to use the latest defined schema, but can
* also be used to update a specific set of tables in wp_get_db_schema().
* @param string $tables Optional. Which set of tables to update. Default is 'all'.
function make_db_current_silent( $tables = 'all' ) {
* Creates a site theme from an existing theme.
* {@internal Missing Long Description}}
* @param string $theme_name The name of the theme.
* @param string $template The directory name of the theme.
function make_site_theme_from_oldschool( $theme_name, $template ) {
$home_path = get_home_path();
$site_dir = WP_CONTENT_DIR . "/themes/$template";
if ( ! file_exists( "$home_path/index.php" ) ) {
* Copy files from the old locations to the site theme.
* TODO: This does not copy arbitrary include dependencies. Only the standard WP files are copied.
'index.php' => 'index.php',
'wp-layout.css' => 'style.css',
'wp-comments.php' => 'comments.php',
'wp-comments-popup.php' => 'comments-popup.php',
foreach ( $files as $oldfile => $newfile ) {
if ( 'index.php' === $oldfile ) {
// Check to make sure it's not a new index.
if ( 'index.php' === $oldfile ) {
$index = implode( '', file( "$oldpath/$oldfile" ) );
if ( strpos( $index, 'WP_USE_THEMES' ) !== false ) {
if ( ! copy( WP_CONTENT_DIR . '/themes/' . WP_DEFAULT_THEME . '/index.php', "$site_dir/$newfile" ) ) {
if ( ! copy( "$oldpath/$oldfile", "$site_dir/$newfile" ) ) {
chmod( "$site_dir/$newfile", 0777 );
// Update the blog header include in each file.
$lines = explode( "\n", implode( '', file( "$site_dir/$newfile" ) ) );
$f = fopen( "$site_dir/$newfile", 'w' );
foreach ( $lines as $line ) {
if ( preg_match( '/require.*wp-blog-header/', $line ) ) {
// Update stylesheet references.
$line = str_replace( "<?php echo __get_option('siteurl'); ?>/wp-layout.css", "<?php bloginfo('stylesheet_url'); ?>", $line );
// Update comments template inclusion.
$line = str_replace( "<?php include(ABSPATH . 'wp-comments.php'); ?>", '<?php comments_template(); ?>', $line );
fwrite( $f, "{$line}\n" );
$header = "/*\nTheme Name: $theme_name\nTheme URI: " . __get_option( 'siteurl' ) . "\nDescription: A theme automatically created by the update.\nVersion: 1.0\nAuthor: Moi\n*/\n";
$stylelines = file_get_contents( "$site_dir/style.css" );
$f = fopen( "$site_dir/style.css", 'w' );
fwrite( $f, $stylelines );
* Creates a site theme from the default theme.
* {@internal Missing Long Description}}
* @param string $theme_name The name of the theme.
* @param string $template The directory name of the theme.
function make_site_theme_from_default( $theme_name, $template ) {
$site_dir = WP_CONTENT_DIR . "/themes/$template";
$default_dir = WP_CONTENT_DIR . '/themes/' . WP_DEFAULT_THEME;
// Copy files from the default theme to the site theme.
// $files = array( 'index.php', 'comments.php', 'comments-popup.php', 'footer.php', 'header.php', 'sidebar.php', 'style.css' );
$theme_dir = @opendir( $default_dir );
while ( ( $theme_file = readdir( $theme_dir ) ) !== false ) {
if ( is_dir( "$default_dir/$theme_file" ) ) {
if ( ! copy( "$default_dir/$theme_file", "$site_dir/$theme_file" ) ) {
chmod( "$site_dir/$theme_file", 0777 );
// Rewrite the theme header.
$stylelines = explode( "\n", implode( '', file( "$site_dir/style.css" ) ) );
$f = fopen( "$site_dir/style.css", 'w' );
foreach ( $stylelines as $line ) {
if ( strpos( $line, 'Theme Name:' ) !== false ) {
$line = 'Theme Name: ' . $theme_name;
} elseif ( strpos( $line, 'Theme URI:' ) !== false ) {
$line = 'Theme URI: ' . __get_option( 'url' );
} elseif ( strpos( $line, 'Description:' ) !== false ) {
$line = 'Description: Your theme.';
} elseif ( strpos( $line, 'Version:' ) !== false ) {
} elseif ( strpos( $line, 'Author:' ) !== false ) {
fwrite( $f, $line . "\n" );
if ( ! mkdir( "$site_dir/images", 0777 ) ) {
$images_dir = @opendir( "$default_dir/images" );
while ( ( $image = readdir( $images_dir ) ) !== false ) {
if ( is_dir( "$default_dir/images/$image" ) ) {
if ( ! copy( "$default_dir/images/$image", "$site_dir/images/$image" ) ) {
chmod( "$site_dir/images/$image", 0777 );
* {@internal Missing Long Description}}
function make_site_theme() {
// Name the theme after the blog.
$theme_name = __get_option( 'blogname' );
$template = sanitize_title( $theme_name );
$site_dir = WP_CONTENT_DIR . "/themes/$template";
// If the theme already exists, nothing to do.
if ( is_dir( $site_dir ) ) {
// We must be able to write to the themes dir.
if ( ! is_writable( WP_CONTENT_DIR . '/themes' ) ) {
if ( ! mkdir( $site_dir, 0777 ) ) {
if ( file_exists( ABSPATH . 'wp-layout.css' ) ) {
if ( ! make_site_theme_from_oldschool( $theme_name, $template ) ) {
// TODO: rm -rf the site theme directory.
if ( ! make_site_theme_from_default( $theme_name, $template ) ) {
// TODO: rm -rf the site theme directory.
// Make the new site theme active.
$current_template = __get_option( 'template' );
if ( WP_DEFAULT_THEME == $current_template ) {
update_option( 'template', $template );
update_option( 'stylesheet', $template );
* Translate user level to user role name.
* @param int $level User level.
* @return string User role name.
function translate_level_to_role( $level ) {
* Checks the version of the installed MySQL binary.
* @global wpdb $wpdb WordPress database abstraction object.
function wp_check_mysql_version() {
$result = $wpdb->check_database_version();
if ( is_wp_error( $result ) ) {
* Disables the Automattic widgets plugin, which was merged into core.
function maybe_disable_automattic_widgets() {
$plugins = __get_option( 'active_plugins' );
foreach ( (array) $plugins as $plugin ) {
if ( 'widgets.php' === basename( $plugin ) ) {
array_splice( $plugins, array_search( $plugin, $plugins, true ), 1 );
update_option( 'active_plugins', $plugins );
* Disables the Link Manager on upgrade if, at the time of upgrade, no links exist in the DB.
* @global int $wp_current_db_version The old (current) database version.
* @global wpdb $wpdb WordPress database abstraction object.
function maybe_disable_link_manager() {
global $wp_current_db_version, $wpdb;
if ( $wp_current_db_version >= 22006 && get_option( 'link_manager_enabled' ) && ! $wpdb->get_var( "SELECT link_id FROM $wpdb->links LIMIT 1" ) ) {
update_option( 'link_manager_enabled', 0 );
* Runs before the schema is upgraded.
* @global int $wp_current_db_version The old (current) database version.
* @global wpdb $wpdb WordPress database abstraction object.
function pre_schema_upgrade() {
global $wp_current_db_version, $wpdb;
// Upgrade versions prior to 2.9.
if ( $wp_current_db_version < 11557 ) {
// Delete duplicate options. Keep the option with the highest option_id.
$wpdb->query( "DELETE o1 FROM $wpdb->options AS o1 JOIN $wpdb->options AS o2 USING (`option_name`) WHERE o2.option_id > o1.option_id" );
// Drop the old primary key and add the new.
$wpdb->query( "ALTER TABLE $wpdb->options DROP PRIMARY KEY, ADD PRIMARY KEY(option_id)" );
// Drop the old option_name index. dbDelta() doesn't do the drop.
$wpdb->query( "ALTER TABLE $wpdb->options DROP INDEX option_name" );
// Multisite schema upgrades.
if ( $wp_current_db_version < 25448 && is_multisite() && wp_should_upgrade_global_tables() ) {
// Upgrade versions prior to 3.7.
if ( $wp_current_db_version < 25179 ) {
// New primary key for signups.
$wpdb->query( "ALTER TABLE $wpdb->signups ADD signup_id BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST" );
$wpdb->query( "ALTER TABLE $wpdb->signups DROP INDEX domain" );
if ( $wp_current_db_version < 25448 ) {
// Convert archived from enum to tinyint.
$wpdb->query( "ALTER TABLE $wpdb->blogs CHANGE COLUMN archived archived varchar(1) NOT NULL default '0'" );
$wpdb->query( "ALTER TABLE $wpdb->blogs CHANGE COLUMN archived archived tinyint(2) NOT NULL default 0" );
// Upgrade versions prior to 4.2.
if ( $wp_current_db_version < 31351 ) {
if ( ! is_multisite() && wp_should_upgrade_global_tables() ) {
$wpdb->query( "ALTER TABLE $wpdb->usermeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
$wpdb->query( "ALTER TABLE $wpdb->terms DROP INDEX slug, ADD INDEX slug(slug(191))" );
$wpdb->query( "ALTER TABLE $wpdb->terms DROP INDEX name, ADD INDEX name(name(191))" );
$wpdb->query( "ALTER TABLE $wpdb->commentmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
$wpdb->query( "ALTER TABLE $wpdb->postmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
$wpdb->query( "ALTER TABLE $wpdb->posts DROP INDEX post_name, ADD INDEX post_name(post_name(191))" );
// Upgrade versions prior to 4.4.
if ( $wp_current_db_version < 34978 ) {
// If compatible termmeta table is found, use it, but enforce a proper index and update collation.
if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->termmeta}'" ) && $wpdb->get_results( "SHOW INDEX FROM {$wpdb->termmeta} WHERE Column_name = 'meta_key'" ) ) {
$wpdb->query( "ALTER TABLE $wpdb->termmeta DROP INDEX meta_key, ADD INDEX meta_key(meta_key(191))" );
maybe_convert_table_to_utf8mb4( $wpdb->termmeta );
if ( ! function_exists( 'install_global_terms' ) ) :
* @global wpdb $wpdb WordPress database abstraction object.
* @global string $charset_collate
function install_global_terms() {
global $wpdb, $charset_collate;
CREATE TABLE $wpdb->sitecategories (
cat_ID bigint(20) NOT NULL auto_increment,
cat_name varchar(55) NOT NULL default '',
category_nicename varchar(200) NOT NULL default '',
last_updated timestamp NOT NULL,