WP_Automatic_Updater::send_email()protectedWP 3.7.0

Sends an email upon the completion or failure of a background core update.

Method of the class: WP_Automatic_Updater{}

Return

null. Nothing (null).

Usage

// protected - for code of main (parent) or child class
$result = $this->send_email( $type, $core_update, $result );
$type(string) (required)
The type of email to send. Can be one of 'success', 'fail', 'manual', 'critical'.
$core_update(object) (required)
The update offer that was attempted.
$result(mixed)
The result for the core update. Can be WP_Error.
Default: null

Changelog

Since 3.7.0 Introduced.

WP_Automatic_Updater::send_email() code WP 6.5.2

protected function send_email( $type, $core_update, $result = null ) {
	update_site_option(
		'auto_core_update_notified',
		array(
			'type'      => $type,
			'email'     => get_site_option( 'admin_email' ),
			'version'   => $core_update->current,
			'timestamp' => time(),
		)
	);

	$next_user_core_update = get_preferred_from_update_core();

	// If the update transient is empty, use the update we just performed.
	if ( ! $next_user_core_update ) {
		$next_user_core_update = $core_update;
	}

	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.
	 *
	 * @since 3.7.0
	 *
	 * @param bool   $send        Whether to send the email. Default true.
	 * @param string $type        The type of email to send. Can be one of
	 *                            'success', 'fail', 'critical'.
	 * @param object $core_update The update offer that was attempted.
	 * @param mixed  $result      The result for the core update. Can be WP_Error.
	 */
	if ( 'manual' !== $type && ! apply_filters( 'auto_core_update_send_email', true, $type, $core_update, $result ) ) {
		return;
	}

	switch ( $type ) {
		case 'success': // We updated.
			/* translators: Site updated notification email subject. 1: Site title, 2: WordPress version. */
			$subject = __( '[%1$s] Your site has updated to WordPress %2$s' );
			break;

		case 'fail':   // We tried to update but couldn't.
		case 'manual': // We can't update (and made no attempt).
			/* translators: Update available notification email subject. 1: Site title, 2: WordPress version. */
			$subject = __( '[%1$s] WordPress %2$s is available. Please update!' );
			break;

		case 'critical': // We tried to update, started to copy files, then things went wrong.
			/* translators: Site down notification email subject. 1: Site title. */
			$subject = __( '[%1$s] URGENT: Your site may be down due to a failed update' );
			break;

		default:
			return;
	}

	// If the auto-update is not to the latest version, say that the current version of WP is available instead.
	$version = 'success' === $type ? $core_update->current : $next_user_core_update->current;
	$subject = sprintf( $subject, wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ), $version );

	$body = '';

	switch ( $type ) {
		case 'success':
			$body .= sprintf(
				/* translators: 1: Home URL, 2: WordPress version. */
				__( 'Howdy! Your site at %1$s has been updated automatically to WordPress %2$s.' ),
				home_url(),
				$core_update->current
			);
			$body .= "\n\n";
			if ( ! $newer_version_available ) {
				$body .= __( 'No further action is needed on your part.' ) . ' ';
			}

			// Can only reference the About screen if their update was successful.
			list( $about_version ) = explode( '-', $core_update->current, 2 );
			/* translators: %s: WordPress version. */
			$body .= sprintf( __( 'For more on version %s, see the About WordPress screen:' ), $about_version );
			$body .= "\n" . admin_url( 'about.php' );

			if ( $newer_version_available ) {
				/* translators: %s: WordPress latest version. */
				$body .= "\n\n" . sprintf( __( 'WordPress %s is also now available.' ), $next_user_core_update->current ) . ' ';
				$body .= __( 'Updating is easy and only takes a few moments:' );
				$body .= "\n" . network_admin_url( 'update-core.php' );
			}

			break;

		case 'fail':
		case 'manual':
			$body .= sprintf(
				/* translators: 1: Home URL, 2: WordPress version. */
				__( 'Please update your site at %1$s to WordPress %2$s.' ),
				home_url(),
				$next_user_core_update->current
			);

			$body .= "\n\n";

			/*
			 * Don't show this message if there is a newer version available.
			 * Potential for confusion, and also not useful for them to know at this point.
			 */
			if ( 'fail' === $type && ! $newer_version_available ) {
				$body .= __( 'An attempt was made, but your site could not be updated automatically.' ) . ' ';
			}

			$body .= __( 'Updating is easy and only takes a few moments:' );
			$body .= "\n" . network_admin_url( 'update-core.php' );
			break;

		case 'critical':
			if ( $newer_version_available ) {
				$body .= sprintf(
					/* translators: 1: Home URL, 2: WordPress version. */
					__( 'Your site at %1$s experienced a critical failure while trying to update WordPress to version %2$s.' ),
					home_url(),
					$core_update->current
				);
			} else {
				$body .= sprintf(
					/* translators: 1: Home URL, 2: WordPress latest version. */
					__( 'Your site at %1$s experienced a critical failure while trying to update to the latest version of WordPress, %2$s.' ),
					home_url(),
					$core_update->current
				);
			}

			$body .= "\n\n" . __( "This means your site may be offline or broken. Don't panic; this can be fixed." );

			$body .= "\n\n" . __( "Please check out your site now. It's possible that everything is working. If it says you need to update, you should do so:" );
			$body .= "\n" . network_admin_url( 'update-core.php' );
			break;
	}

	$critical_support = 'critical' === $type && ! empty( $core_update->support_email );
	if ( $critical_support ) {
		// Support offer if available.
		$body .= "\n\n" . sprintf(
			/* translators: %s: Support email address. */
			__( 'The WordPress team is willing to help you. Forward this email to %s and the team will work with you to make sure your site is working.' ),
			$core_update->support_email
		);
	} else {
		// Add a note about the support forums.
		$body .= "\n\n" . __( 'If you experience any issues or need support, the volunteers in the WordPress.org support forums may be able to help.' );
		$body .= "\n" . __( 'https://wordpress.org/support/forums/' );
	}

	// Updates are important!
	if ( 'success' !== $type || $newer_version_available ) {
		$body .= "\n\n" . __( 'Keeping your site updated is important for security. It also makes the internet a safer place for you and your readers.' );
	}

	if ( $critical_support ) {
		$body .= ' ' . __( "Reach out to WordPress Core developers to ensure you'll never have this problem again." );
	}

	// If things are successful and we're now on the latest, mention plugins and themes if any are out of date.
	if ( 'success' === $type && ! $newer_version_available && ( get_plugin_updates() || get_theme_updates() ) ) {
		$body .= "\n\n" . __( 'You also have some plugins or themes with updates available. Update them now:' );
		$body .= "\n" . network_admin_url();
	}

	$body .= "\n\n" . __( 'The WordPress Team' ) . "\n";

	if ( 'critical' === $type && is_wp_error( $result ) ) {
		$body .= "\n***\n\n";
		/* translators: %s: WordPress version. */
		$body .= sprintf( __( 'Your site was running version %s.' ), get_bloginfo( 'version' ) );
		$body .= ' ' . __( 'Some data that describes the error your site encountered has been put together.' );
		$body .= ' ' . __( 'Your hosting company, support forum volunteers, or a friendly developer may be able to use this information to help you:' );

		/*
		 * If we had a rollback and we're still critical, then the rollback failed too.
		 * Loop through all errors (the main WP_Error, the update result, the rollback result) for code, data, etc.
		 */
		if ( 'rollback_was_required' === $result->get_error_code() ) {
			$errors = array( $result, $result->get_error_data()->update, $result->get_error_data()->rollback );
		} else {
			$errors = array( $result );
		}

		foreach ( $errors as $error ) {
			if ( ! is_wp_error( $error ) ) {
				continue;
			}

			$error_code = $error->get_error_code();
			/* translators: %s: Error code. */
			$body .= "\n\n" . sprintf( __( 'Error code: %s' ), $error_code );

			if ( 'rollback_was_required' === $error_code ) {
				continue;
			}

			if ( $error->get_error_message() ) {
				$body .= "\n" . $error->get_error_message();
			}

			$error_data = $error->get_error_data();
			if ( $error_data ) {
				$body .= "\n" . implode( ', ', (array) $error_data );
			}
		}

		$body .= "\n";
	}

	$to      = get_site_option( 'admin_email' );
	$headers = '';

	$email = compact( 'to', 'subject', 'body', 'headers' );

	/**
	 * Filters the email sent following an automatic background core update.
	 *
	 * @since 3.7.0
	 *
	 * @param array $email {
	 *     Array of email arguments that will be passed to wp_mail().
	 *
	 *     @type string $to      The email recipient. An array of emails
	 *                            can be returned, as handled by wp_mail().
	 *     @type string $subject The email's subject.
	 *     @type string $body    The email message body.
	 *     @type string $headers Any email headers, defaults to no headers.
	 * }
	 * @param string $type        The type of email being sent. Can be one of
	 *                            'success', 'fail', 'manual', 'critical'.
	 * @param object $core_update The update offer that was attempted.
	 * @param mixed  $result      The result for the core update. Can be WP_Error.
	 */
	$email = apply_filters( 'auto_core_update_email', $email, $type, $core_update, $result );

	wp_mail( $email['to'], wp_specialchars_decode( $email['subject'] ), $email['body'], $email['headers'] );
}