Changeset 55720 for trunk/src/wp-admin/includes/class-wp-upgrader.php
- Timestamp:
- 05/04/2023 02:34:58 AM (12 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-admin/includes/class-wp-upgrader.php
r55258 r55720 114 114 115 115 /** 116 * Stores the list of plugins or themes added to temporary backup directory. 117 * 118 * Used by the rollback functions. 119 * 120 * @since 6.3.0 121 * @var array 122 */ 123 private $temp_backups = array(); 124 125 /** 126 * Stores the list of plugins or themes to be restored from temporary backup directory. 127 * 128 * Used by the rollback functions. 129 * 130 * @since 6.3.0 131 * @var array 132 */ 133 private $temp_restores = array(); 134 135 /** 116 136 * Construct the upgrader with a skin. 117 137 * … … 135 155 * and also add the generic strings to `WP_Upgrader::$strings`. 136 156 * 157 * Additionally, it will schedule a weekly task to clean up the temporary backup directory. 158 * 137 159 * @since 2.8.0 160 * @since 6.3.0 Added the `schedule_temp_backup_cleanup()` task. 138 161 */ 139 162 public function init() { 140 163 $this->skin->set_upgrader( $this ); 141 164 $this->generic_strings(); 165 166 if ( ! wp_installing() ) { 167 $this->schedule_temp_backup_cleanup(); 168 } 169 } 170 171 /** 172 * Schedules the cleanup of the temporary backup directory. 173 * 174 * @since 6.3.0 175 */ 176 protected function schedule_temp_backup_cleanup() { 177 if ( false === wp_next_scheduled( 'wp_delete_temp_updater_backups' ) ) { 178 wp_schedule_event( time(), 'weekly', 'wp_delete_temp_updater_backups' ); 179 } 142 180 } 143 181 … … 168 206 $this->strings['maintenance_start'] = __( 'Enabling Maintenance mode…' ); 169 207 $this->strings['maintenance_end'] = __( 'Disabling Maintenance mode…' ); 208 209 /* translators: %s: upgrade-temp-backup */ 210 $this->strings['temp_backup_mkdir_failed'] = sprintf( __( 'Could not create the %s directory.' ), 'upgrade-temp-backup' ); 211 /* translators: %s: upgrade-temp-backup */ 212 $this->strings['temp_backup_move_failed'] = sprintf( __( 'Could not move the old version to the %s directory.' ), 'upgrade-temp-backup' ); 213 /* translators: %s: The plugin or theme slug. */ 214 $this->strings['temp_backup_restore_failed'] = __( 'Could not restore the original version of %s.' ); 215 /* translators: %s: The plugin or theme slug. */ 216 $this->strings['temp_backup_delete_failed'] = __( 'Could not delete the temporary backup directory for %s.' ); 170 217 } 171 218 … … 309 356 $this->skin->feedback( 'unpack_package' ); 310 357 358 if ( ! $wp_filesystem->wp_content_dir() ) { 359 return new WP_Error( 'fs_no_content_dir', $this->strings['fs_no_content_dir'] ); 360 } 361 311 362 $upgrade_folder = $wp_filesystem->wp_content_dir() . 'upgrade/'; 312 363 … … 533 584 if ( is_wp_error( $source ) ) { 534 585 return $source; 586 } 587 588 if ( ! empty( $args['hook_extra']['temp_backup'] ) ) { 589 $temp_backup = $this->move_to_temp_backup_dir( $args['hook_extra']['temp_backup'] ); 590 591 if ( is_wp_error( $temp_backup ) ) { 592 return $temp_backup; 593 } 594 595 $this->temp_backups[] = $args['hook_extra']['temp_backup']; 535 596 } 536 597 … … 615 676 } 616 677 617 // Clear the working folder?678 // Clear the working directory? 618 679 if ( $args['clear_working'] ) { 619 680 $wp_filesystem->delete( $remote_source, true ); … … 828 889 829 890 $this->skin->set_result( $result ); 891 830 892 if ( is_wp_error( $result ) ) { 893 if ( ! empty( $options['hook_extra']['temp_backup'] ) ) { 894 $this->temp_restores[] = $options['hook_extra']['temp_backup']; 895 896 /* 897 * Restore the backup on shutdown. 898 * Actions running on `shutdown` are immune to PHP timeouts, 899 * so in case the failure was due to a PHP timeout, 900 * it will still be able to properly restore the previous version. 901 */ 902 add_action( 'shutdown', array( $this, 'restore_temp_backup' ) ); 903 } 831 904 $this->skin->error( $result ); 832 905 … … 840 913 841 914 $this->skin->after(); 915 916 // Clean up the backup kept in the temporary backup directory. 917 if ( ! empty( $options['hook_extra']['temp_backup'] ) ) { 918 // Delete the backup on `shutdown` to avoid a PHP timeout. 919 add_action( 'shutdown', array( $this, 'delete_temp_backup' ), 100, 0 ); 920 } 842 921 843 922 if ( ! $options['is_multi'] ) { … … 967 1046 return delete_option( $lock_name . '.lock' ); 968 1047 } 1048 1049 /** 1050 * Moves the plugin or theme being updated into a temporary backup directory. 1051 * 1052 * @since 6.3.0 1053 * 1054 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. 1055 * 1056 * @param string[] $args { 1057 * Array of data for the temporary backup. 1058 * 1059 * @type string $slug Plugin or theme slug. 1060 * @type string $src Path to the root directory for plugins or themes. 1061 * @type string $dir Destination subdirectory name. Accepts 'plugins' or 'themes'. 1062 * } 1063 * 1064 * @return bool|WP_Error True on success, false on early exit, otherwise WP_Error. 1065 */ 1066 public function move_to_temp_backup_dir( $args ) { 1067 global $wp_filesystem; 1068 1069 if ( empty( $args['slug'] ) || empty( $args['src'] ) || empty( $args['dir'] ) ) { 1070 return false; 1071 } 1072 1073 /* 1074 * Skip any plugin that has "." as its slug. 1075 * A slug of "." will result in a `$src` value ending in a period. 1076 * 1077 * On Windows, this will cause the 'plugins' folder to be moved, 1078 * and will cause a failure when attempting to call `mkdir()`. 1079 */ 1080 if ( '.' === $args['slug'] ) { 1081 return false; 1082 } 1083 1084 if ( ! $wp_filesystem->wp_content_dir() ) { 1085 return new WP_Error( 'fs_no_content_dir', $this->strings['fs_no_content_dir'] ); 1086 } 1087 1088 $dest_dir = $wp_filesystem->wp_content_dir() . 'upgrade-temp-backup/'; 1089 $sub_dir = $dest_dir . $args['dir'] . '/'; 1090 1091 // Create the temporary backup directory if it does not exist. 1092 if ( ! $wp_filesystem->is_dir( $sub_dir ) ) { 1093 if ( ! $wp_filesystem->is_dir( $dest_dir ) ) { 1094 $wp_filesystem->mkdir( $dest_dir, FS_CHMOD_DIR ); 1095 } 1096 1097 if ( ! $wp_filesystem->mkdir( $sub_dir, FS_CHMOD_DIR ) ) { 1098 // Could not create the backup directory. 1099 return new WP_Error( 'fs_temp_backup_mkdir', $this->strings['temp_backup_mkdir_failed'] ); 1100 } 1101 } 1102 1103 $src_dir = $wp_filesystem->find_folder( $args['src'] ); 1104 $src = trailingslashit( $src_dir ) . $args['slug']; 1105 $dest = $dest_dir . trailingslashit( $args['dir'] ) . $args['slug']; 1106 1107 // Delete the temporary backup directory if it already exists. 1108 if ( $wp_filesystem->is_dir( $dest ) ) { 1109 $wp_filesystem->delete( $dest, true ); 1110 } 1111 1112 // Move to the temporary backup directory. 1113 $result = move_dir( $src, $dest, true ); 1114 if ( is_wp_error( $result ) ) { 1115 return new WP_Error( 'fs_temp_backup_move', $this->strings['temp_backup_move_failed'] ); 1116 } 1117 1118 return true; 1119 } 1120 1121 /** 1122 * Restores the plugin or theme from temporary backup. 1123 * 1124 * @since 6.3.0 1125 * 1126 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. 1127 * 1128 * @return bool|WP_Error True on success, false on early exit, otherwise WP_Error. 1129 */ 1130 public function restore_temp_backup() { 1131 global $wp_filesystem; 1132 1133 $errors = new WP_Error(); 1134 1135 foreach ( $this->temp_restores as $args ) { 1136 if ( empty( $args['slug'] ) || empty( $args['src'] ) || empty( $args['dir'] ) ) { 1137 return false; 1138 } 1139 1140 if ( ! $wp_filesystem->wp_content_dir() ) { 1141 $errors->add( 'fs_no_content_dir', $this->strings['fs_no_content_dir'] ); 1142 return $errors; 1143 } 1144 1145 $src = $wp_filesystem->wp_content_dir() . 'upgrade-temp-backup/' . $args['dir'] . '/' . $args['slug']; 1146 $dest_dir = $wp_filesystem->find_folder( $args['src'] ); 1147 $dest = trailingslashit( $dest_dir ) . $args['slug']; 1148 1149 if ( $wp_filesystem->is_dir( $src ) ) { 1150 // Cleanup. 1151 if ( $wp_filesystem->is_dir( $dest ) && ! $wp_filesystem->delete( $dest, true ) ) { 1152 $errors->add( 1153 'fs_temp_backup_delete', 1154 sprintf( $this->strings['temp_backup_restore_failed'], $args['slug'] ) 1155 ); 1156 continue; 1157 } 1158 1159 // Move it. 1160 $result = move_dir( $src, $dest, true ); 1161 if ( is_wp_error( $result ) ) { 1162 $errors->add( 1163 'fs_temp_backup_delete', 1164 sprintf( $this->strings['temp_backup_restore_failed'], $args['slug'] ) 1165 ); 1166 continue; 1167 } 1168 } 1169 } 1170 1171 return $errors->has_errors() ? $errors : true; 1172 } 1173 1174 /** 1175 * Deletes a temporary backup. 1176 * 1177 * @since 6.3.0 1178 * 1179 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. 1180 * 1181 * @return bool|WP_Error True on success, false on early exit, otherwise WP_Error. 1182 */ 1183 public function delete_temp_backup() { 1184 global $wp_filesystem; 1185 1186 $errors = new WP_Error(); 1187 1188 foreach ( $this->temp_backups as $args ) { 1189 if ( empty( $args['slug'] ) || empty( $args['dir'] ) ) { 1190 return false; 1191 } 1192 1193 if ( ! $wp_filesystem->wp_content_dir() ) { 1194 $errors->add( 'fs_no_content_dir', $this->strings['fs_no_content_dir'] ); 1195 return $errors; 1196 } 1197 1198 $temp_backup_dir = $wp_filesystem->wp_content_dir() . "upgrade-temp-backup/{$args['dir']}/{$args['slug']}"; 1199 1200 if ( ! $wp_filesystem->delete( $temp_backup_dir, true ) ) { 1201 $errors->add( 1202 'temp_backup_delete_failed', 1203 sprintf( $this->strings['temp_backup_delete_failed'] ), 1204 $args['slug'] 1205 ); 1206 continue; 1207 } 1208 } 1209 1210 return $errors->has_errors() ? $errors : true; 1211 } 969 1212 } 970 1213
Note: See TracChangeset
for help on using the changeset viewer.