Make WordPress Core


Ignore:
Timestamp:
05/04/2023 02:34:58 AM (3 years ago)
Author:
SergeyBiryukov
Message:

Upgrade/Install: Create a temporary backup of plugins and themes before updating.

This aims to make the update process more reliable and ensures that if a plugin or theme update fails, the previous version can be safely restored.

  • When updating a plugin or theme, the old version is moved to a temporary backup directory:
    • wp-content/upgrade-temp-backup/plugins/[plugin-slug] for plugins
    • wp-content/upgrade-temp-backup/themes/[theme-slug] for themes.
  • If the update fails, then the backup kept in the temporary backup directory is restored to its original location.
  • If the update succeeds, the temporary backup is deleted.

To further help troubleshoot plugin and theme updates, two new checks were added to the Site Health screen:

  • A check to make sure that the upgrade-temp-backup directory is writable.
  • A check that there is enough disk space available to safely perform updates.

To avoid confusion: The temporary backup directory will NOT be used to “roll back” a plugin to a previous version after a completed update. This directory will simply contain a transient backup of the previous version of a plugin or theme being updated, and as soon as the update process finishes, the directory will be empty.

Follow-up to [55204], [55220].

Props afragen, costdev, pbiron, azaozz, hellofromTonya, aristath, peterwilsoncc, TJNowell, bronsonquick, Clorith, dd32, poena, TimothyBlynJacobs, audrasjb, mikeschroder, a2hosting, KZeni, galbaras, richards1052, Boniu91, mai21, francina, TobiasBg, desrosj, noisysocks, johnbillion, dlh, chaion07, davidbaumwald, jrf, thisisyeasin, ignatggeorgiev, SergeyBiryukov.
Fixes #51857.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/update.php

    r55641 r55720  
    10781078}
    10791079
     1080/**
     1081 * Schedules the removal of all contents in the temporary backup directory.
     1082 *
     1083 * @since 6.3.0
     1084 */
     1085function wp_delete_all_temp_backups() {
     1086    /*
     1087     * Check if there is a lock, or if currently performing an Ajax request,
     1088     * in which case there is a chance an update is running.
     1089     * Reschedule for an hour from now and exit early.
     1090     */
     1091    if ( get_option( 'core_updater.lock' ) || get_option( 'auto_updater.lock' ) || wp_doing_ajax() ) {
     1092        wp_schedule_single_event( time() + HOUR_IN_SECONDS, 'wp_delete_temp_updater_backups' );
     1093        return;
     1094    }
     1095
     1096    // This action runs on shutdown to make sure there are no plugin updates currently running.
     1097    add_action( 'shutdown', '_wp_delete_all_temp_backups' );
     1098}
     1099
     1100/**
     1101 * Deletes all contents in the temporary backup directory.
     1102 *
     1103 * @since 6.3.0
     1104 *
     1105 * @access private
     1106 *
     1107 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
     1108 *
     1109 * @return void|WP_Error Void on success, or a WP_Error object on failure.
     1110 */
     1111function _wp_delete_all_temp_backups() {
     1112    global $wp_filesystem;
     1113
     1114    if ( ! $wp_filesystem ) {
     1115        require_once ABSPATH . '/wp-admin/includes/file.php';
     1116        WP_Filesystem();
     1117    }
     1118
     1119    if ( ! $wp_filesystem->wp_content_dir() ) {
     1120        return new WP_Error( 'fs_no_content_dir', __( 'Unable to locate WordPress content directory (wp-content).' ) );
     1121    }
     1122
     1123    $temp_backup_dir = $wp_filesystem->wp_content_dir() . 'upgrade-temp-backup/';
     1124    $dirlist         = $wp_filesystem->dirlist( $temp_backup_dir );
     1125    $dirlist         = $dirlist ? $dirlist : array();
     1126
     1127    foreach ( array_keys( $dirlist ) as $dir ) {
     1128        if ( '.' === $dir || '..' === $dir ) {
     1129            continue;
     1130        }
     1131
     1132        $wp_filesystem->delete( $temp_backup_dir . $dir, true );
     1133    }
     1134}
     1135
    10801136if ( ( ! is_main_site() && ! is_network_admin() ) || wp_doing_ajax() ) {
    10811137    return;
     
    11021158
    11031159add_action( 'init', 'wp_schedule_update_checks' );
     1160
     1161add_action( 'wp_delete_temp_updater_backups', 'wp_delete_all_temp_backups' );
Note: See TracChangeset for help on using the changeset viewer.