update_core

函式
update_core ( $from, $to )
引數
  • (string) $from New release unzipped path.
    Required:
  • (string) $to Path to old WordPress installation.
    Required:
返回值
  • (string|WP_Error) New WordPress version on success, WP_Error on failure.
定義位置
相關方法
wp_update_core_maybe_update_coreupdate_metawp_update_commentupdate_category_cache
引入
2.7.0
棄用
-

update_core: 這個函式更新WordPress的核心檔案到一個新的版本。它通常在自動更新過程中被呼叫,但也可以手動觸發。

升級WordPress的核心。

這將在WordPress目錄的底部建立一個.maintenance檔案,以確保在檔案被複制到它們的位置時,人們無法訪問網站。

在資料庫升級後,`$_old_files`列表中的檔案將被刪除,新的檔案將從壓縮檔案中複製出來。

如果版本大於或等於被升級的舊版本,`$_new_bundled_files`列表中的檔案將被新增到安裝中。

新版本下載並解壓後,升級器的步驟是。
1. 測試選定檔案的解壓位置,以確保解壓成功。
2. 2.在當前的WordPress基地建立.maintenance檔案。
3. 3. 將新的WordPress目錄複製到舊的WordPress檔案上。
4. 升級WordPress到新版本。
4.1. 複製除wp-content以外的所有檔案/資料夾
4.2. 把任何語言檔案複製到WP_LANG_DIR(可能與WP_CONTENT_DIR不同)。
4.3. 將任何新的捆綁的主題/外掛複製到它們各自的位置。
5. 刪除新的WordPress目錄路徑。
6. 刪除.maintenance檔案。
7. 刪除舊檔案。
8. 刪除’update_core’選項。

有幾個地方會出現故障。例如,如果PHP在第6步之前就超時了,那麼你將無法訪問網站的任何部分。另外,由於升級將不會從它離開的地方繼續進行,你將不能自動刪除舊的檔案和刪除’update_core’選項。這並不是那麼糟糕。

如果在舊的WordPress上覆制新的WordPress失敗了,那麼更糟糕的是新的WordPress目錄會保留。

