diff -r 34716fd837a4 -r be944660c56a wp/wp-admin/includes/class-wp-automatic-updater.php --- a/wp/wp-admin/includes/class-wp-automatic-updater.php Tue Dec 15 15:52:01 2020 +0100 +++ b/wp/wp-admin/includes/class-wp-automatic-updater.php Wed Sep 21 18:19:35 2022 +0200 @@ -62,7 +62,7 @@ * filesystem to the top of the drive, erring on the side of detecting a VCS * checkout somewhere. * - * ABSPATH is always checked in addition to whatever $context is (which may be the + * ABSPATH is always checked in addition to whatever `$context` is (which may be the * wp-content directory, for example). The underlying assumption is that if you are * using version control *anywhere*, then you should be making decisions for * how things get updated. @@ -70,6 +70,8 @@ * @since 3.7.0 * * @param string $context The filesystem path to check, in addition to ABSPATH. + * @return bool True if a VCS checkout was discovered at `$context` or ABSPATH, + * or anywhere higher. False otherwise. */ public function is_vcs_checkout( $context ) { $context_dirs = array( untrailingslashit( $context ) ); @@ -112,7 +114,7 @@ * * @since 3.7.0 * - * @param bool $checkout Whether a VCS checkout was discovered at $context + * @param bool $checkout Whether a VCS checkout was discovered at `$context` * or ABSPATH, or anywhere higher. * @param string $context The filesystem context (a path) against which * filesystem status should be checked. @@ -132,6 +134,7 @@ * @param object $item The update offer. * @param string $context The filesystem context (a path) against which filesystem * access and status should be checked. + * @return bool True if the item should be updated, false otherwise. */ public function should_update( $type, $item, $context ) { // Used to see if WP_Filesystem is set up to allow unattended updates. @@ -148,7 +151,9 @@ } // If we can't do an auto core update, we may still be able to email the user. - if ( ! $skin->request_filesystem_credentials( false, $context, $allow_relaxed_file_ownership ) || $this->is_vcs_checkout( $context ) ) { + if ( ! $skin->request_filesystem_credentials( false, $context, $allow_relaxed_file_ownership ) + || $this->is_vcs_checkout( $context ) + ) { if ( 'core' === $type ) { $this->send_core_update_notification_email( $item ); } @@ -179,7 +184,9 @@ * Filters whether to automatically update core, a plugin, a theme, or a language. * * The dynamic portion of the hook name, `$type`, refers to the type of update - * being checked. Potential hook names include: + * being checked. + * + * Possible hook names include: * * - `auto_update_core` * - `auto_update_plugin` @@ -242,12 +249,17 @@ * @since 3.7.0 * * @param object $item The update offer. + * @return bool True if the site administrator is notified of a core update, + * false otherwise. */ protected function send_core_update_notification_email( $item ) { $notified = get_site_option( 'auto_core_update_notified' ); // Don't notify if we've already notified the same email address of the same version. - if ( $notified && get_site_option( 'admin_email' ) === $notified['email'] && $notified['version'] == $item->current ) { + if ( $notified + && get_site_option( 'admin_email' ) === $notified['email'] + && $notified['version'] === $item->current + ) { return false; } @@ -343,6 +355,11 @@ $upgrader_item = $item->theme; $theme = wp_get_theme( $upgrader_item ); $item_name = $theme->Get( 'Name' ); + // Add the current version so that it can be reported in the notification email. + $item->current_version = $theme->get( 'Version' ); + if ( empty( $item->current_version ) ) { + $item->current_version = false; + } /* translators: %s: Theme name. */ $skin->feedback( __( 'Updating theme: %s' ), $item_name ); break; @@ -350,6 +367,11 @@ $upgrader_item = $item->plugin; $plugin_data = get_plugin_data( $context . '/' . $upgrader_item ); $item_name = $plugin_data['Name']; + // Add the current version so that it can be reported in the notification email. + $item->current_version = $plugin_data['Version']; + if ( empty( $item->current_version ) ) { + $item->current_version = false; + } /* translators: %s: Plugin name. */ $skin->feedback( __( 'Updating plugin: %s' ), $item_name ); break; @@ -607,9 +629,14 @@ $send = false; } - $n = get_site_option( 'auto_core_update_notified' ); + $notified = get_site_option( 'auto_core_update_notified' ); + // Don't notify if we've already notified the same email address of the same version of the same notification type. - if ( $n && 'fail' === $n['type'] && get_site_option( 'admin_email' ) === $n['email'] && $n['version'] == $core_update->current ) { + if ( $notified + && 'fail' === $notified['type'] + && get_site_option( 'admin_email' ) === $notified['email'] + && $notified['version'] === $core_update->current + ) { $send = false; } @@ -657,7 +684,13 @@ $next_user_core_update = $core_update; } - $newer_version_available = ( 'upgrade' === $next_user_core_update->response && version_compare( $next_user_core_update->version, $core_update->version, '>' ) ); + if ( 'upgrade' === $next_user_core_update->response + && version_compare( $next_user_core_update->version, $core_update->version, '>' ) + ) { + $newer_version_available = true; + } else { + $newer_version_available = false; + } /** * Filters whether to send an email following an automatic background core update. @@ -887,44 +920,48 @@ $successful_updates = array(); $failed_updates = array(); - /** - * Filters whether to send an email following an automatic background plugin update. - * - * @since 5.5.0 - * @since 5.5.1 Added the $update_results parameter. - * - * @param bool $enabled True if plugins notifications are enabled, false otherwise. - * @param array $update_results The results of plugins update tasks. - */ - $notifications_enabled = apply_filters( 'auto_plugin_update_send_email', true, $update_results['plugin'] ); + if ( ! empty( $update_results['plugin'] ) ) { + /** + * Filters whether to send an email following an automatic background plugin update. + * + * @since 5.5.0 + * @since 5.5.1 Added the `$update_results` parameter. + * + * @param bool $enabled True if plugin update notifications are enabled, false otherwise. + * @param array $update_results The results of plugins update tasks. + */ + $notifications_enabled = apply_filters( 'auto_plugin_update_send_email', true, $update_results['plugin'] ); - if ( ! empty( $update_results['plugin'] ) && $notifications_enabled ) { - foreach ( $update_results['plugin'] as $update_result ) { - if ( true === $update_result->result ) { - $successful_updates['plugin'][] = $update_result; - } else { - $failed_updates['plugin'][] = $update_result; + if ( $notifications_enabled ) { + foreach ( $update_results['plugin'] as $update_result ) { + if ( true === $update_result->result ) { + $successful_updates['plugin'][] = $update_result; + } else { + $failed_updates['plugin'][] = $update_result; + } } } } - /** - * Filters whether to send an email following an automatic background theme update. - * - * @since 5.5.0 - * @since 5.5.1 Added the $update_results parameter. - * - * @param bool $enabled True if notifications are enabled, false otherwise. - * @param array $update_results The results of theme update tasks. - */ - $notifications_enabled = apply_filters( 'auto_theme_update_send_email', true, $update_results['theme'] ); + if ( ! empty( $update_results['theme'] ) ) { + /** + * Filters whether to send an email following an automatic background theme update. + * + * @since 5.5.0 + * @since 5.5.1 Added the `$update_results` parameter. + * + * @param bool $enabled True if theme update notifications are enabled, false otherwise. + * @param array $update_results The results of theme update tasks. + */ + $notifications_enabled = apply_filters( 'auto_theme_update_send_email', true, $update_results['theme'] ); - if ( ! empty( $update_results['theme'] ) && $notifications_enabled ) { - foreach ( $update_results['theme'] as $update_result ) { - if ( true === $update_result->result ) { - $successful_updates['theme'][] = $update_result; - } else { - $failed_updates['theme'][] = $update_result; + if ( $notifications_enabled ) { + foreach ( $update_results['theme'] as $update_result ) { + if ( true === $update_result->result ) { + $successful_updates['theme'][] = $update_result; + } else { + $failed_updates['theme'][] = $update_result; + } } } } @@ -1061,12 +1098,22 @@ $body[] = __( 'These plugins failed to update:' ); foreach ( $failed_updates['plugin'] as $item ) { - $body[] = sprintf( - /* translators: 1: Plugin name, 2: Version number. */ - __( '- %1$s version %2$s' ), - $item->name, - $item->item->new_version - ); + if ( $item->item->current_version ) { + $body[] = sprintf( + /* translators: 1: Plugin name, 2: Current version number, 3: New version number. */ + __( '- %1$s (from version %2$s to %3$s)' ), + $item->name, + $item->item->current_version, + $item->item->new_version + ); + } else { + $body[] = sprintf( + /* translators: 1: Plugin name, 2: Version number. */ + __( '- %1$s version %2$s' ), + $item->name, + $item->item->new_version + ); + } $past_failure_emails[ $item->item->plugin ] = $item->item->new_version; } @@ -1079,12 +1126,22 @@ $body[] = __( 'These themes failed to update:' ); foreach ( $failed_updates['theme'] as $item ) { - $body[] = sprintf( - /* translators: 1: Theme name, 2: Version number. */ - __( '- %1$s version %2$s' ), - $item->name, - $item->item->new_version - ); + if ( $item->item->current_version ) { + $body[] = sprintf( + /* translators: 1: Theme name, 2: Current version number, 3: New version number. */ + __( '- %1$s (from version %2$s to %3$s)' ), + $item->name, + $item->item->current_version, + $item->item->new_version + ); + } else { + $body[] = sprintf( + /* translators: 1: Theme name, 2: Version number. */ + __( '- %1$s version %2$s' ), + $item->name, + $item->item->new_version + ); + } $past_failure_emails[ $item->item->theme ] = $item->item->new_version; } @@ -1102,12 +1159,22 @@ $body[] = __( 'These plugins are now up to date:' ); foreach ( $successful_updates['plugin'] as $item ) { - $body[] = sprintf( - /* translators: 1: Plugin name, 2: Version number. */ - __( '- %1$s version %2$s' ), - $item->name, - $item->item->new_version - ); + if ( $item->item->current_version ) { + $body[] = sprintf( + /* translators: 1: Plugin name, 2: Current version number, 3: New version number. */ + __( '- %1$s (from version %2$s to %3$s)' ), + $item->name, + $item->item->current_version, + $item->item->new_version + ); + } else { + $body[] = sprintf( + /* translators: 1: Plugin name, 2: Version number. */ + __( '- %1$s version %2$s' ), + $item->name, + $item->item->new_version + ); + } unset( $past_failure_emails[ $item->item->plugin ] ); } @@ -1120,12 +1187,22 @@ $body[] = __( 'These themes are now up to date:' ); foreach ( $successful_updates['theme'] as $item ) { - $body[] = sprintf( - /* translators: 1: Theme name, 2: Version number. */ - __( '- %1$s version %2$s' ), - $item->name, - $item->item->new_version - ); + if ( $item->item->current_version ) { + $body[] = sprintf( + /* translators: 1: Theme name, 2: Current version number, 3: New version number. */ + __( '- %1$s (from version %2$s to %3$s)' ), + $item->name, + $item->item->current_version, + $item->item->new_version + ); + } else { + $body[] = sprintf( + /* translators: 1: Theme name, 2: Version number. */ + __( '- %1$s version %2$s' ), + $item->name, + $item->item->new_version + ); + } unset( $past_failure_emails[ $item->item->theme ] ); } @@ -1211,6 +1288,7 @@ // Core. if ( isset( $this->update_results['core'] ) ) { $result = $this->update_results['core'][0]; + if ( $result->result && ! is_wp_error( $result->result ) ) { /* translators: %s: WordPress version. */ $body[] = sprintf( __( 'SUCCESS: WordPress was successfully updated to %s' ), $result->name ); @@ -1219,6 +1297,7 @@ $body[] = sprintf( __( 'FAILED: WordPress failed to update to %s' ), $result->name ); $failures++; } + $body[] = ''; } @@ -1227,7 +1306,9 @@ if ( ! isset( $this->update_results[ $type ] ) ) { continue; } + $success_items = wp_list_filter( $this->update_results[ $type ], array( 'result' => true ) ); + if ( $success_items ) { $messages = array( 'plugin' => __( 'The following plugins were successfully updated:' ), @@ -1241,7 +1322,8 @@ $body[] = ' * ' . sprintf( __( 'SUCCESS: %s' ), $name ); } } - if ( $success_items != $this->update_results[ $type ] ) { + + if ( $success_items !== $this->update_results[ $type ] ) { // Failed updates. $messages = array( 'plugin' => __( 'The following plugins failed to update:' ), @@ -1250,6 +1332,7 @@ ); $body[] = $messages[ $type ]; + foreach ( $this->update_results[ $type ] as $item ) { if ( ! $item->result || is_wp_error( $item->result ) ) { /* translators: %s: Name of plugin / theme / translation. */ @@ -1258,10 +1341,12 @@ } } } + $body[] = ''; } $site_title = wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ); + if ( $failures ) { $body[] = trim( __( @@ -1298,18 +1383,23 @@ if ( ! isset( $this->update_results[ $type ] ) ) { continue; } + foreach ( $this->update_results[ $type ] as $update ) { $body[] = $update->name; $body[] = str_repeat( '-', strlen( $update->name ) ); + foreach ( $update->messages as $message ) { $body[] = ' ' . html_entity_decode( str_replace( '…', '...', $message ) ); } + if ( is_wp_error( $update->result ) ) { $results = array( 'update' => $update->result ); + // If we rolled back, we want to know an error that occurred then too. if ( 'rollback_was_required' === $update->result->get_error_code() ) { $results = (array) $update->result->get_error_data(); } + foreach ( $results as $result_type => $result ) { if ( ! is_wp_error( $result ) ) { continue; @@ -1328,6 +1418,7 @@ } } } + $body[] = ''; } }