Core_Upgrader::upgrade( object $current, array $args = array() ): string|false|WP_Error

In this article

Upgrades WordPress core.

Parameters

$currentobjectrequired
Response object for whether WordPress is current.
$argsarrayoptional
Arguments for upgrading WordPress core.
  • pre_check_md5 bool
    Whether to check the file checksums before attempting the upgrade. Default true.
  • attempt_rollback bool
    Whether to attempt to rollback the chances if there is a problem. Default false.
  • do_rollback bool
    Whether to perform this "upgrade" as a rollback.
    Default false.

Default:array()

Return

string|false|WP_Error New WordPress version on success, false or WP_Error on failure.

Source

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' ) ) {
		// Output 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 some files could not be copied. 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 ( str_contains( $error_code, 'do_rollback' ) ) {
				$try_rollback = true;
			} elseif ( str_contains( $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;
}

Hooks

apply_filters( ‘update_feedback’, string $feedback )

Filters feedback messages displayed during the core update process.

do_action( ‘upgrader_process_complete’, WP_Upgrader $upgrader, array $hook_extra )

Fires when the upgrader process is complete.

Changelog

VersionDescription
2.8.0Introduced.

User Contributed Notes

You must log in before being able to contribute a note or feedback.