Source
File: wp-admin/includes/class-core-upgrader.php
public function upgrade( $current, $args = array() ) {
global $wp_filesystem;
require ABSPATH . WPINC . '/version.php'; // $wp_version;
$start_time = time();
$defaults = array(
'pre_check_md5' => true,
'attempt_rollback' => false,
'do_rollback' => false,
'allow_relaxed_file_ownership' => false,
);
$parsed_args = wp_parse_args( $args, $defaults );
$this->init();
$this->upgrade_strings();
// Is an update available?
if ( ! isset( $current->response ) || 'latest' === $current->response ) {
return new WP_Error( 'up_to_date', $this->strings['up_to_date'] );
}
$res = $this->fs_connect( array( ABSPATH, WP_CONTENT_DIR ), $parsed_args['allow_relaxed_file_ownership'] );
if ( ! $res || is_wp_error( $res ) ) {
return $res;
}
$wp_dir = trailingslashit( $wp_filesystem->abspath() );
$partial = true;
if ( $parsed_args['do_rollback'] ) {
$partial = false;
} elseif ( $parsed_args['pre_check_md5'] && ! $this->check_files() ) {
$partial = false;
}
/*
* If partial update is returned from the API, use that, unless we're doing
* a reinstallation. If we cross the new_bundled version number, then use
* the new_bundled zip. Don't though if the constant is set to skip bundled items.
* If the API returns a no_content zip, go with it. Finally, default to the full zip.
*/
if ( $parsed_args['do_rollback'] && $current->packages->rollback ) {
$to_download = 'rollback';
} elseif ( $current->packages->partial && 'reinstall' !== $current->response && $wp_version == $current->partial_version && $partial ) {
$to_download = 'partial';
} elseif ( $current->packages->new_bundled && version_compare( $wp_version, $current->new_bundled, '<' )
&& ( ! defined( 'CORE_UPGRADE_SKIP_NEW_BUNDLED' ) || ! CORE_UPGRADE_SKIP_NEW_BUNDLED ) ) {
$to_download = 'new_bundled';
} elseif ( $current->packages->no_content ) {
$to_download = 'no_content';
} else {
$to_download = 'full';
}
// Lock to prevent multiple Core Updates occurring.
$lock = WP_Upgrader::create_lock( 'core_updater', 15 * MINUTE_IN_SECONDS );
if ( ! $lock ) {
return new WP_Error( 'locked', $this->strings['locked'] );
}
$download = $this->download_package( $current->packages->$to_download, true );
// Allow for signature soft-fail.
// WARNING: This may be removed in the future.
if ( is_wp_error( $download ) && $download->get_error_data( 'softfail-filename' ) ) {
// Outout the failure error as a normal feedback, and not as an error:
/** This filter is documented in wp-admin/includes/update-core.php */
apply_filters( 'update_feedback', $download->get_error_message() );
// Report this failure back to WordPress.org for debugging purposes.
wp_version_check(
array(
'signature_failure_code' => $download->get_error_code(),
'signature_failure_data' => $download->get_error_data(),
)
);
// Pretend this error didn't happen.
$download = $download->get_error_data( 'softfail-filename' );
}
if ( is_wp_error( $download ) ) {
WP_Upgrader::release_lock( 'core_updater' );
return $download;
}
$working_dir = $this->unpack_package( $download );
if ( is_wp_error( $working_dir ) ) {
WP_Upgrader::release_lock( 'core_updater' );
return $working_dir;
}
// Copy update-core.php from the new version into place.
if ( ! $wp_filesystem->copy( $working_dir . '/wordpress/wp-admin/includes/update-core.php', $wp_dir . 'wp-admin/includes/update-core.php', true ) ) {
$wp_filesystem->delete( $working_dir, true );
WP_Upgrader::release_lock( 'core_updater' );
return new WP_Error( 'copy_failed_for_update_core_file', __( 'The update cannot be installed because we will be unable to copy some files. This is usually due to inconsistent file permissions.' ), 'wp-admin/includes/update-core.php' );
}
$wp_filesystem->chmod( $wp_dir . 'wp-admin/includes/update-core.php', FS_CHMOD_FILE );
wp_opcache_invalidate( ABSPATH . 'wp-admin/includes/update-core.php' );
require_once ABSPATH . 'wp-admin/includes/update-core.php';
if ( ! function_exists( 'update_core' ) ) {
WP_Upgrader::release_lock( 'core_updater' );
return new WP_Error( 'copy_failed_space', $this->strings['copy_failed_space'] );
}
$result = update_core( $working_dir, $wp_dir );
// In the event of an issue, we may be able to roll back.
if ( $parsed_args['attempt_rollback'] && $current->packages->rollback && ! $parsed_args['do_rollback'] ) {
$try_rollback = false;
if ( is_wp_error( $result ) ) {
$error_code = $result->get_error_code();
/*
* Not all errors are equal. These codes are critical: copy_failed__copy_dir,
* mkdir_failed__copy_dir, copy_failed__copy_dir_retry, and disk_full.
* do_rollback allows for update_core() to trigger a rollback if needed.
*/
if ( false !== strpos( $error_code, 'do_rollback' ) ) {
$try_rollback = true;
} elseif ( false !== strpos( $error_code, '__copy_dir' ) ) {
$try_rollback = true;
} elseif ( 'disk_full' === $error_code ) {
$try_rollback = true;
}
}
if ( $try_rollback ) {
/** This filter is documented in wp-admin/includes/update-core.php */
apply_filters( 'update_feedback', $result );
/** This filter is documented in wp-admin/includes/update-core.php */
apply_filters( 'update_feedback', $this->strings['start_rollback'] );
$rollback_result = $this->upgrade( $current, array_merge( $parsed_args, array( 'do_rollback' => true ) ) );
$original_result = $result;
$result = new WP_Error(
'rollback_was_required',
$this->strings['rollback_was_required'],
(object) array(
'update' => $original_result,
'rollback' => $rollback_result,
)
);
}
}
/** This action is documented in wp-admin/includes/class-wp-upgrader.php */
do_action(
'upgrader_process_complete',
$this,
array(
'action' => 'update',
'type' => 'core',
)
);
// Clear the current updates.
delete_site_transient( 'update_core' );
if ( ! $parsed_args['do_rollback'] ) {
$stats = array(
'update_type' => $current->response,
'success' => true,
'fs_method' => $wp_filesystem->method,
'fs_method_forced' => defined( 'FS_METHOD' ) || has_filter( 'filesystem_method' ),
'fs_method_direct' => ! empty( $GLOBALS['_wp_filesystem_direct_method'] ) ? $GLOBALS['_wp_filesystem_direct_method'] : '',
'time_taken' => time() - $start_time,
'reported' => $wp_version,
'attempted' => $current->version,
);
if ( is_wp_error( $result ) ) {
$stats['success'] = false;
// Did a rollback occur?
if ( ! empty( $try_rollback ) ) {
$stats['error_code'] = $original_result->get_error_code();
$stats['error_data'] = $original_result->get_error_data();
// Was the rollback successful? If not, collect its error too.
$stats['rollback'] = ! is_wp_error( $rollback_result );
if ( is_wp_error( $rollback_result ) ) {
$stats['rollback_code'] = $rollback_result->get_error_code();
$stats['rollback_data'] = $rollback_result->get_error_data();
}
} else {
$stats['error_code'] = $result->get_error_code();
$stats['error_data'] = $result->get_error_data();
}
}
wp_version_check( $stats );
}
WP_Upgrader::release_lock( 'core_updater' );
return $result;
}