summaryrefslogtreecommitdiffstats
path: root/wp-admin/includes/class-wp-upgrader.php
diff options
context:
space:
mode:
Diffstat (limited to 'wp-admin/includes/class-wp-upgrader.php')
-rw-r--r--wp-admin/includes/class-wp-upgrader.php71
1 files changed, 61 insertions, 10 deletions
diff --git a/wp-admin/includes/class-wp-upgrader.php b/wp-admin/includes/class-wp-upgrader.php
index 1fbfa99..9474ce0 100644
--- a/wp-admin/includes/class-wp-upgrader.php
+++ b/wp-admin/includes/class-wp-upgrader.php
@@ -196,6 +196,7 @@ class WP_Upgrader {
/* translators: %s: Directory name. */
$this->strings['fs_no_folder'] = __( 'Unable to locate needed folder (%s).' );
+ $this->strings['no_package'] = __( 'Package not available.' );
$this->strings['download_failed'] = __( 'Download failed.' );
$this->strings['installing_package'] = __( 'Installing the latest version…' );
$this->strings['no_files'] = __( 'The package contains no files.' );
@@ -527,7 +528,10 @@ class WP_Upgrader {
set_time_limit( 300 );
}
- if ( empty( $source ) || empty( $destination ) ) {
+ if (
+ ( ! is_string( $source ) || '' === $source || trim( $source ) !== $source ) ||
+ ( ! is_string( $destination ) || '' === $destination || trim( $destination ) !== $destination )
+ ) {
return new WP_Error( 'bad_request', $this->strings['bad_request'] );
}
$this->skin->feedback( 'installing_package' );
@@ -824,7 +828,7 @@ class WP_Upgrader {
* Download the package. Note: If the package is the full path
* to an existing local file, it will be returned untouched.
*/
- $download = $this->download_package( $options['package'], true, $options['hook_extra'] );
+ $download = $this->download_package( $options['package'], false, $options['hook_extra'] );
/*
* Allow for signature soft-fail.
@@ -897,6 +901,7 @@ class WP_Upgrader {
$this->skin->set_result( $result );
if ( is_wp_error( $result ) ) {
+ // An automatic plugin update will have already performed its rollback.
if ( ! empty( $options['hook_extra']['temp_backup'] ) ) {
$this->temp_restores[] = $options['hook_extra']['temp_backup'];
@@ -905,8 +910,12 @@ class WP_Upgrader {
* Actions running on `shutdown` are immune to PHP timeouts,
* so in case the failure was due to a PHP timeout,
* it will still be able to properly restore the previous version.
+ *
+ * Zero arguments are accepted as a string can sometimes be passed
+ * internally during actions, causing an error because
+ * `WP_Upgrader::restore_temp_backup()` expects an array.
*/
- add_action( 'shutdown', array( $this, 'restore_temp_backup' ) );
+ add_action( 'shutdown', array( $this, 'restore_temp_backup' ), 10, 0 );
}
$this->skin->error( $result );
@@ -979,15 +988,25 @@ class WP_Upgrader {
*/
public function maintenance_mode( $enable = false ) {
global $wp_filesystem;
+
+ if ( ! $wp_filesystem ) {
+ require_once ABSPATH . 'wp-admin/includes/file.php';
+ WP_Filesystem();
+ }
+
$file = $wp_filesystem->abspath() . '.maintenance';
if ( $enable ) {
- $this->skin->feedback( 'maintenance_start' );
+ if ( ! wp_doing_cron() ) {
+ $this->skin->feedback( 'maintenance_start' );
+ }
// Create maintenance file to signal that we are upgrading.
$maintenance_string = '<?php $upgrading = ' . time() . '; ?>';
$wp_filesystem->delete( $file );
$wp_filesystem->put_contents( $file, $maintenance_string, FS_CHMOD_FILE );
} elseif ( ! $enable && $wp_filesystem->exists( $file ) ) {
- $this->skin->feedback( 'maintenance_end' );
+ if ( ! wp_doing_cron() ) {
+ $this->skin->feedback( 'maintenance_end' );
+ }
$wp_filesystem->delete( $file );
}
}
@@ -1012,7 +1031,7 @@ class WP_Upgrader {
$lock_option = $lock_name . '.lock';
// Try to lock.
- $lock_result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO `$wpdb->options` ( `option_name`, `option_value`, `autoload` ) VALUES (%s, %s, 'no') /* LOCK */", $lock_option, time() ) );
+ $lock_result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO `$wpdb->options` ( `option_name`, `option_value`, `autoload` ) VALUES (%s, %s, 'off') /* LOCK */", $lock_option, time() ) );
if ( ! $lock_result ) {
$lock_result = get_option( $lock_option );
@@ -1129,17 +1148,33 @@ class WP_Upgrader {
* Restores the plugin or theme from temporary backup.
*
* @since 6.3.0
+ * @since 6.6.0 Added the `$temp_backups` parameter.
*
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
*
+ * @param array[] $temp_backups {
+ * Optional. An array of temporary backups.
+ *
+ * @type array ...$0 {
+ * Information about the backup.
+ *
+ * @type string $dir The temporary backup location in the upgrade-temp-backup directory.
+ * @type string $slug The item's slug.
+ * @type string $src The directory where the original is stored. For example, `WP_PLUGIN_DIR`.
+ * }
+ * }
* @return bool|WP_Error True on success, false on early exit, otherwise WP_Error.
*/
- public function restore_temp_backup() {
+ public function restore_temp_backup( array $temp_backups = array() ) {
global $wp_filesystem;
$errors = new WP_Error();
- foreach ( $this->temp_restores as $args ) {
+ if ( empty( $temp_backups ) ) {
+ $temp_backups = $this->temp_restores;
+ }
+
+ foreach ( $temp_backups as $args ) {
if ( empty( $args['slug'] ) || empty( $args['src'] ) || empty( $args['dir'] ) ) {
return false;
}
@@ -1182,17 +1217,33 @@ class WP_Upgrader {
* Deletes a temporary backup.
*
* @since 6.3.0
+ * @since 6.6.0 Added the `$temp_backups` parameter.
*
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
*
+ * @param array[] $temp_backups {
+ * Optional. An array of temporary backups.
+ *
+ * @type array ...$0 {
+ * Information about the backup.
+ *
+ * @type string $dir The temporary backup location in the upgrade-temp-backup directory.
+ * @type string $slug The item's slug.
+ * @type string $src The directory where the original is stored. For example, `WP_PLUGIN_DIR`.
+ * }
+ * }
* @return bool|WP_Error True on success, false on early exit, otherwise WP_Error.
*/
- public function delete_temp_backup() {
+ public function delete_temp_backup( array $temp_backups = array() ) {
global $wp_filesystem;
$errors = new WP_Error();
- foreach ( $this->temp_backups as $args ) {
+ if ( empty( $temp_backups ) ) {
+ $temp_backups = $this->temp_backups;
+ }
+
+ foreach ( $temp_backups as $args ) {
if ( empty( $args['slug'] ) || empty( $args['dir'] ) ) {
return false;
}