wp/wp-admin/includes/class-theme-upgrader.php
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
child 22 8c2e4d02f4ef
--- a/wp/wp-admin/includes/class-theme-upgrader.php	Thu Sep 29 08:06:27 2022 +0200
+++ b/wp/wp-admin/includes/class-theme-upgrader.php	Fri Sep 05 18:40:08 2025 +0200
@@ -48,7 +48,7 @@
 	public $new_theme_data = array();
 
 	/**
-	 * Initialize the upgrade strings.
+	 * Initializes the upgrade strings.
 	 *
 	 * @since 2.8.0
 	 */
@@ -56,7 +56,7 @@
 		$this->strings['up_to_date'] = __( 'The theme is at the latest version.' );
 		$this->strings['no_package'] = __( 'Update package not available.' );
 		/* translators: %s: Package URL. */
-		$this->strings['downloading_package'] = sprintf( __( 'Downloading update from %s&#8230;' ), '<span class="code">%s</span>' );
+		$this->strings['downloading_package'] = sprintf( __( 'Downloading update from %s&#8230;' ), '<span class="code pre">%s</span>' );
 		$this->strings['unpack_package']      = __( 'Unpacking the update&#8230;' );
 		$this->strings['remove_old']          = __( 'Removing the old version of the theme&#8230;' );
 		$this->strings['remove_old_failed']   = __( 'Could not remove the old theme.' );