如果假設每個檔案都會被複制過來,包括外掛和主題,那麼如果你編輯了預設的主題,你應該重新命名它,這樣你的改動就會保留下來。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
function update_core( $from, $to ) {
global $wp_filesystem, $_old_files, $_new_bundled_files, $wpdb;
set_time_limit( 300 );
/**
* Filters feedback messages displayed during the core update process.
*
* The filter is first evaluated after the zip file for the latest version
* has been downloaded and unzipped. It is evaluated five more times during
* the process:
*
* 1. Before WordPress begins the core upgrade process.
* 2. Before Maintenance Mode is enabled.
* 3. Before WordPress begins copying over the necessary files.
* 4. Before Maintenance Mode is disabled.
* 5. Before the database is upgraded.
*
* @since 2.5.0
*
* @param string $feedback The core update feedback messages.
*/
apply_filters( 'update_feedback', __( 'Verifying the unpacked files…' ) );
// Sanity check the unzipped distribution.
$distro = '';
$roots = array( '/wordpress/', '/wordpress-mu/' );
foreach ( $roots as $root ) {
if ( $wp_filesystem->exists( $from . $root . 'readme.html' )
&& $wp_filesystem->exists( $from . $root . 'wp-includes/version.php' )
) {
$distro = $root;
break;
}
}
if ( ! $distro ) {
$wp_filesystem->delete( $from, true );
return new WP_Error( 'insane_distro', __( 'The update could not be unpacked' ) );
}
/*
* Import $wp_version, $required_php_version, and $required_mysql_version from the new version.
* DO NOT globalize any variables imported from `version-current.php` in this function.
*
* BC Note: $wp_filesystem->wp_content_dir() returned unslashed pre-2.8.
*/
$versions_file = trailingslashit( $wp_filesystem->wp_content_dir() ) . 'upgrade/version-current.php';
if ( ! $wp_filesystem->copy( $from . $distro . 'wp-includes/version.php', $versions_file ) ) {
$wp_filesystem->delete( $from, true );
return new WP_Error(
'copy_failed_for_version_file',
__( 'The update cannot be installed because some files could not be copied. This is usually due to inconsistent file permissions.' ),
'wp-includes/version.php'
);
}
$wp_filesystem->chmod( $versions_file, FS_CHMOD_FILE );
/*
* `wp_opcache_invalidate()` only exists in WordPress 5.5 or later,
* so don't run it when upgrading from older versions.
*/
if ( function_exists( 'wp_opcache_invalidate' ) ) {
wp_opcache_invalidate( $versions_file );
}
require WP_CONTENT_DIR . '/upgrade/version-current.php';
$wp_filesystem->delete( $versions_file );
$php_version = PHP_VERSION;
$mysql_version = $wpdb->db_version();
$old_wp_version = $GLOBALS['wp_version']; // The version of WordPress we're updating from.
$development_build = ( false !== strpos( $old_wp_version . $wp_version, '-' ) ); // A dash in the version indicates a development release.
$php_compat = version_compare( $php_version, $required_php_version, '>=' );
if ( file_exists( WP_CONTENT_DIR . '/db.php' ) && empty( $wpdb->is_mysql ) ) {
$mysql_compat = true;
} else {
$mysql_compat = version_compare( $mysql_version, $required_mysql_version, '>=' );
}
if ( ! $mysql_compat || ! $php_compat ) {
$wp_filesystem->delete( $from, true );
}
$php_update_message = '';
if ( function_exists( 'wp_get_update_php_url' ) ) {
$php_update_message = '</p><p>' . sprintf(
/* translators: %s: URL to Update PHP page. */
__( '<a href="%s">Learn more about updating PHP</a>.' ),
esc_url( wp_get_update_php_url() )
);
if ( function_exists( 'wp_get_update_php_annotation' ) ) {
$annotation = wp_get_update_php_annotation();
if ( $annotation ) {
$php_update_message .= '</p><p><em>' . $annotation . '</em>';
}
}
}
if ( ! $mysql_compat && ! $php_compat ) {
return new WP_Error(
'php_mysql_not_compatible',
sprintf(
/* translators: 1: WordPress version number, 2: Minimum required PHP version number, 3: Minimum required MySQL version number, 4: Current PHP version number, 5: Current MySQL version number. */
__( 'The update cannot be installed because WordPress %1$s requires PHP version %2$s or higher and MySQL version %3$s or higher. You are running PHP version %4$s and MySQL version %5$s.' ),
$wp_version,
$required_php_version,
$required_mysql_version,
$php_version,
$mysql_version
) . $php_update_message
);
} elseif ( ! $php_compat ) {
return new WP_Error(
'php_not_compatible',
sprintf(
/* translators: 1: WordPress version number, 2: Minimum required PHP version number, 3: Current PHP version number. */
__( 'The update cannot be installed because WordPress %1$s requires PHP version %2$s or higher. You are running version %3$s.' ),
$wp_version,
$required_php_version,
$php_version
) . $php_update_message
);
} elseif ( ! $mysql_compat ) {
return new WP_Error(
'mysql_not_compatible',
sprintf(
/* translators: 1: WordPress version number, 2: Minimum required MySQL version number, 3: Current MySQL version number. */
__( 'The update cannot be installed because WordPress %1$s requires MySQL version %2$s or higher. You are running version %3$s.' ),
$wp_version,
$required_mysql_version,
$mysql_version
)
);
}
// Add a warning when the JSON PHP extension is missing.
if ( ! extension_loaded( 'json' ) ) {
return new WP_Error(
'php_not_compatible_json',
sprintf(
/* translators: 1: WordPress version number, 2: The PHP extension name needed. */
__( 'The update cannot be installed because WordPress %1$s requires the %2$s PHP extension.' ),
$wp_version,
'JSON'
)
);
}
/** This filter is documented in wp-admin/includes/update-core.php */
apply_filters( 'update_feedback', __( 'Preparing to install the latest version…' ) );
// Don't copy wp-content, we'll deal with that below.
// We also copy version.php last so failed updates report their old version.
$skip = array( 'wp-content', 'wp-includes/version.php' );
$check_is_writable = array();
// Check to see which files don't really need updating - only available for 3.7 and higher.
if ( function_exists( 'get_core_checksums' ) ) {
// Find the local version of the working directory.
$working_dir_local = WP_CONTENT_DIR . '/upgrade/' . basename( $from ) . $distro;
$checksums = get_core_checksums( $wp_version, isset( $wp_local_package ) ? $wp_local_package : 'en_US' );
if ( is_array( $checksums ) && isset( $checksums[ $wp_version ] ) ) {
$checksums = $checksums[ $wp_version ]; // Compat code for 3.7-beta2.
}
if ( is_array( $checksums ) ) {
foreach ( $checksums as $file => $checksum ) {
if ( 'wp-content' === substr( $file, 0, 10 ) ) {
continue;
}
if ( ! file_exists( ABSPATH . $file ) ) {
continue;
}
if ( ! file_exists( $working_dir_local . $file ) ) {
continue;
}
if ( '.' === dirname( $file )
&& in_array( pathinfo( $file, PATHINFO_EXTENSION ), array( 'html', 'txt' ), true )
) {
continue;
}
if ( md5_file( ABSPATH . $file ) === $checksum ) {
$skip[] = $file;
} else {
$check_is_writable[ $file ] = ABSPATH . $file;
}
}
}
}
// If we're using the direct method, we can predict write failures that are due to permissions.
if ( $check_is_writable && 'direct' === $wp_filesystem->method ) {
$files_writable = array_filter( $check_is_writable, array( $wp_filesystem, 'is_writable' ) );
if ( $files_writable !== $check_is_writable ) {
$files_not_writable = array_diff_key( $check_is_writable, $files_writable );
foreach ( $files_not_writable as $relative_file_not_writable => $file_not_writable ) {
// If the writable check failed, chmod file to 0644 and try again, same as copy_dir().
$wp_filesystem->chmod( $file_not_writable, FS_CHMOD_FILE );
if ( $wp_filesystem->is_writable( $file_not_writable ) ) {
unset( $files_not_writable[ $relative_file_not_writable ] );
}
}
// Store package-relative paths (the key) of non-writable files in the WP_Error object.
$error_data = version_compare( $old_wp_version, '3.7-beta2', '>' ) ? array_keys( $files_not_writable ) : '';
if ( $files_not_writable ) {
return new WP_Error(
'files_not_writable',
__( 'The update cannot be installed because your site is unable to copy some files. This is usually due to inconsistent file permissions.' ),
implode( ', ', $error_data )
);
}
}
}
/** This filter is documented in wp-admin/includes/update-core.php */
apply_filters( 'update_feedback', __( 'Enabling Maintenance mode…' ) );
// Create maintenance file to signal that we are upgrading.
$maintenance_string = '<?php $upgrading = ' . time() . '; ?>';
$maintenance_file = $to . '.maintenance';
$wp_filesystem->delete( $maintenance_file );
$wp_filesystem->put_contents( $maintenance_file, $maintenance_string, FS_CHMOD_FILE );
/** This filter is documented in wp-admin/includes/update-core.php */
apply_filters( 'update_feedback', __( 'Copying the required files…' ) );
// Copy new versions of WP files into place.
$result = copy_dir( $from . $distro, $to, $skip );
if ( is_wp_error( $result ) ) {
$result = new WP_Error(
$result->get_error_code(),
$result->get_error_message(),
substr( $result->get_error_data(), strlen( $to ) )
);
}
// Since we know the core files have copied over, we can now copy the version file.
if ( ! is_wp_error( $result ) ) {
if ( ! $wp_filesystem->copy( $from . $distro . 'wp-includes/version.php', $to . 'wp-includes/version.php', true /* overwrite */ ) ) {
$wp_filesystem->delete( $from, true );
$result = new WP_Error(
'copy_failed_for_version_file',
__( 'The update cannot be installed because your site is unable to copy some files. This is usually due to inconsistent file permissions.' ),
'wp-includes/version.php'
);
}
$wp_filesystem->chmod( $to . 'wp-includes/version.php', FS_CHMOD_FILE );
/*
* `wp_opcache_invalidate()` only exists in WordPress 5.5 or later,
* so don't run it when upgrading from older versions.
*/
if ( function_exists( 'wp_opcache_invalidate' ) ) {
wp_opcache_invalidate( $to . 'wp-includes/version.php' );
}
}
// Check to make sure everything copied correctly, ignoring the contents of wp-content.
$skip = array( 'wp-content' );
$failed = array();
if ( isset( $checksums ) && is_array( $checksums ) ) {
foreach ( $checksums as $file => $checksum ) {
if ( 'wp-content' === substr( $file, 0, 10 ) ) {
continue;
}
if ( ! file_exists( $working_dir_local . $file ) ) {
continue;
}
if ( '.' === dirname( $file )
&& in_array( pathinfo( $file, PATHINFO_EXTENSION ), array( 'html', 'txt' ), true )
) {
$skip[] = $file;
continue;
}
if ( file_exists( ABSPATH . $file ) && md5_file( ABSPATH . $file ) === $checksum ) {
$skip[] = $file;
} else {
$failed[] = $file;
}
}
}
// Some files didn't copy properly.
if ( ! empty( $failed ) ) {
$total_size = 0;
foreach ( $failed as $file ) {
if ( file_exists( $working_dir_local . $file ) ) {
$total_size += filesize( $working_dir_local . $file );
}
}
// If we don't have enough free space, it isn't worth trying again.
// Unlikely to be hit due to the check in unzip_file().
$available_space = function_exists( 'disk_free_space' ) ? @disk_free_space( ABSPATH ) : false;
if ( $available_space && $total_size >= $available_space ) {
$result = new WP_Error( 'disk_full', __( 'There is not enough free disk space to complete the update.' ) );
} else {
$result = copy_dir( $from . $distro, $to, $skip );
if ( is_wp_error( $result ) ) {
$result = new WP_Error(
$result->get_error_code() . '_retry',
$result->get_error_message(),
substr( $result->get_error_data(), strlen( $to ) )
);
}
}
}
// Custom content directory needs updating now.
// Copy languages.
if ( ! is_wp_error( $result ) && $wp_filesystem->is_dir( $from . $distro . 'wp-content/languages' ) ) {
if ( WP_LANG_DIR !== ABSPATH . WPINC . '/languages' || @is_dir( WP_LANG_DIR ) ) {
$lang_dir = WP_LANG_DIR;
} else {
$lang_dir = WP_CONTENT_DIR . '/languages';
}
// Check if the language directory exists first.
if ( ! @is_dir( $lang_dir ) && 0 === strpos( $lang_dir, ABSPATH ) ) {
// If it's within the ABSPATH we can handle it here, otherwise they're out of luck.
$wp_filesystem->mkdir( $to . str_replace( ABSPATH, '', $lang_dir ), FS_CHMOD_DIR );
clearstatcache(); // For FTP, need to clear the stat cache.
}
if ( @is_dir( $lang_dir ) ) {
$wp_lang_dir = $wp_filesystem->find_folder( $lang_dir );
if ( $wp_lang_dir ) {
$result = copy_dir( $from . $distro . 'wp-content/languages/', $wp_lang_dir );
if ( is_wp_error( $result ) ) {
$result = new WP_Error(
$result->get_error_code() . '_languages',
$result->get_error_message(),
substr( $result->get_error_data(), strlen( $wp_lang_dir ) )
);
}
}
}
}
/** This filter is documented in wp-admin/includes/update-core.php */
apply_filters( 'update_feedback', __( 'Disabling Maintenance mode…' ) );
// Remove maintenance file, we're done with potential site-breaking changes.
$wp_filesystem->delete( $maintenance_file );
// 3.5 -> 3.5+ - an empty twentytwelve directory was created upon upgrade to 3.5 for some users,
// preventing installation of Twenty Twelve.
if ( '3.5' === $old_wp_version ) {
if ( is_dir( WP_CONTENT_DIR . '/themes/twentytwelve' )
&& ! file_exists( WP_CONTENT_DIR . '/themes/twentytwelve/style.css' )
) {
$wp_filesystem->delete( $wp_filesystem->wp_themes_dir() . 'twentytwelve/' );
}
}
/*
* Copy new bundled plugins & themes.
* This gives us the ability to install new plugins & themes bundled with
* future versions of WordPress whilst avoiding the re-install upon upgrade issue.
* $development_build controls us overwriting bundled themes and plugins when a non-stable release is being updated.
*/
if ( ! is_wp_error( $result )
&& ( ! defined( 'CORE_UPGRADE_SKIP_NEW_BUNDLED' ) || ! CORE_UPGRADE_SKIP_NEW_BUNDLED )
) {
foreach ( (array) $_new_bundled_files as $file => $introduced_version ) {
// If a $development_build or if $introduced version is greater than what the site was previously running.
if ( $development_build || version_compare( $introduced_version, $old_wp_version, '>' ) ) {
$directory = ( '/' === $file[ strlen( $file ) - 1 ] );
list( $type, $filename ) = explode( '/', $file, 2 );
// Check to see if the bundled items exist before attempting to copy them.
if ( ! $wp_filesystem->exists( $from . $distro . 'wp-content/' . $file ) ) {
continue;
}
if ( 'plugins' === $type ) {
$dest = $wp_filesystem->wp_plugins_dir();
} elseif ( 'themes' === $type ) {
// Back-compat, ::wp_themes_dir() did not return trailingslash'd pre-3.2.
$dest = trailingslashit( $wp_filesystem->wp_themes_dir() );
} else {
continue;
}
if ( ! $directory ) {
if ( ! $development_build && $wp_filesystem->exists( $dest . $filename ) ) {
continue;
}
if ( ! $wp_filesystem->copy( $from . $distro . 'wp-content/' . $file, $dest . $filename, FS_CHMOD_FILE ) ) {
$result = new WP_Error( "copy_failed_for_new_bundled_$type", __( 'Could not copy file.' ), $dest . $filename );
}
} else {
if ( ! $development_build && $wp_filesystem->is_dir( $dest . $filename ) ) {
continue;
}
$wp_filesystem->mkdir( $dest . $filename, FS_CHMOD_DIR );
$_result = copy_dir( $from . $distro . 'wp-content/' . $file, $dest . $filename );
// If a error occurs partway through this final step, keep the error flowing through, but keep process going.
if ( is_wp_error( $_result ) ) {
if ( ! is_wp_error( $result ) ) {
$result = new WP_Error;
}
$result->add(
$_result->get_error_code() . "_$type",
$_result->get_error_message(),
substr( $_result->get_error_data(), strlen( $dest ) )
);
}
}
}
} // End foreach.
}
// Handle $result error from the above blocks.
if ( is_wp_error( $result ) ) {
$wp_filesystem->delete( $from, true );
return $result;
}
// Remove old files.
foreach ( $_old_files as $old_file ) {
$old_file = $to . $old_file;
if ( ! $wp_filesystem->exists( $old_file ) ) {
continue;
}
// If the file isn't deleted, try writing an empty string to the file instead.
if ( ! $wp_filesystem->delete( $old_file, true ) && $wp_filesystem->is_file( $old_file ) ) {
$wp_filesystem->put_contents( $old_file, '' );
}
}
// Remove any Genericons example.html's from the filesystem.
_upgrade_422_remove_genericons();
// Deactivate the REST API plugin if its version is 2.0 Beta 4 or lower.
_upgrade_440_force_deactivate_incompatible_plugins();
// Deactivate the Gutenberg plugin if its version is 11.8 or lower.
_upgrade_590_force_deactivate_incompatible_plugins();
// Upgrade DB with separate request.
/** This filter is documented in wp-admin/includes/update-core.php */
apply_filters( 'update_feedback', __( 'Upgrading database…' ) );
$db_upgrade_url = admin_url( 'upgrade.php?step=upgrade_db' );
wp_remote_post( $db_upgrade_url, array( 'timeout' => 60 ) );
// Clear the cache to prevent an update_option() from saving a stale db_version to the cache.
wp_cache_flush();
// Not all cache back ends listen to 'flush'.
wp_cache_delete( 'alloptions', 'options' );
// Remove working directory.
$wp_filesystem->delete( $from, true );
// Force refresh of update information.
if ( function_exists( 'delete_site_transient' ) ) {
delete_site_transient( 'update_core' );
} else {
delete_option( 'update_core' );
}
/**
* Fires after WordPress core has been successfully updated.
*
* @since 3.3.0
*
* @param string $wp_version The current WordPress version.
*/
do_action( '_core_updated_successfully', $wp_version );
// Clear the option that blocks auto-updates after failures, now that we've been successful.
if ( function_exists( 'delete_site_option' ) ) {
delete_site_option( 'auto_core_update_failed' );
}
return $wp_version;
}
function update_core( $from, $to ) { global $wp_filesystem, $_old_files, $_new_bundled_files, $wpdb; set_time_limit( 300 ); /** * Filters feedback messages displayed during the core update process. * * The filter is first evaluated after the zip file for the latest version * has been downloaded and unzipped. It is evaluated five more times during * the process: * * 1. Before WordPress begins the core upgrade process. * 2. Before Maintenance Mode is enabled. * 3. Before WordPress begins copying over the necessary files. * 4. Before Maintenance Mode is disabled. * 5. Before the database is upgraded. * * @since 2.5.0 * * @param string $feedback The core update feedback messages. */ apply_filters( 'update_feedback', __( 'Verifying the unpacked files…' ) ); // Sanity check the unzipped distribution. $distro = ''; $roots = array( '/wordpress/', '/wordpress-mu/' ); foreach ( $roots as $root ) { if ( $wp_filesystem->exists( $from . $root . 'readme.html' ) && $wp_filesystem->exists( $from . $root . 'wp-includes/version.php' ) ) { $distro = $root; break; } } if ( ! $distro ) { $wp_filesystem->delete( $from, true ); return new WP_Error( 'insane_distro', __( 'The update could not be unpacked' ) ); } /* * Import $wp_version, $required_php_version, and $required_mysql_version from the new version. * DO NOT globalize any variables imported from `version-current.php` in this function. * * BC Note: $wp_filesystem->wp_content_dir() returned unslashed pre-2.8. */ $versions_file = trailingslashit( $wp_filesystem->wp_content_dir() ) . 'upgrade/version-current.php'; if ( ! $wp_filesystem->copy( $from . $distro . 'wp-includes/version.php', $versions_file ) ) { $wp_filesystem->delete( $from, true ); return new WP_Error( 'copy_failed_for_version_file', __( 'The update cannot be installed because some files could not be copied. This is usually due to inconsistent file permissions.' ), 'wp-includes/version.php' ); } $wp_filesystem->chmod( $versions_file, FS_CHMOD_FILE ); /* * `wp_opcache_invalidate()` only exists in WordPress 5.5 or later, * so don't run it when upgrading from older versions. */ if ( function_exists( 'wp_opcache_invalidate' ) ) { wp_opcache_invalidate( $versions_file ); } require WP_CONTENT_DIR . '/upgrade/version-current.php'; $wp_filesystem->delete( $versions_file ); $php_version = PHP_VERSION; $mysql_version = $wpdb->db_version(); $old_wp_version = $GLOBALS['wp_version']; // The version of WordPress we're updating from. $development_build = ( false !== strpos( $old_wp_version . $wp_version, '-' ) ); // A dash in the version indicates a development release. $php_compat = version_compare( $php_version, $required_php_version, '>=' ); if ( file_exists( WP_CONTENT_DIR . '/db.php' ) && empty( $wpdb->is_mysql ) ) { $mysql_compat = true; } else { $mysql_compat = version_compare( $mysql_version, $required_mysql_version, '>=' ); } if ( ! $mysql_compat || ! $php_compat ) { $wp_filesystem->delete( $from, true ); } $php_update_message = ''; if ( function_exists( 'wp_get_update_php_url' ) ) { $php_update_message = '</p><p>' . sprintf( /* translators: %s: URL to Update PHP page. */ __( '<a href="%s">Learn more about updating PHP</a>.' ), esc_url( wp_get_update_php_url() ) ); if ( function_exists( 'wp_get_update_php_annotation' ) ) { $annotation = wp_get_update_php_annotation(); if ( $annotation ) { $php_update_message .= '</p><p><em>' . $annotation . '</em>'; } } } if ( ! $mysql_compat && ! $php_compat ) { return new WP_Error( 'php_mysql_not_compatible', sprintf( /* translators: 1: WordPress version number, 2: Minimum required PHP version number, 3: Minimum required MySQL version number, 4: Current PHP version number, 5: Current MySQL version number. */ __( 'The update cannot be installed because WordPress %1$s requires PHP version %2$s or higher and MySQL version %3$s or higher. You are running PHP version %4$s and MySQL version %5$s.' ), $wp_version, $required_php_version, $required_mysql_version, $php_version, $mysql_version ) . $php_update_message ); } elseif ( ! $php_compat ) { return new WP_Error( 'php_not_compatible', sprintf( /* translators: 1: WordPress version number, 2: Minimum required PHP version number, 3: Current PHP version number. */ __( 'The update cannot be installed because WordPress %1$s requires PHP version %2$s or higher. You are running version %3$s.' ), $wp_version, $required_php_version, $php_version ) . $php_update_message ); } elseif ( ! $mysql_compat ) { return new WP_Error( 'mysql_not_compatible', sprintf( /* translators: 1: WordPress version number, 2: Minimum required MySQL version number, 3: Current MySQL version number. */ __( 'The update cannot be installed because WordPress %1$s requires MySQL version %2$s or higher. You are running version %3$s.' ), $wp_version, $required_mysql_version, $mysql_version ) ); } // Add a warning when the JSON PHP extension is missing. if ( ! extension_loaded( 'json' ) ) { return new WP_Error( 'php_not_compatible_json', sprintf( /* translators: 1: WordPress version number, 2: The PHP extension name needed. */ __( 'The update cannot be installed because WordPress %1$s requires the %2$s PHP extension.' ), $wp_version, 'JSON' ) ); } /** This filter is documented in wp-admin/includes/update-core.php */ apply_filters( 'update_feedback', __( 'Preparing to install the latest version…' ) ); // Don't copy wp-content, we'll deal with that below. // We also copy version.php last so failed updates report their old version. $skip = array( 'wp-content', 'wp-includes/version.php' ); $check_is_writable = array(); // Check to see which files don't really need updating - only available for 3.7 and higher. if ( function_exists( 'get_core_checksums' ) ) { // Find the local version of the working directory. $working_dir_local = WP_CONTENT_DIR . '/upgrade/' . basename( $from ) . $distro; $checksums = get_core_checksums( $wp_version, isset( $wp_local_package ) ? $wp_local_package : 'en_US' ); if ( is_array( $checksums ) && isset( $checksums[ $wp_version ] ) ) { $checksums = $checksums[ $wp_version ]; // Compat code for 3.7-beta2. } if ( is_array( $checksums ) ) { foreach ( $checksums as $file => $checksum ) { if ( 'wp-content' === substr( $file, 0, 10 ) ) { continue; } if ( ! file_exists( ABSPATH . $file ) ) { continue; } if ( ! file_exists( $working_dir_local . $file ) ) { continue; } if ( '.' === dirname( $file ) && in_array( pathinfo( $file, PATHINFO_EXTENSION ), array( 'html', 'txt' ), true ) ) { continue; } if ( md5_file( ABSPATH . $file ) === $checksum ) { $skip[] = $file; } else { $check_is_writable[ $file ] = ABSPATH . $file; } } } } // If we're using the direct method, we can predict write failures that are due to permissions. if ( $check_is_writable && 'direct' === $wp_filesystem->method ) { $files_writable = array_filter( $check_is_writable, array( $wp_filesystem, 'is_writable' ) ); if ( $files_writable !== $check_is_writable ) { $files_not_writable = array_diff_key( $check_is_writable, $files_writable ); foreach ( $files_not_writable as $relative_file_not_writable => $file_not_writable ) { // If the writable check failed, chmod file to 0644 and try again, same as copy_dir(). $wp_filesystem->chmod( $file_not_writable, FS_CHMOD_FILE ); if ( $wp_filesystem->is_writable( $file_not_writable ) ) { unset( $files_not_writable[ $relative_file_not_writable ] ); } } // Store package-relative paths (the key) of non-writable files in the WP_Error object. $error_data = version_compare( $old_wp_version, '3.7-beta2', '>' ) ? array_keys( $files_not_writable ) : ''; if ( $files_not_writable ) { return new WP_Error( 'files_not_writable', __( 'The update cannot be installed because your site is unable to copy some files. This is usually due to inconsistent file permissions.' ), implode( ', ', $error_data ) ); } } } /** This filter is documented in wp-admin/includes/update-core.php */ apply_filters( 'update_feedback', __( 'Enabling Maintenance mode…' ) ); // Create maintenance file to signal that we are upgrading. $maintenance_string = '<?php $upgrading = ' . time() . '; ?>'; $maintenance_file = $to . '.maintenance'; $wp_filesystem->delete( $maintenance_file ); $wp_filesystem->put_contents( $maintenance_file, $maintenance_string, FS_CHMOD_FILE ); /** This filter is documented in wp-admin/includes/update-core.php */ apply_filters( 'update_feedback', __( 'Copying the required files…' ) ); // Copy new versions of WP files into place. $result = copy_dir( $from . $distro, $to, $skip ); if ( is_wp_error( $result ) ) { $result = new WP_Error( $result->get_error_code(), $result->get_error_message(), substr( $result->get_error_data(), strlen( $to ) ) ); } // Since we know the core files have copied over, we can now copy the version file. if ( ! is_wp_error( $result ) ) { if ( ! $wp_filesystem->copy( $from . $distro . 'wp-includes/version.php', $to . 'wp-includes/version.php', true /* overwrite */ ) ) { $wp_filesystem->delete( $from, true ); $result = new WP_Error( 'copy_failed_for_version_file', __( 'The update cannot be installed because your site is unable to copy some files. This is usually due to inconsistent file permissions.' ), 'wp-includes/version.php' ); } $wp_filesystem->chmod( $to . 'wp-includes/version.php', FS_CHMOD_FILE ); /* * `wp_opcache_invalidate()` only exists in WordPress 5.5 or later, * so don't run it when upgrading from older versions. */ if ( function_exists( 'wp_opcache_invalidate' ) ) { wp_opcache_invalidate( $to . 'wp-includes/version.php' ); } } // Check to make sure everything copied correctly, ignoring the contents of wp-content. $skip = array( 'wp-content' ); $failed = array(); if ( isset( $checksums ) && is_array( $checksums ) ) { foreach ( $checksums as $file => $checksum ) { if ( 'wp-content' === substr( $file, 0, 10 ) ) { continue; } if ( ! file_exists( $working_dir_local . $file ) ) { continue; } if ( '.' === dirname( $file ) && in_array( pathinfo( $file, PATHINFO_EXTENSION ), array( 'html', 'txt' ), true ) ) { $skip[] = $file; continue; } if ( file_exists( ABSPATH . $file ) && md5_file( ABSPATH . $file ) === $checksum ) { $skip[] = $file; } else { $failed[] = $file; } } } // Some files didn't copy properly. if ( ! empty( $failed ) ) { $total_size = 0; foreach ( $failed as $file ) { if ( file_exists( $working_dir_local . $file ) ) { $total_size += filesize( $working_dir_local . $file ); } } // If we don't have enough free space, it isn't worth trying again. // Unlikely to be hit due to the check in unzip_file(). $available_space = function_exists( 'disk_free_space' ) ? @disk_free_space( ABSPATH ) : false; if ( $available_space && $total_size >= $available_space ) { $result = new WP_Error( 'disk_full', __( 'There is not enough free disk space to complete the update.' ) ); } else { $result = copy_dir( $from . $distro, $to, $skip ); if ( is_wp_error( $result ) ) { $result = new WP_Error( $result->get_error_code() . '_retry', $result->get_error_message(), substr( $result->get_error_data(), strlen( $to ) ) ); } } } // Custom content directory needs updating now. // Copy languages. if ( ! is_wp_error( $result ) && $wp_filesystem->is_dir( $from . $distro . 'wp-content/languages' ) ) { if ( WP_LANG_DIR !== ABSPATH . WPINC . '/languages' || @is_dir( WP_LANG_DIR ) ) { $lang_dir = WP_LANG_DIR; } else { $lang_dir = WP_CONTENT_DIR . '/languages'; } // Check if the language directory exists first. if ( ! @is_dir( $lang_dir ) && 0 === strpos( $lang_dir, ABSPATH ) ) { // If it's within the ABSPATH we can handle it here, otherwise they're out of luck. $wp_filesystem->mkdir( $to . str_replace( ABSPATH, '', $lang_dir ), FS_CHMOD_DIR ); clearstatcache(); // For FTP, need to clear the stat cache. } if ( @is_dir( $lang_dir ) ) { $wp_lang_dir = $wp_filesystem->find_folder( $lang_dir ); if ( $wp_lang_dir ) { $result = copy_dir( $from . $distro . 'wp-content/languages/', $wp_lang_dir ); if ( is_wp_error( $result ) ) { $result = new WP_Error( $result->get_error_code() . '_languages', $result->get_error_message(), substr( $result->get_error_data(), strlen( $wp_lang_dir ) ) ); } } } } /** This filter is documented in wp-admin/includes/update-core.php */ apply_filters( 'update_feedback', __( 'Disabling Maintenance mode…' ) ); // Remove maintenance file, we're done with potential site-breaking changes. $wp_filesystem->delete( $maintenance_file ); // 3.5 -> 3.5+ - an empty twentytwelve directory was created upon upgrade to 3.5 for some users, // preventing installation of Twenty Twelve. if ( '3.5' === $old_wp_version ) { if ( is_dir( WP_CONTENT_DIR . '/themes/twentytwelve' ) && ! file_exists( WP_CONTENT_DIR . '/themes/twentytwelve/style.css' ) ) { $wp_filesystem->delete( $wp_filesystem->wp_themes_dir() . 'twentytwelve/' ); } } /* * Copy new bundled plugins & themes. * This gives us the ability to install new plugins & themes bundled with * future versions of WordPress whilst avoiding the re-install upon upgrade issue. * $development_build controls us overwriting bundled themes and plugins when a non-stable release is being updated. */ if ( ! is_wp_error( $result ) && ( ! defined( 'CORE_UPGRADE_SKIP_NEW_BUNDLED' ) || ! CORE_UPGRADE_SKIP_NEW_BUNDLED ) ) { foreach ( (array) $_new_bundled_files as $file => $introduced_version ) { // If a $development_build or if $introduced version is greater than what the site was previously running. if ( $development_build || version_compare( $introduced_version, $old_wp_version, '>' ) ) { $directory = ( '/' === $file[ strlen( $file ) - 1 ] ); list( $type, $filename ) = explode( '/', $file, 2 ); // Check to see if the bundled items exist before attempting to copy them. if ( ! $wp_filesystem->exists( $from . $distro . 'wp-content/' . $file ) ) { continue; } if ( 'plugins' === $type ) { $dest = $wp_filesystem->wp_plugins_dir(); } elseif ( 'themes' === $type ) { // Back-compat, ::wp_themes_dir() did not return trailingslash'd pre-3.2. $dest = trailingslashit( $wp_filesystem->wp_themes_dir() ); } else { continue; } if ( ! $directory ) { if ( ! $development_build && $wp_filesystem->exists( $dest . $filename ) ) { continue; } if ( ! $wp_filesystem->copy( $from . $distro . 'wp-content/' . $file, $dest . $filename, FS_CHMOD_FILE ) ) { $result = new WP_Error( "copy_failed_for_new_bundled_$type", __( 'Could not copy file.' ), $dest . $filename ); } } else { if ( ! $development_build && $wp_filesystem->is_dir( $dest . $filename ) ) { continue; } $wp_filesystem->mkdir( $dest . $filename, FS_CHMOD_DIR ); $_result = copy_dir( $from . $distro . 'wp-content/' . $file, $dest . $filename ); // If a error occurs partway through this final step, keep the error flowing through, but keep process going. if ( is_wp_error( $_result ) ) { if ( ! is_wp_error( $result ) ) { $result = new WP_Error; } $result->add( $_result->get_error_code() . "_$type", $_result->get_error_message(), substr( $_result->get_error_data(), strlen( $dest ) ) ); } } } } // End foreach. } // Handle $result error from the above blocks. if ( is_wp_error( $result ) ) { $wp_filesystem->delete( $from, true ); return $result; } // Remove old files. foreach ( $_old_files as $old_file ) { $old_file = $to . $old_file; if ( ! $wp_filesystem->exists( $old_file ) ) { continue; } // If the file isn't deleted, try writing an empty string to the file instead. if ( ! $wp_filesystem->delete( $old_file, true ) && $wp_filesystem->is_file( $old_file ) ) { $wp_filesystem->put_contents( $old_file, '' ); } } // Remove any Genericons example.html's from the filesystem. _upgrade_422_remove_genericons(); // Deactivate the REST API plugin if its version is 2.0 Beta 4 or lower. _upgrade_440_force_deactivate_incompatible_plugins(); // Deactivate the Gutenberg plugin if its version is 11.8 or lower. _upgrade_590_force_deactivate_incompatible_plugins(); // Upgrade DB with separate request. /** This filter is documented in wp-admin/includes/update-core.php */ apply_filters( 'update_feedback', __( 'Upgrading database…' ) ); $db_upgrade_url = admin_url( 'upgrade.php?step=upgrade_db' ); wp_remote_post( $db_upgrade_url, array( 'timeout' => 60 ) ); // Clear the cache to prevent an update_option() from saving a stale db_version to the cache. wp_cache_flush(); // Not all cache back ends listen to 'flush'. wp_cache_delete( 'alloptions', 'options' ); // Remove working directory. $wp_filesystem->delete( $from, true ); // Force refresh of update information. if ( function_exists( 'delete_site_transient' ) ) { delete_site_transient( 'update_core' ); } else { delete_option( 'update_core' ); } /** * Fires after WordPress core has been successfully updated. * * @since 3.3.0 * * @param string $wp_version The current WordPress version. */ do_action( '_core_updated_successfully', $wp_version ); // Clear the option that blocks auto-updates after failures, now that we've been successful. if ( function_exists( 'delete_site_option' ) ) { delete_site_option( 'auto_core_update_failed' ); } return $wp_version; }
function update_core( $from, $to ) {
	global $wp_filesystem, $_old_files, $_new_bundled_files, $wpdb;

	set_time_limit( 300 );

	/**
	 * Filters feedback messages displayed during the core update process.
	 *
	 * The filter is first evaluated after the zip file for the latest version
	 * has been downloaded and unzipped. It is evaluated five more times during
	 * the process:
	 *
	 * 1. Before WordPress begins the core upgrade process.
	 * 2. Before Maintenance Mode is enabled.
	 * 3. Before WordPress begins copying over the necessary files.
	 * 4. Before Maintenance Mode is disabled.
	 * 5. Before the database is upgraded.
	 *
	 * @since 2.5.0
	 *
	 * @param string $feedback The core update feedback messages.
	 */
	apply_filters( 'update_feedback', __( 'Verifying the unpacked files…' ) );

	// Sanity check the unzipped distribution.
	$distro = '';
	$roots  = array( '/wordpress/', '/wordpress-mu/' );

	foreach ( $roots as $root ) {
		if ( $wp_filesystem->exists( $from . $root . 'readme.html' )
			&& $wp_filesystem->exists( $from . $root . 'wp-includes/version.php' )
		) {
			$distro = $root;
			break;
		}
	}

	if ( ! $distro ) {
		$wp_filesystem->delete( $from, true );

		return new WP_Error( 'insane_distro', __( 'The update could not be unpacked' ) );
	}

	/*
	 * Import $wp_version, $required_php_version, and $required_mysql_version from the new version.
	 * DO NOT globalize any variables imported from `version-current.php` in this function.
	 *
	 * BC Note: $wp_filesystem->wp_content_dir() returned unslashed pre-2.8.
	 */
	$versions_file = trailingslashit( $wp_filesystem->wp_content_dir() ) . 'upgrade/version-current.php';

	if ( ! $wp_filesystem->copy( $from . $distro . 'wp-includes/version.php', $versions_file ) ) {
		$wp_filesystem->delete( $from, true );

		return new WP_Error(
			'copy_failed_for_version_file',
			__( 'The update cannot be installed because some files could not be copied. This is usually due to inconsistent file permissions.' ),
			'wp-includes/version.php'
		);
	}

	$wp_filesystem->chmod( $versions_file, FS_CHMOD_FILE );

	/*
	 * `wp_opcache_invalidate()` only exists in WordPress 5.5 or later,
	 * so don't run it when upgrading from older versions.
	 */
	if ( function_exists( 'wp_opcache_invalidate' ) ) {
		wp_opcache_invalidate( $versions_file );
	}

	require WP_CONTENT_DIR . '/upgrade/version-current.php';
	$wp_filesystem->delete( $versions_file );

	$php_version       = PHP_VERSION;
	$mysql_version     = $wpdb->db_version();
	$old_wp_version    = $GLOBALS['wp_version']; // The version of WordPress we're updating from.
	$development_build = ( false !== strpos( $old_wp_version . $wp_version, '-' ) ); // A dash in the version indicates a development release.
	$php_compat        = version_compare( $php_version, $required_php_version, '>=' );

	if ( file_exists( WP_CONTENT_DIR . '/db.php' ) && empty( $wpdb->is_mysql ) ) {
		$mysql_compat = true;
	} else {
		$mysql_compat = version_compare( $mysql_version, $required_mysql_version, '>=' );
	}

	if ( ! $mysql_compat || ! $php_compat ) {
		$wp_filesystem->delete( $from, true );
	}

	$php_update_message = '';

	if ( function_exists( 'wp_get_update_php_url' ) ) {
		$php_update_message = '</p><p>' . sprintf(
			/* translators: %s: URL to Update PHP page. */
			__( '<a href="%s">Learn more about updating PHP</a>.' ),
			esc_url( wp_get_update_php_url() )
		);

		if ( function_exists( 'wp_get_update_php_annotation' ) ) {
			$annotation = wp_get_update_php_annotation();

			if ( $annotation ) {
				$php_update_message .= '</p><p><em>' . $annotation . '</em>';
			}
		}
	}

	if ( ! $mysql_compat && ! $php_compat ) {
		return new WP_Error(
			'php_mysql_not_compatible',
			sprintf(
				/* translators: 1: WordPress version number, 2: Minimum required PHP version number, 3: Minimum required MySQL version number, 4: Current PHP version number, 5: Current MySQL version number. */
				__( 'The update cannot be installed because WordPress %1$s requires PHP version %2$s or higher and MySQL version %3$s or higher. You are running PHP version %4$s and MySQL version %5$s.' ),
				$wp_version,
				$required_php_version,
				$required_mysql_version,
				$php_version,
				$mysql_version
			) . $php_update_message
		);
	} elseif ( ! $php_compat ) {
		return new WP_Error(
			'php_not_compatible',
			sprintf(
				/* translators: 1: WordPress version number, 2: Minimum required PHP version number, 3: Current PHP version number. */
				__( 'The update cannot be installed because WordPress %1$s requires PHP version %2$s or higher. You are running version %3$s.' ),
				$wp_version,
				$required_php_version,
				$php_version
			) . $php_update_message
		);
	} elseif ( ! $mysql_compat ) {
		return new WP_Error(
			'mysql_not_compatible',
			sprintf(
				/* translators: 1: WordPress version number, 2: Minimum required MySQL version number, 3: Current MySQL version number. */
				__( 'The update cannot be installed because WordPress %1$s requires MySQL version %2$s or higher. You are running version %3$s.' ),
				$wp_version,
				$required_mysql_version,
				$mysql_version
			)
		);
	}

	// Add a warning when the JSON PHP extension is missing.
	if ( ! extension_loaded( 'json' ) ) {
		return new WP_Error(
			'php_not_compatible_json',
			sprintf(
				/* translators: 1: WordPress version number, 2: The PHP extension name needed. */
				__( 'The update cannot be installed because WordPress %1$s requires the %2$s PHP extension.' ),
				$wp_version,
				'JSON'
			)
		);
	}

	/** This filter is documented in wp-admin/includes/update-core.php */
	apply_filters( 'update_feedback', __( 'Preparing to install the latest version…' ) );

	// Don't copy wp-content, we'll deal with that below.
	// We also copy version.php last so failed updates report their old version.
	$skip              = array( 'wp-content', 'wp-includes/version.php' );
	$check_is_writable = array();

	// Check to see which files don't really need updating - only available for 3.7 and higher.
	if ( function_exists( 'get_core_checksums' ) ) {
		// Find the local version of the working directory.
		$working_dir_local = WP_CONTENT_DIR . '/upgrade/' . basename( $from ) . $distro;

		$checksums = get_core_checksums( $wp_version, isset( $wp_local_package ) ? $wp_local_package : 'en_US' );

		if ( is_array( $checksums ) && isset( $checksums[ $wp_version ] ) ) {
			$checksums = $checksums[ $wp_version ]; // Compat code for 3.7-beta2.
		}

		if ( is_array( $checksums ) ) {
			foreach ( $checksums as $file => $checksum ) {
				if ( 'wp-content' === substr( $file, 0, 10 ) ) {
					continue;
				}

				if ( ! file_exists( ABSPATH . $file ) ) {
					continue;
				}

				if ( ! file_exists( $working_dir_local . $file ) ) {
					continue;
				}

				if ( '.' === dirname( $file )
					&& in_array( pathinfo( $file, PATHINFO_EXTENSION ), array( 'html', 'txt' ), true )
				) {
					continue;
				}

				if ( md5_file( ABSPATH . $file ) === $checksum ) {
					$skip[] = $file;
				} else {
					$check_is_writable[ $file ] = ABSPATH . $file;
				}
			}
		}
	}

	// If we're using the direct method, we can predict write failures that are due to permissions.
	if ( $check_is_writable && 'direct' === $wp_filesystem->method ) {
		$files_writable = array_filter( $check_is_writable, array( $wp_filesystem, 'is_writable' ) );

		if ( $files_writable !== $check_is_writable ) {
			$files_not_writable = array_diff_key( $check_is_writable, $files_writable );

			foreach ( $files_not_writable as $relative_file_not_writable => $file_not_writable ) {
				// If the writable check failed, chmod file to 0644 and try again, same as copy_dir().
				$wp_filesystem->chmod( $file_not_writable, FS_CHMOD_FILE );

				if ( $wp_filesystem->is_writable( $file_not_writable ) ) {
					unset( $files_not_writable[ $relative_file_not_writable ] );
				}
			}

			// Store package-relative paths (the key) of non-writable files in the WP_Error object.
			$error_data = version_compare( $old_wp_version, '3.7-beta2', '>' ) ? array_keys( $files_not_writable ) : '';

			if ( $files_not_writable ) {
				return new WP_Error(
					'files_not_writable',
					__( 'The update cannot be installed because your site is unable to copy some files. This is usually due to inconsistent file permissions.' ),
					implode( ', ', $error_data )
				);
			}
		}
	}

	/** This filter is documented in wp-admin/includes/update-core.php */
	apply_filters( 'update_feedback', __( 'Enabling Maintenance mode…' ) );

	// Create maintenance file to signal that we are upgrading.
	$maintenance_string = '<?php $upgrading = ' . time() . '; ?>';
	$maintenance_file   = $to . '.maintenance';
	$wp_filesystem->delete( $maintenance_file );
	$wp_filesystem->put_contents( $maintenance_file, $maintenance_string, FS_CHMOD_FILE );

	/** This filter is documented in wp-admin/includes/update-core.php */
	apply_filters( 'update_feedback', __( 'Copying the required files…' ) );

	// Copy new versions of WP files into place.
	$result = copy_dir( $from . $distro, $to, $skip );

	if ( is_wp_error( $result ) ) {
		$result = new WP_Error(
			$result->get_error_code(),
			$result->get_error_message(),
			substr( $result->get_error_data(), strlen( $to ) )
		);
	}

	// Since we know the core files have copied over, we can now copy the version file.
	if ( ! is_wp_error( $result ) ) {
		if ( ! $wp_filesystem->copy( $from . $distro . 'wp-includes/version.php', $to . 'wp-includes/version.php', true /* overwrite */ ) ) {
			$wp_filesystem->delete( $from, true );
			$result = new WP_Error(
				'copy_failed_for_version_file',
				__( 'The update cannot be installed because your site is unable to copy some files. This is usually due to inconsistent file permissions.' ),
				'wp-includes/version.php'
			);
		}

		$wp_filesystem->chmod( $to . 'wp-includes/version.php', FS_CHMOD_FILE );

		/*
		 * `wp_opcache_invalidate()` only exists in WordPress 5.5 or later,
		 * so don't run it when upgrading from older versions.
		 */
		if ( function_exists( 'wp_opcache_invalidate' ) ) {
			wp_opcache_invalidate( $to . 'wp-includes/version.php' );
		}
	}

	// Check to make sure everything copied correctly, ignoring the contents of wp-content.
	$skip   = array( 'wp-content' );
	$failed = array();

	if ( isset( $checksums ) && is_array( $checksums ) ) {
		foreach ( $checksums as $file => $checksum ) {
			if ( 'wp-content' === substr( $file, 0, 10 ) ) {
				continue;
			}

			if ( ! file_exists( $working_dir_local . $file ) ) {
				continue;
			}

			if ( '.' === dirname( $file )
				&& in_array( pathinfo( $file, PATHINFO_EXTENSION ), array( 'html', 'txt' ), true )
			) {
				$skip[] = $file;
				continue;
			}

			if ( file_exists( ABSPATH . $file ) && md5_file( ABSPATH . $file ) === $checksum ) {
				$skip[] = $file;
			} else {
				$failed[] = $file;
			}
		}
	}

	// Some files didn't copy properly.
	if ( ! empty( $failed ) ) {
		$total_size = 0;

		foreach ( $failed as $file ) {
			if ( file_exists( $working_dir_local . $file ) ) {
				$total_size += filesize( $working_dir_local . $file );
			}
		}

		// If we don't have enough free space, it isn't worth trying again.
		// Unlikely to be hit due to the check in unzip_file().
		$available_space = function_exists( 'disk_free_space' ) ? @disk_free_space( ABSPATH ) : false;

		if ( $available_space && $total_size >= $available_space ) {
			$result = new WP_Error( 'disk_full', __( 'There is not enough free disk space to complete the update.' ) );
		} else {
			$result = copy_dir( $from . $distro, $to, $skip );

			if ( is_wp_error( $result ) ) {
				$result = new WP_Error(
					$result->get_error_code() . '_retry',
					$result->get_error_message(),
					substr( $result->get_error_data(), strlen( $to ) )
				);
			}
		}
	}

	// Custom content directory needs updating now.
	// Copy languages.
	if ( ! is_wp_error( $result ) && $wp_filesystem->is_dir( $from . $distro . 'wp-content/languages' ) ) {
		if ( WP_LANG_DIR !== ABSPATH . WPINC . '/languages' || @is_dir( WP_LANG_DIR ) ) {
			$lang_dir = WP_LANG_DIR;
		} else {
			$lang_dir = WP_CONTENT_DIR . '/languages';
		}

		// Check if the language directory exists first.
		if ( ! @is_dir( $lang_dir ) && 0 === strpos( $lang_dir, ABSPATH ) ) {
			// If it's within the ABSPATH we can handle it here, otherwise they're out of luck.
			$wp_filesystem->mkdir( $to . str_replace( ABSPATH, '', $lang_dir ), FS_CHMOD_DIR );
			clearstatcache(); // For FTP, need to clear the stat cache.
		}

		if ( @is_dir( $lang_dir ) ) {
			$wp_lang_dir = $wp_filesystem->find_folder( $lang_dir );

			if ( $wp_lang_dir ) {
				$result = copy_dir( $from . $distro . 'wp-content/languages/', $wp_lang_dir );

				if ( is_wp_error( $result ) ) {
					$result = new WP_Error(
						$result->get_error_code() . '_languages',
						$result->get_error_message(),
						substr( $result->get_error_data(), strlen( $wp_lang_dir ) )
					);
				}
			}
		}
	}

	/** This filter is documented in wp-admin/includes/update-core.php */
	apply_filters( 'update_feedback', __( 'Disabling Maintenance mode…' ) );

	// Remove maintenance file, we're done with potential site-breaking changes.
	$wp_filesystem->delete( $maintenance_file );

	// 3.5 -> 3.5+ - an empty twentytwelve directory was created upon upgrade to 3.5 for some users,
	// preventing installation of Twenty Twelve.
	if ( '3.5' === $old_wp_version ) {
		if ( is_dir( WP_CONTENT_DIR . '/themes/twentytwelve' )
			&& ! file_exists( WP_CONTENT_DIR . '/themes/twentytwelve/style.css' )
		) {
			$wp_filesystem->delete( $wp_filesystem->wp_themes_dir() . 'twentytwelve/' );
		}
	}

	/*
	 * Copy new bundled plugins & themes.
	 * This gives us the ability to install new plugins & themes bundled with
	 * future versions of WordPress whilst avoiding the re-install upon upgrade issue.
	 * $development_build controls us overwriting bundled themes and plugins when a non-stable release is being updated.
	 */
	if ( ! is_wp_error( $result )
		&& ( ! defined( 'CORE_UPGRADE_SKIP_NEW_BUNDLED' ) || ! CORE_UPGRADE_SKIP_NEW_BUNDLED )
	) {
		foreach ( (array) $_new_bundled_files as $file => $introduced_version ) {
			// If a $development_build or if $introduced version is greater than what the site was previously running.
			if ( $development_build || version_compare( $introduced_version, $old_wp_version, '>' ) ) {
				$directory = ( '/' === $file[ strlen( $file ) - 1 ] );

				list( $type, $filename ) = explode( '/', $file, 2 );

				// Check to see if the bundled items exist before attempting to copy them.
				if ( ! $wp_filesystem->exists( $from . $distro . 'wp-content/' . $file ) ) {
					continue;
				}

				if ( 'plugins' === $type ) {
					$dest = $wp_filesystem->wp_plugins_dir();
				} elseif ( 'themes' === $type ) {
					// Back-compat, ::wp_themes_dir() did not return trailingslash'd pre-3.2.
					$dest = trailingslashit( $wp_filesystem->wp_themes_dir() );
				} else {
					continue;
				}

				if ( ! $directory ) {
					if ( ! $development_build && $wp_filesystem->exists( $dest . $filename ) ) {
						continue;
					}

					if ( ! $wp_filesystem->copy( $from . $distro . 'wp-content/' . $file, $dest . $filename, FS_CHMOD_FILE ) ) {
						$result = new WP_Error( "copy_failed_for_new_bundled_$type", __( 'Could not copy file.' ), $dest . $filename );
					}
				} else {
					if ( ! $development_build && $wp_filesystem->is_dir( $dest . $filename ) ) {
						continue;
					}

					$wp_filesystem->mkdir( $dest . $filename, FS_CHMOD_DIR );
					$_result = copy_dir( $from . $distro . 'wp-content/' . $file, $dest . $filename );

					// If a error occurs partway through this final step, keep the error flowing through, but keep process going.
					if ( is_wp_error( $_result ) ) {
						if ( ! is_wp_error( $result ) ) {
							$result = new WP_Error;
						}

						$result->add(
							$_result->get_error_code() . "_$type",
							$_result->get_error_message(),
							substr( $_result->get_error_data(), strlen( $dest ) )
						);
					}
				}
			}
		} // End foreach.
	}

	// Handle $result error from the above blocks.
	if ( is_wp_error( $result ) ) {
		$wp_filesystem->delete( $from, true );

		return $result;
	}

	// Remove old files.
	foreach ( $_old_files as $old_file ) {
		$old_file = $to . $old_file;

		if ( ! $wp_filesystem->exists( $old_file ) ) {
			continue;
		}

		// If the file isn't deleted, try writing an empty string to the file instead.
		if ( ! $wp_filesystem->delete( $old_file, true ) && $wp_filesystem->is_file( $old_file ) ) {
			$wp_filesystem->put_contents( $old_file, '' );
		}
	}

	// Remove any Genericons example.html's from the filesystem.
	_upgrade_422_remove_genericons();

	// Deactivate the REST API plugin if its version is 2.0 Beta 4 or lower.
	_upgrade_440_force_deactivate_incompatible_plugins();

	// Deactivate the Gutenberg plugin if its version is 11.8 or lower.
	_upgrade_590_force_deactivate_incompatible_plugins();

	// Upgrade DB with separate request.
	/** This filter is documented in wp-admin/includes/update-core.php */
	apply_filters( 'update_feedback', __( 'Upgrading database…' ) );

	$db_upgrade_url = admin_url( 'upgrade.php?step=upgrade_db' );
	wp_remote_post( $db_upgrade_url, array( 'timeout' => 60 ) );

	// Clear the cache to prevent an update_option() from saving a stale db_version to the cache.
	wp_cache_flush();
	// Not all cache back ends listen to 'flush'.
	wp_cache_delete( 'alloptions', 'options' );

	// Remove working directory.
	$wp_filesystem->delete( $from, true );

	// Force refresh of update information.
	if ( function_exists( 'delete_site_transient' ) ) {
		delete_site_transient( 'update_core' );
	} else {
		delete_option( 'update_core' );
	}

	/**
	 * Fires after WordPress core has been successfully updated.
	 *
	 * @since 3.3.0
	 *
	 * @param string $wp_version The current WordPress version.
	 */
	do_action( '_core_updated_successfully', $wp_version );

	// Clear the option that blocks auto-updates after failures, now that we've been successful.
	if ( function_exists( 'delete_site_option' ) ) {
		delete_site_option( 'auto_core_update_failed' );
	}

	return $wp_version;
}

常見問題

FAQs
檢視更多 >