@@ -65,14 +65,14 @@
 	}
 
 	/**
-	 * Initialize the installation strings.
+	 * Initializes the installation strings.
 	 *
 	 * @since 2.8.0
 	 */
 	public function install_strings() {
 		$this->strings['no_package'] = __( 'Installation package not available.' );
 		/* translators: %s: Package URL. */
-		$this->strings['downloading_package'] = sprintf( __( 'Downloading installation package from %s&#8230;' ), '<span class="code">%s</span>' );
+		$this->strings['downloading_package'] = sprintf( __( 'Downloading installation package from %s&#8230;' ), '<span class="code pre">%s</span>' );
 		$this->strings['unpack_package']      = __( 'Unpacking the package&#8230;' );
 		$this->strings['installing_package']  = __( 'Installing the theme&#8230;' );
 		$this->strings['remove_old']          = __( 'Removing the old version of the theme&#8230;' );
@@ -110,7 +110,7 @@
 	}
 
 	/**
-	 * Check if a child theme is being installed and we need to install its parent.
+	 * Checks if a child theme is being installed and its parent also needs to be installed.
 	 *
 	 * Hooked to the {@see 'upgrader_post_install'} filter by Theme_Upgrader::install().
 	 *
@@ -278,7 +278,7 @@
 	}
 
 	/**
-	 * Upgrade a theme.
+	 * Upgrades a theme.
 	 *
 	 * @since 2.8.0
 	 * @since 3.7.0 The `$args` parameter was added, making clearing the update cache optional.
@@ -328,9 +328,14 @@
 				'clear_destination' => true,
 				'clear_working'     => true,
 				'hook_extra'        => array(
-					'theme'  => $theme,
-					'type'   => 'theme',
-					'action' => 'update',
+					'theme'       => $theme,
+					'type'        => 'theme',
+					'action'      => 'update',
+					'temp_backup' => array(
+						'slug' => $theme,
+						'src'  => get_theme_root( $theme ),
+						'dir'  => 'themes',
+					),
 				),
 			)
 		);
@@ -346,8 +351,10 @@
 
 		wp_clean_themes_cache( $parsed_args['clear_update_cache'] );
 
-		// Ensure any future auto-update failures trigger a failure email by removing
-		// the last failure notification from the list when themes update successfully.
+		/*
+		 * Ensure any future auto-update failures trigger a failure email by removing
+		 * the last failure notification from the list when themes update successfully.
+		 */
 		$past_failure_emails = get_option( 'auto_plugin_theme_update_emails', array() );
 
 		if ( isset( $past_failure_emails[ $theme ] ) ) {
@@ -359,11 +366,13 @@
 	}
 
 	/**
-	 * Upgrade several themes at once.
+	 * Upgrades several themes at once.
 	 *
 	 * @since 3.0.0
 	 * @since 3.7.0 The `$args` parameter was added, making clearing the update cache optional.
 	 *
+	 * @global string $wp_version The WordPress version string.
+	 *
 	 * @param string[] $themes Array of the theme slugs.
 	 * @param array    $args {
 	 *     Optional. Other arguments for upgrading several themes at once. Default empty array.
@@ -374,6 +383,8 @@
 	 * @return array[]|false An array of results, or false if unable to connect to the filesystem.
 	 */
 	public function bulk_upgrade( $themes, $args = array() ) {
+		global $wp_version;
+
 		$defaults    = array(
 			'clear_update_cache' => true,
 		);
@@ -419,7 +430,7 @@
 		$this->update_count   = count( $themes );
 		$this->update_current = 0;
 		foreach ( $themes as $theme ) {
-			$this->update_current++;
+			++$this->update_current;
 
 			$this->skin->theme_info = $this->theme_info( $theme );
 
@@ -435,18 +446,55 @@
 			// Get the URL to the zip file.
 			$r = $current->response[ $theme ];
 
-			$result = $this->run(
-				array(
-					'package'           => $r['package'],
-					'destination'       => get_theme_root( $theme ),
-					'clear_destination' => true,
-					'clear_working'     => true,
-					'is_multi'          => true,
-					'hook_extra'        => array(
-						'theme' => $theme,
-					),
-				)
-			);
+			if ( isset( $r['requires'] ) && ! is_wp_version_compatible( $r['requires'] ) ) {
+				$result = new WP_Error(
+					'incompatible_wp_required_version',
+					sprintf(
+						/* translators: 1: Current WordPress version, 2: WordPress version required by the new theme version. */
+						__( 'Your WordPress version is %1$s, however the new theme version requires %2$s.' ),
+						$wp_version,
+						$r['requires']
+					)
+				);
+
+				$this->skin->before( $result );
+				$this->skin->error( $result );
+				$this->skin->after();
+			} elseif ( isset( $r['requires_php'] ) && ! is_php_version_compatible( $r['requires_php'] ) ) {
+				$result = new WP_Error(
+					'incompatible_php_required_version',
+					sprintf(
+						/* translators: 1: Current PHP version, 2: PHP version required by the new theme version. */
+						__( 'The PHP version on your server is %1$s, however the new theme version requires %2$s.' ),
+						PHP_VERSION,
+						$r['requires_php']
+					)
+				);
+
+				$this->skin->before( $result );
+				$this->skin->error( $result );
+				$this->skin->after();
+			} else {
+				add_filter( 'upgrader_source_selection', array( $this, 'check_package' ) );
+				$result = $this->run(
+					array(
+						'package'           => $r['package'],
+						'destination'       => get_theme_root( $theme ),
+						'clear_destination' => true,
+						'clear_working'     => true,
+						'is_multi'          => true,
+						'hook_extra'        => array(
+							'theme'       => $theme,
+							'temp_backup' => array(
+								'slug' => $theme,
+								'src'  => get_theme_root( $theme ),
+								'dir'  => 'themes',
+							),
+						),
+					)
+				);
+				remove_filter( 'upgrader_source_selection', array( $this, 'check_package' ) );
+			}
 
 			$results[ $theme ] = $result;
 
@@ -477,13 +525,15 @@
 
 		$this->skin->footer();
 
-		// Cleanup our hooks, in case something else does a upgrade on this connection.
+		// Cleanup our hooks, in case something else does an upgrade on this connection.
 		remove_filter( 'upgrader_pre_install', array( $this, 'current_before' ) );
 		remove_filter( 'upgrader_post_install', array( $this, 'current_after' ) );
 		remove_filter( 'upgrader_clear_destination', array( $this, 'delete_old_theme' ) );
 
-		// Ensure any future auto-update failures trigger a failure email by removing
-		// the last failure notification from the list when themes update successfully.
+		/*
+		 * Ensure any future auto-update failures trigger a failure email by removing
+		 * the last failure notification from the list when themes update successfully.
+		 */
 		$past_failure_emails = get_option( 'auto_plugin_theme_update_emails', array() );
 
 		foreach ( $results as $theme => $result ) {
@@ -524,7 +574,7 @@
 
 		// Check that the folder contains a valid theme.
 		$working_directory = str_replace( $wp_filesystem->wp_content_dir(), trailingslashit( WP_CONTENT_DIR ), $source );
-		if ( ! is_dir( $working_directory ) ) { // Sanity check, if the above fails, let's not prevent installation.
+		if ( ! is_dir( $working_directory ) ) { // Confidence check, if the above fails, let's not prevent installation.
 			return $source;
 		}
 
@@ -599,7 +649,7 @@
 			$error = sprintf(
 				/* translators: 1: Current PHP version, 2: Version required by the uploaded theme. */
 				__( 'The PHP version on your server is %1$s, however the uploaded theme requires %2$s.' ),
-				phpversion(),
+				PHP_VERSION,
 				$requires_php
 			);
 
@@ -622,7 +672,7 @@
 	}
 
 	/**
-	 * Turn on maintenance mode before attempting to upgrade the active theme.
+	 * Turns on maintenance mode before attempting to upgrade the active theme.
 	 *
 	 * Hooked to the {@see 'upgrader_pre_install'} filter by Theme_Upgrader::upgrade() and
 	 * Theme_Upgrader::bulk_upgrade().
@@ -654,7 +704,7 @@
 	}
 
 	/**
-	 * Turn off maintenance mode after upgrading the active theme.
+	 * Turns off maintenance mode after upgrading the active theme.
 	 *
 	 * Hooked to the {@see 'upgrader_post_install'} filter by Theme_Upgrader::upgrade()
 	 * and Theme_Upgrader::bulk_upgrade().
@@ -692,7 +742,7 @@
 	}
 
 	/**
-	 * Delete the old theme during an upgrade.
+	 * Deletes the old theme during an upgrade.
 	 *
 	 * Hooked to the {@see 'upgrader_clear_destination'} filter by Theme_Upgrader::upgrade()
 	 * and Theme_Upgrader::bulk_upgrade().
@@ -730,7 +780,7 @@
 	}
 
 	/**
-	 * Get the WP_Theme object for a theme.
+	 * Gets the WP_Theme object for a theme.
 	 *
 	 * @since 2.8.0
 	 * @since 3.0.0 The `$theme` argument was added.
@@ -754,5 +804,4 @@
 
 		return $theme;
 	}
-
 }