diff --git a/src/wp-admin/admin-header.php b/src/wp-admin/admin-header.php
index 235468f146..2cb5041b4d 100644
--- a/src/wp-admin/admin-header.php
+++ b/src/wp-admin/admin-header.php
@@ -33,7 +33,7 @@ if ( empty( $current_screen ) ) {
 }
 
 get_admin_page_title();
-$title = strip_tags( $title );
+$title = wp_strip_all_tags( $title );
 
 if ( is_network_admin() ) {
 	/* translators: Network admin screen title. %s: Network title. */
diff --git a/src/wp-admin/includes/class-bulk-upgrader-skin.php b/src/wp-admin/includes/class-bulk-upgrader-skin.php
index 5cdd2a56ce..ea8a364638 100644
--- a/src/wp-admin/includes/class-bulk-upgrader-skin.php
+++ b/src/wp-admin/includes/class-bulk-upgrader-skin.php
@@ -84,7 +84,7 @@ class Bulk_Upgrader_Skin extends WP_Upgrader_Skin {
 
 		if ( str_contains( $feedback, '%' ) ) {
 			if ( $args ) {
-				$args     = array_map( 'strip_tags', $args );
+				$args     = array_map( 'wp_strip_all_tags', $args );
 				$args     = array_map( 'esc_html', $args );
 				$feedback = vsprintf( $feedback, $args );
 			}
@@ -134,7 +134,7 @@ class Bulk_Upgrader_Skin extends WP_Upgrader_Skin {
 			$messages = array();
 			foreach ( $errors->get_error_messages() as $emessage ) {
 				if ( $errors->get_error_data() && is_string( $errors->get_error_data() ) ) {
-					$messages[] = $emessage . ' ' . esc_html( strip_tags( $errors->get_error_data() ) );
+					$messages[] = $emessage . ' ' . esc_html( wp_strip_all_tags( $errors->get_error_data() ) );
 				} else {
 					$messages[] = $emessage;
 				}
diff --git a/src/wp-admin/includes/class-wp-ajax-upgrader-skin.php b/src/wp-admin/includes/class-wp-ajax-upgrader-skin.php
index 1ac8e31b43..ea727948e4 100644
--- a/src/wp-admin/includes/class-wp-ajax-upgrader-skin.php
+++ b/src/wp-admin/includes/class-wp-ajax-upgrader-skin.php
@@ -92,7 +92,7 @@ class WP_Ajax_Upgrader_Skin extends Automatic_Upgrader_Skin {
 			$error_data = $this->errors->get_error_data( $error_code );
 
 			if ( $error_data && is_string( $error_data ) ) {
-				$messages[] = $this->errors->get_error_message( $error_code ) . ' ' . esc_html( strip_tags( $error_data ) );
+				$messages[] = $this->errors->get_error_message( $error_code ) . ' ' . esc_html( wp_strip_all_tags( $error_data ) );
 			} else {
 				$messages[] = $this->errors->get_error_message( $error_code );
 			}
diff --git a/src/wp-admin/includes/class-wp-plugin-install-list-table.php b/src/wp-admin/includes/class-wp-plugin-install-list-table.php
index f39ec60a24..6f35435026 100644
--- a/src/wp-admin/includes/class-wp-plugin-install-list-table.php
+++ b/src/wp-admin/includes/class-wp-plugin-install-list-table.php
@@ -528,7 +528,7 @@ class WP_Plugin_Install_List_Table extends WP_List_Table {
 			$title = wp_kses( $plugin['name'], $plugins_allowedtags );
 
 			// Remove any HTML from the description.
-			$description = strip_tags( $plugin['short_description'] );
+			$description = wp_strip_all_tags( $plugin['short_description'] );
 
 			/**
 			 * Filters the plugin card description on the Add Plugins screen.
@@ -543,7 +543,7 @@ class WP_Plugin_Install_List_Table extends WP_List_Table {
 
 			$version = wp_kses( $plugin['version'], $plugins_allowedtags );
 
-			$name = strip_tags( $title . ' ' . $version );
+			$name = wp_strip_all_tags( $title . ' ' . $version );
 
 			$author = wp_kses( $plugin['author'], $plugins_allowedtags );
 			if ( ! empty( $author ) ) {
@@ -750,8 +750,8 @@ class WP_Plugin_Install_List_Table extends WP_List_Table {
 	 *
 	 * @since 6.5.0
 	 *
-	 * @param array  $plugin_data An array of plugin data. See {@see plugins_api()}
-	 *                            for the list of possible values.
+	 * @param array $plugin_data An array of plugin data. See {@see plugins_api()}
+	 *                           for the list of possible values.
 	 * @return string A notice containing a list of dependencies required by the plugin,
 	 *                or an empty string if none is required.
 	 */
diff --git a/src/wp-admin/includes/class-wp-plugins-list-table.php b/src/wp-admin/includes/class-wp-plugins-list-table.php
index e96445b771..00a50249bd 100644
--- a/src/wp-admin/includes/class-wp-plugins-list-table.php
+++ b/src/wp-admin/includes/class-wp-plugins-list-table.php
@@ -375,7 +375,7 @@ class WP_Plugins_List_Table extends WP_List_Table {
 		global $s;
 
 		foreach ( $plugin as $value ) {
-			if ( is_string( $value ) && false !== stripos( strip_tags( $value ), urldecode( $s ) ) ) {
+			if ( is_string( $value ) && false !== stripos( wp_strip_all_tags( $value ), urldecode( $s ) ) ) {
 				return true;
 			}
 		}
diff --git a/src/wp-admin/includes/class-wp-themes-list-table.php b/src/wp-admin/includes/class-wp-themes-list-table.php
index 53b34e93f9..f9a7696fb5 100644
--- a/src/wp-admin/includes/class-wp-themes-list-table.php
+++ b/src/wp-admin/includes/class-wp-themes-list-table.php
@@ -114,8 +114,7 @@ class WP_Themes_List_Table extends WP_List_Table {
 				return;
 			}
 			// Else, fallthrough. install_themes doesn't help if you can't enable it.
-		} else {
-			if ( current_user_can( 'install_themes' ) ) {
+		} elseif ( current_user_can( 'install_themes' ) ) {
 				printf(
 					/* translators: %s: URL to Add Themes screen. */
 					__( 'You only have one theme installed right now. Live a little! You can choose from over 1,000 free themes in the WordPress Theme Directory at any time: just click on the <a href="%s">Install Themes</a> tab above.' ),
@@ -123,7 +122,6 @@ class WP_Themes_List_Table extends WP_List_Table {
 				);
 
 				return;
-			}
 		}
 		// Fallthrough.
 		printf(
@@ -317,7 +315,7 @@ class WP_Themes_List_Table extends WP_List_Table {
 
 			foreach ( array( 'Name', 'Description', 'Author', 'AuthorURI' ) as $header ) {
 				// Don't mark up; Do translate.
-				if ( false !== stripos( strip_tags( $theme->display( $header, false, true ) ), $word ) ) {
+				if ( false !== stripos( wp_strip_all_tags( $theme->display( $header, false, true ) ), $word ) ) {
 					continue 2;
 				}
 			}
diff --git a/src/wp-admin/includes/class-wp-upgrader-skin.php b/src/wp-admin/includes/class-wp-upgrader-skin.php
index a5c80fad6d..72cd09b413 100644
--- a/src/wp-admin/includes/class-wp-upgrader-skin.php
+++ b/src/wp-admin/includes/class-wp-upgrader-skin.php
@@ -182,7 +182,7 @@ class WP_Upgrader_Skin {
 		} elseif ( is_wp_error( $errors ) && $errors->has_errors() ) {
 			foreach ( $errors->get_error_messages() as $message ) {
 				if ( $errors->get_error_data() && is_string( $errors->get_error_data() ) ) {
-					$this->feedback( $message . ' ' . esc_html( strip_tags( $errors->get_error_data() ) ) );
+					$this->feedback( $message . ' ' . esc_html( wp_strip_all_tags( $errors->get_error_data() ) ) );
 				} else {
 					$this->feedback( $message );
 				}
@@ -206,7 +206,7 @@ class WP_Upgrader_Skin {
 
 		if ( str_contains( $feedback, '%' ) ) {
 			if ( $args ) {
-				$args     = array_map( 'strip_tags', $args );
+				$args     = array_map( 'wp_strip_all_tags', $args );
 				$args     = array_map( 'esc_html', $args );
 				$feedback = vsprintf( $feedback, $args );
 			}
diff --git a/src/wp-admin/includes/dashboard.php b/src/wp-admin/includes/dashboard.php
index b198325f27..b22c765885 100644
--- a/src/wp-admin/includes/dashboard.php
+++ b/src/wp-admin/includes/dashboard.php
@@ -1273,7 +1273,7 @@ function wp_dashboard_rss_control( $widget_id, $form_inputs = array() ) {
 			if ( is_wp_error( $rss ) ) {
 				$widget_options[ $widget_id ]['title'] = htmlentities( __( 'Unknown Feed' ) );
 			} else {
-				$widget_options[ $widget_id ]['title'] = htmlentities( strip_tags( $rss->get_title() ) );
+				$widget_options[ $widget_id ]['title'] = htmlentities( wp_strip_all_tags( $rss->get_title() ) );
 				$rss->__destruct();
 				unset( $rss );
 			}
@@ -1384,7 +1384,8 @@ function wp_print_community_events_markup() {
 					<?php _e( 'City:' ); ?>
 				</label>
 				<?php
-				/* translators: Replace with a city related to your locale.
+				/*
+				translators: Replace with a city related to your locale.
 				 * Test that it matches the expected location and has upcoming
 				 * events before including it. If no cities related to your
 				 * locale have events, then use a city related to your locale
@@ -1432,7 +1433,8 @@ function wp_print_community_events_templates() {
 	<script id="tmpl-community-events-could-not-locate" type="text/template">
 		<?php
 		printf(
-			/* translators: %s is the name of the city we couldn't locate.
+			/*
+			translators: %s is the name of the city we couldn't locate.
 			 * Replace the examples with cities in your locale, but test
 			 * that they match the expected location before including them.
 			 * Use endonyms (native locale names) whenever possible.
diff --git a/src/wp-admin/includes/widgets.php b/src/wp-admin/includes/widgets.php
index 682f596d94..de68232632 100644
--- a/src/wp-admin/includes/widgets.php
+++ b/src/wp-admin/includes/widgets.php
@@ -237,7 +237,7 @@ function wp_widget_control( $sidebar_args ) {
 	$wp_registered_widgets[ $widget_id ]['callback'] = $wp_registered_widgets[ $widget_id ]['_callback'];
 	unset( $wp_registered_widgets[ $widget_id ]['_callback'] );
 
-	$widget_title = esc_html( strip_tags( $sidebar_args['widget_name'] ) );
+	$widget_title = esc_html( wp_strip_all_tags( $sidebar_args['widget_name'] ) );
 	$has_form     = 'noform';
 
 	echo $sidebar_args['before_widget'];
diff --git a/src/wp-admin/update-core.php b/src/wp-admin/update-core.php
index 82525a2f5f..186c9af7d0 100644
--- a/src/wp-admin/update-core.php
+++ b/src/wp-admin/update-core.php
@@ -76,79 +76,77 @@ function list_core_update( $update ) {
 
 	if ( 'development' === $update->response ) {
 		$message = __( 'You can update to the latest nightly build manually:' );
-	} else {
-		if ( $current ) {
+	} elseif ( $current ) {
 			/* translators: %s: WordPress version. */
 			$submit      = sprintf( __( 'Re-install version %s' ), $version_string );
 			$form_action = 'update-core.php?action=do-core-reinstall';
+	} else {
+		$php_compat = version_compare( $php_version, $update->php_version, '>=' );
+		if ( file_exists( WP_CONTENT_DIR . '/db.php' ) && empty( $wpdb->is_mysql ) ) {
+			$mysql_compat = true;
 		} else {
-			$php_compat = version_compare( $php_version, $update->php_version, '>=' );
-			if ( file_exists( WP_CONTENT_DIR . '/db.php' ) && empty( $wpdb->is_mysql ) ) {
-				$mysql_compat = true;
-			} else {
-				$mysql_compat = version_compare( $mysql_version, $update->mysql_version, '>=' );
-			}
+			$mysql_compat = version_compare( $mysql_version, $update->mysql_version, '>=' );
+		}
 
-			$version_url = sprintf(
-				/* translators: %s: WordPress version. */
-				esc_url( __( 'https://wordpress.org/documentation/wordpress-version/version-%s/' ) ),
-				sanitize_title( $update->current )
-			);
+		$version_url = sprintf(
+			/* translators: %s: WordPress version. */
+			esc_url( __( 'https://wordpress.org/documentation/wordpress-version/version-%s/' ) ),
+			sanitize_title( $update->current )
+		);
 
-			$php_update_message = '</p><p>' . sprintf(
-				/* translators: %s: URL to Update PHP page. */
-				__( '<a href="%s">Learn more about updating PHP</a>.' ),
-				esc_url( wp_get_update_php_url() )
-			);
+		$php_update_message = '</p><p>' . sprintf(
+			/* translators: %s: URL to Update PHP page. */
+			__( '<a href="%s">Learn more about updating PHP</a>.' ),
+			esc_url( wp_get_update_php_url() )
+		);
 
-			$annotation = wp_get_update_php_annotation();
+		$annotation = wp_get_update_php_annotation();
 
-			if ( $annotation ) {
-				$php_update_message .= '</p><p><em>' . $annotation . '</em>';
-			}
+		if ( $annotation ) {
+			$php_update_message .= '</p><p><em>' . $annotation . '</em>';
+		}
 
-			if ( ! $mysql_compat && ! $php_compat ) {
-				$message = sprintf(
-					/* translators: 1: URL to WordPress release notes, 2: WordPress version number, 3: Minimum required PHP version number, 4: Minimum required MySQL version number, 5: Current PHP version number, 6: Current MySQL version number. */
-					__( 'You cannot update because <a href="%1$s">WordPress %2$s</a> requires PHP version %3$s or higher and MySQL version %4$s or higher. You are running PHP version %5$s and MySQL version %6$s.' ),
-					$version_url,
-					$update->current,
-					$update->php_version,
-					$update->mysql_version,
-					$php_version,
-					$mysql_version
-				) . $php_update_message;
-			} elseif ( ! $php_compat ) {
-				$message = sprintf(
-					/* translators: 1: URL to WordPress release notes, 2: WordPress version number, 3: Minimum required PHP version number, 4: Current PHP version number. */
-					__( 'You cannot update because <a href="%1$s">WordPress %2$s</a> requires PHP version %3$s or higher. You are running version %4$s.' ),
-					$version_url,
-					$update->current,
-					$update->php_version,
-					$php_version
-				) . $php_update_message;
-			} elseif ( ! $mysql_compat ) {
-				$message = sprintf(
-					/* translators: 1: URL to WordPress release notes, 2: WordPress version number, 3: Minimum required MySQL version number, 4: Current MySQL version number. */
-					__( 'You cannot update because <a href="%1$s">WordPress %2$s</a> requires MySQL version %3$s or higher. You are running version %4$s.' ),
-					$version_url,
-					$update->current,
-					$update->mysql_version,
-					$mysql_version
-				);
-			} else {
-				$message = sprintf(
-					/* translators: 1: Installed WordPress version number, 2: URL to WordPress release notes, 3: New WordPress version number, including locale if necessary. */
-					__( 'You can update from WordPress %1$s to <a href="%2$s">WordPress %3$s</a> manually:' ),
-					$wp_version,
-					$version_url,
-					$version_string
-				);
-			}
+		if ( ! $mysql_compat && ! $php_compat ) {
+			$message = sprintf(
+				/* translators: 1: URL to WordPress release notes, 2: WordPress version number, 3: Minimum required PHP version number, 4: Minimum required MySQL version number, 5: Current PHP version number, 6: Current MySQL version number. */
+				__( 'You cannot update because <a href="%1$s">WordPress %2$s</a> requires PHP version %3$s or higher and MySQL version %4$s or higher. You are running PHP version %5$s and MySQL version %6$s.' ),
+				$version_url,
+				$update->current,
+				$update->php_version,
+				$update->mysql_version,
+				$php_version,
+				$mysql_version
+			) . $php_update_message;
+		} elseif ( ! $php_compat ) {
+			$message = sprintf(
+				/* translators: 1: URL to WordPress release notes, 2: WordPress version number, 3: Minimum required PHP version number, 4: Current PHP version number. */
+				__( 'You cannot update because <a href="%1$s">WordPress %2$s</a> requires PHP version %3$s or higher. You are running version %4$s.' ),
+				$version_url,
+				$update->current,
+				$update->php_version,
+				$php_version
+			) . $php_update_message;
+		} elseif ( ! $mysql_compat ) {
+			$message = sprintf(
+				/* translators: 1: URL to WordPress release notes, 2: WordPress version number, 3: Minimum required MySQL version number, 4: Current MySQL version number. */
+				__( 'You cannot update because <a href="%1$s">WordPress %2$s</a> requires MySQL version %3$s or higher. You are running version %4$s.' ),
+				$version_url,
+				$update->current,
+				$update->mysql_version,
+				$mysql_version
+			);
+		} else {
+			$message = sprintf(
+				/* translators: 1: Installed WordPress version number, 2: URL to WordPress release notes, 3: New WordPress version number, including locale if necessary. */
+				__( 'You can update from WordPress %1$s to <a href="%2$s">WordPress %3$s</a> manually:' ),
+				$wp_version,
+				$version_url,
+				$version_string
+			);
+		}
 
-			if ( ! $mysql_compat || ! $php_compat ) {
-				$show_buttons = false;
-			}
+		if ( ! $mysql_compat || ! $php_compat ) {
+			$show_buttons = false;
 		}
 	}
 
@@ -562,7 +560,7 @@ function list_plugin_updates() {
 
 		// Get the upgrade notice for the new plugin version.
 		if ( isset( $plugin_data->update->upgrade_notice ) ) {
-			$upgrade_notice = '<br />' . strip_tags( $plugin_data->update->upgrade_notice );
+			$upgrade_notice = '<br />' . wp_strip_all_tags( $plugin_data->update->upgrade_notice );
 		} else {
 			$upgrade_notice = '';
 		}
diff --git a/src/wp-admin/widgets-form.php b/src/wp-admin/widgets-form.php
index 461f8d6fb4..6a1805b223 100644
--- a/src/wp-admin/widgets-form.php
+++ b/src/wp-admin/widgets-form.php
@@ -251,11 +251,11 @@ if ( isset( $_GET['editwidget'] ) && $_GET['editwidget'] ) {
 		$control          = $wp_registered_widget_controls[ $widget_id ];
 		$control_callback = $control['callback'];
 	} elseif ( ! isset( $wp_registered_widget_controls[ $widget_id ] ) && isset( $wp_registered_widgets[ $widget_id ] ) ) {
-		$name = esc_html( strip_tags( $wp_registered_widgets[ $widget_id ]['name'] ) );
+		$name = esc_html( wp_strip_all_tags( $wp_registered_widgets[ $widget_id ]['name'] ) );
 	}
 
 	if ( ! isset( $name ) ) {
-		$name = esc_html( strip_tags( $control['name'] ) );
+		$name = esc_html( wp_strip_all_tags( $control['name'] ) );
 	}
 
 	if ( ! isset( $sidebar ) ) {
diff --git a/src/wp-includes/PHPMailer/PHPMailer.php b/src/wp-includes/PHPMailer/PHPMailer.php
index 31731594f1..e8b773a740 100644
--- a/src/wp-includes/PHPMailer/PHPMailer.php
+++ b/src/wp-includes/PHPMailer/PHPMailer.php
@@ -29,5222 +29,5124 @@ namespace PHPMailer\PHPMailer;
  * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
  * @author Brent R. Matzelle (original founder)
  */
-class PHPMailer
-{
-    const CHARSET_ASCII = 'us-ascii';
-    const CHARSET_ISO88591 = 'iso-8859-1';
-    const CHARSET_UTF8 = 'utf-8';
-
-    const CONTENT_TYPE_PLAINTEXT = 'text/plain';
-    const CONTENT_TYPE_TEXT_CALENDAR = 'text/calendar';
-    const CONTENT_TYPE_TEXT_HTML = 'text/html';
-    const CONTENT_TYPE_MULTIPART_ALTERNATIVE = 'multipart/alternative';
-    const CONTENT_TYPE_MULTIPART_MIXED = 'multipart/mixed';
-    const CONTENT_TYPE_MULTIPART_RELATED = 'multipart/related';
-
-    const ENCODING_7BIT = '7bit';
-    const ENCODING_8BIT = '8bit';
-    const ENCODING_BASE64 = 'base64';
-    const ENCODING_BINARY = 'binary';
-    const ENCODING_QUOTED_PRINTABLE = 'quoted-printable';
-
-    const ENCRYPTION_STARTTLS = 'tls';
-    const ENCRYPTION_SMTPS = 'ssl';
-
-    const ICAL_METHOD_REQUEST = 'REQUEST';
-    const ICAL_METHOD_PUBLISH = 'PUBLISH';
-    const ICAL_METHOD_REPLY = 'REPLY';
-    const ICAL_METHOD_ADD = 'ADD';
-    const ICAL_METHOD_CANCEL = 'CANCEL';
-    const ICAL_METHOD_REFRESH = 'REFRESH';
-    const ICAL_METHOD_COUNTER = 'COUNTER';
-    const ICAL_METHOD_DECLINECOUNTER = 'DECLINECOUNTER';
-
-    /**
-     * Email priority.
-     * Options: null (default), 1 = High, 3 = Normal, 5 = low.
-     * When null, the header is not set at all.
-     *
-     * @var int|null
-     */
-    public $Priority;
-
-    /**
-     * The character set of the message.
-     *
-     * @var string
-     */
-    public $CharSet = self::CHARSET_ISO88591;
-
-    /**
-     * The MIME Content-type of the message.
-     *
-     * @var string
-     */
-    public $ContentType = self::CONTENT_TYPE_PLAINTEXT;
-
-    /**
-     * The message encoding.
-     * Options: "8bit", "7bit", "binary", "base64", and "quoted-printable".
-     *
-     * @var string
-     */
-    public $Encoding = self::ENCODING_8BIT;
-
-    /**
-     * Holds the most recent mailer error message.
-     *
-     * @var string
-     */
-    public $ErrorInfo = '';
-
-    /**
-     * The From email address for the message.
-     *
-     * @var string
-     */
-    public $From = '';
-
-    /**
-     * The From name of the message.
-     *
-     * @var string
-     */
-    public $FromName = '';
-
-    /**
-     * The envelope sender of the message.
-     * This will usually be turned into a Return-Path header by the receiver,
-     * and is the address that bounces will be sent to.
-     * If not empty, will be passed via `-f` to sendmail or as the 'MAIL FROM' value over SMTP.
-     *
-     * @var string
-     */
-    public $Sender = '';
-
-    /**
-     * The Subject of the message.
-     *
-     * @var string
-     */
-    public $Subject = '';
-
-    /**
-     * An HTML or plain text message body.
-     * If HTML then call isHTML(true).
-     *
-     * @var string
-     */
-    public $Body = '';
-
-    /**
-     * The plain-text message body.
-     * This body can be read by mail clients that do not have HTML email
-     * capability such as mutt & Eudora.
-     * Clients that can read HTML will view the normal Body.
-     *
-     * @var string
-     */
-    public $AltBody = '';
-
-    /**
-     * An iCal message part body.
-     * Only supported in simple alt or alt_inline message types
-     * To generate iCal event structures, use classes like EasyPeasyICS or iCalcreator.
-     *
-     * @see https://kigkonsult.se/iCalcreator/
-     *
-     * @var string
-     */
-    public $Ical = '';
-
-    /**
-     * Value-array of "method" in Contenttype header "text/calendar"
-     *
-     * @var string[]
-     */
-    protected static $IcalMethods = [
-        self::ICAL_METHOD_REQUEST,
-        self::ICAL_METHOD_PUBLISH,
-        self::ICAL_METHOD_REPLY,
-        self::ICAL_METHOD_ADD,
-        self::ICAL_METHOD_CANCEL,
-        self::ICAL_METHOD_REFRESH,
-        self::ICAL_METHOD_COUNTER,
-        self::ICAL_METHOD_DECLINECOUNTER,
-    ];
-
-    /**
-     * The complete compiled MIME message body.
-     *
-     * @var string
-     */
-    protected $MIMEBody = '';
-
-    /**
-     * The complete compiled MIME message headers.
-     *
-     * @var string
-     */
-    protected $MIMEHeader = '';
-
-    /**
-     * Extra headers that createHeader() doesn't fold in.
-     *
-     * @var string
-     */
-    protected $mailHeader = '';
-
-    /**
-     * Word-wrap the message body to this number of chars.
-     * Set to 0 to not wrap. A useful value here is 78, for RFC2822 section 2.1.1 compliance.
-     *
-     * @see static::STD_LINE_LENGTH
-     *
-     * @var int
-     */
-    public $WordWrap = 0;
-
-    /**
-     * Which method to use to send mail.
-     * Options: "mail", "sendmail", or "smtp".
-     *
-     * @var string
-     */
-    public $Mailer = 'mail';
-
-    /**
-     * The path to the sendmail program.
-     *
-     * @var string
-     */
-    public $Sendmail = '/usr/sbin/sendmail';
-
-    /**
-     * Whether mail() uses a fully sendmail-compatible MTA.
-     * One which supports sendmail's "-oi -f" options.
-     *
-     * @var bool
-     */
-    public $UseSendmailOptions = true;
-
-    /**
-     * The email address that a reading confirmation should be sent to, also known as read receipt.
-     *
-     * @var string
-     */
-    public $ConfirmReadingTo = '';
-
-    /**
-     * The hostname to use in the Message-ID header and as default HELO string.
-     * If empty, PHPMailer attempts to find one with, in order,
-     * $_SERVER['SERVER_NAME'], gethostname(), php_uname('n'), or the value
-     * 'localhost.localdomain'.
-     *
-     * @see PHPMailer::$Helo
-     *
-     * @var string
-     */
-    public $Hostname = '';
-
-    /**
-     * An ID to be used in the Message-ID header.
-     * If empty, a unique id will be generated.
-     * You can set your own, but it must be in the format "<id@domain>",
-     * as defined in RFC5322 section 3.6.4 or it will be ignored.
-     *
-     * @see https://www.rfc-editor.org/rfc/rfc5322#section-3.6.4
-     *
-     * @var string
-     */
-    public $MessageID = '';
-
-    /**
-     * The message Date to be used in the Date header.
-     * If empty, the current date will be added.
-     *
-     * @var string
-     */
-    public $MessageDate = '';
-
-    /**
-     * SMTP hosts.
-     * Either a single hostname or multiple semicolon-delimited hostnames.
-     * You can also specify a different port
-     * for each host by using this format: [hostname:port]
-     * (e.g. "smtp1.example.com:25;smtp2.example.com").
-     * You can also specify encryption type, for example:
-     * (e.g. "tls://smtp1.example.com:587;ssl://smtp2.example.com:465").
-     * Hosts will be tried in order.
-     *
-     * @var string
-     */
-    public $Host = 'localhost';
-
-    /**
-     * The default SMTP server port.
-     *
-     * @var int
-     */
-    public $Port = 25;
-
-    /**
-     * The SMTP HELO/EHLO name used for the SMTP connection.
-     * Default is $Hostname. If $Hostname is empty, PHPMailer attempts to find
-     * one with the same method described above for $Hostname.
-     *
-     * @see PHPMailer::$Hostname
-     *
-     * @var string
-     */
-    public $Helo = '';
-
-    /**
-     * What kind of encryption to use on the SMTP connection.
-     * Options: '', static::ENCRYPTION_STARTTLS, or static::ENCRYPTION_SMTPS.
-     *
-     * @var string
-     */
-    public $SMTPSecure = '';
-
-    /**
-     * Whether to enable TLS encryption automatically if a server supports it,
-     * even if `SMTPSecure` is not set to 'tls'.
-     * Be aware that in PHP >= 5.6 this requires that the server's certificates are valid.
-     *
-     * @var bool
-     */
-    public $SMTPAutoTLS = true;
-
-    /**
-     * Whether to use SMTP authentication.
-     * Uses the Username and Password properties.
-     *
-     * @see PHPMailer::$Username
-     * @see PHPMailer::$Password
-     *
-     * @var bool
-     */
-    public $SMTPAuth = false;
-
-    /**
-     * Options array passed to stream_context_create when connecting via SMTP.
-     *
-     * @var array
-     */
-    public $SMTPOptions = [];
-
-    /**
-     * SMTP username.
-     *
-     * @var string
-     */
-    public $Username = '';
-
-    /**
-     * SMTP password.
-     *
-     * @var string
-     */
-    public $Password = '';
-
-    /**
-     * SMTP authentication type. Options are CRAM-MD5, LOGIN, PLAIN, XOAUTH2.
-     * If not specified, the first one from that list that the server supports will be selected.
-     *
-     * @var string
-     */
-    public $AuthType = '';
-
-    /**
-     * SMTP SMTPXClient command attributes
-     *
-     * @var array
-     */
-    protected $SMTPXClient = [];
-
-    /**
-     * An implementation of the PHPMailer OAuthTokenProvider interface.
-     *
-     * @var OAuthTokenProvider
-     */
-    protected $oauth;
-
-    /**
-     * The SMTP server timeout in seconds.
-     * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2.
-     *
-     * @var int
-     */
-    public $Timeout = 300;
-
-    /**
-     * Comma separated list of DSN notifications
-     * 'NEVER' under no circumstances a DSN must be returned to the sender.
-     *         If you use NEVER all other notifications will be ignored.
-     * 'SUCCESS' will notify you when your mail has arrived at its destination.
-     * 'FAILURE' will arrive if an error occurred during delivery.
-     * 'DELAY'   will notify you if there is an unusual delay in delivery, but the actual
-     *           delivery's outcome (success or failure) is not yet decided.
-     *
-     * @see https://www.rfc-editor.org/rfc/rfc3461.html#section-4.1 for more information about NOTIFY
-     */
-    public $dsn = '';
-
-    /**
-     * SMTP class debug output mode.
-     * Debug output level.
-     * Options:
-     * @see SMTP::DEBUG_OFF: No output
-     * @see SMTP::DEBUG_CLIENT: Client messages
-     * @see SMTP::DEBUG_SERVER: Client and server messages
-     * @see SMTP::DEBUG_CONNECTION: As SERVER plus connection status
-     * @see SMTP::DEBUG_LOWLEVEL: Noisy, low-level data output, rarely needed
-     *
-     * @see SMTP::$do_debug
-     *
-     * @var int
-     */
-    public $SMTPDebug = 0;
-
-    /**
-     * How to handle debug output.
-     * Options:
-     * * `echo` Output plain-text as-is, appropriate for CLI
-     * * `html` Output escaped, line breaks converted to `<br>`, appropriate for browser output
-     * * `error_log` Output to error log as configured in php.ini
-     * By default PHPMailer will use `echo` if run from a `cli` or `cli-server` SAPI, `html` otherwise.
-     * Alternatively, you can provide a callable expecting two params: a message string and the debug level:
-     *
-     * ```php
-     * $mail->Debugoutput = function($str, $level) {echo "debug level $level; message: $str";};
-     * ```
-     *
-     * Alternatively, you can pass in an instance of a PSR-3 compatible logger, though only `debug`
-     * level output is used:
-     *
-     * ```php
-     * $mail->Debugoutput = new myPsr3Logger;
-     * ```
-     *
-     * @see SMTP::$Debugoutput
-     *
-     * @var string|callable|\Psr\Log\LoggerInterface
-     */
-    public $Debugoutput = 'echo';
-
-    /**
-     * Whether to keep the SMTP connection open after each message.
-     * If this is set to true then the connection will remain open after a send,
-     * and closing the connection will require an explicit call to smtpClose().
-     * It's a good idea to use this if you are sending multiple messages as it reduces overhead.
-     * See the mailing list example for how to use it.
-     *
-     * @var bool
-     */
-    public $SMTPKeepAlive = false;
-
-    /**
-     * Whether to split multiple to addresses into multiple messages
-     * or send them all in one message.
-     * Only supported in `mail` and `sendmail` transports, not in SMTP.
-     *
-     * @var bool
-     *
-     * @deprecated 6.0.0 PHPMailer isn't a mailing list manager!
-     */
-    public $SingleTo = false;
-
-    /**
-     * Storage for addresses when SingleTo is enabled.
-     *
-     * @var array
-     */
-    protected $SingleToArray = [];
-
-    /**
-     * Whether to generate VERP addresses on send.
-     * Only applicable when sending via SMTP.
-     *
-     * @see https://en.wikipedia.org/wiki/Variable_envelope_return_path
-     * @see https://www.postfix.org/VERP_README.html Postfix VERP info
-     *
-     * @var bool
-     */
-    public $do_verp = false;
-
-    /**
-     * Whether to allow sending messages with an empty body.
-     *
-     * @var bool
-     */
-    public $AllowEmpty = false;
-
-    /**
-     * DKIM selector.
-     *
-     * @var string
-     */
-    public $DKIM_selector = '';
-
-    /**
-     * DKIM Identity.
-     * Usually the email address used as the source of the email.
-     *
-     * @var string
-     */
-    public $DKIM_identity = '';
-
-    /**
-     * DKIM passphrase.
-     * Used if your key is encrypted.
-     *
-     * @var string
-     */
-    public $DKIM_passphrase = '';
-
-    /**
-     * DKIM signing domain name.
-     *
-     * @example 'example.com'
-     *
-     * @var string
-     */
-    public $DKIM_domain = '';
-
-    /**
-     * DKIM Copy header field values for diagnostic use.
-     *
-     * @var bool
-     */
-    public $DKIM_copyHeaderFields = true;
-
-    /**
-     * DKIM Extra signing headers.
-     *
-     * @example ['List-Unsubscribe', 'List-Help']
-     *
-     * @var array
-     */
-    public $DKIM_extraHeaders = [];
-
-    /**
-     * DKIM private key file path.
-     *
-     * @var string
-     */
-    public $DKIM_private = '';
-
-    /**
-     * DKIM private key string.
-     *
-     * If set, takes precedence over `$DKIM_private`.
-     *
-     * @var string
-     */
-    public $DKIM_private_string = '';
-
-    /**
-     * Callback Action function name.
-     *
-     * The function that handles the result of the send email action.
-     * It is called out by send() for each email sent.
-     *
-     * Value can be any php callable: https://www.php.net/is_callable
-     *
-     * Parameters:
-     *   bool $result           result of the send action
-     *   array   $to            email addresses of the recipients
-     *   array   $cc            cc email addresses
-     *   array   $bcc           bcc email addresses
-     *   string  $subject       the subject
-     *   string  $body          the email body
-     *   string  $from          email address of sender
-     *   string  $extra         extra information of possible use
-     *                          "smtp_transaction_id' => last smtp transaction id
-     *
-     * @var string
-     */
-    public $action_function = '';
-
-    /**
-     * What to put in the X-Mailer header.
-     * Options: An empty string for PHPMailer default, whitespace/null for none, or a string to use.
-     *
-     * @var string|null
-     */
-    public $XMailer = '';
-
-    /**
-     * Which validator to use by default when validating email addresses.
-     * May be a callable to inject your own validator, but there are several built-in validators.
-     * The default validator uses PHP's FILTER_VALIDATE_EMAIL filter_var option.
-     *
-     * @see PHPMailer::validateAddress()
-     *
-     * @var string|callable
-     */
-    public static $validator = 'php';
-
-    /**
-     * An instance of the SMTP sender class.
-     *
-     * @var SMTP
-     */
-    protected $smtp;
-
-    /**
-     * The array of 'to' names and addresses.
-     *
-     * @var array
-     */
-    protected $to = [];
-
-    /**
-     * The array of 'cc' names and addresses.
-     *
-     * @var array
-     */
-    protected $cc = [];
-
-    /**
-     * The array of 'bcc' names and addresses.
-     *
-     * @var array
-     */
-    protected $bcc = [];
-
-    /**
-     * The array of reply-to names and addresses.
-     *
-     * @var array
-     */
-    protected $ReplyTo = [];
-
-    /**
-     * An array of all kinds of addresses.
-     * Includes all of $to, $cc, $bcc.
-     *
-     * @see PHPMailer::$to
-     * @see PHPMailer::$cc
-     * @see PHPMailer::$bcc
-     *
-     * @var array
-     */
-    protected $all_recipients = [];
-
-    /**
-     * An array of names and addresses queued for validation.
-     * In send(), valid and non duplicate entries are moved to $all_recipients
-     * and one of $to, $cc, or $bcc.
-     * This array is used only for addresses with IDN.
-     *
-     * @see PHPMailer::$to
-     * @see PHPMailer::$cc
-     * @see PHPMailer::$bcc
-     * @see PHPMailer::$all_recipients
-     *
-     * @var array
-     */
-    protected $RecipientsQueue = [];
-
-    /**
-     * An array of reply-to names and addresses queued for validation.
-     * In send(), valid and non duplicate entries are moved to $ReplyTo.
-     * This array is used only for addresses with IDN.
-     *
-     * @see PHPMailer::$ReplyTo
-     *
-     * @var array
-     */
-    protected $ReplyToQueue = [];
-
-    /**
-     * The array of attachments.
-     *
-     * @var array
-     */
-    protected $attachment = [];
-
-    /**
-     * The array of custom headers.
-     *
-     * @var array
-     */
-    protected $CustomHeader = [];
-
-    /**
-     * The most recent Message-ID (including angular brackets).
-     *
-     * @var string
-     */
-    protected $lastMessageID = '';
-
-    /**
-     * The message's MIME type.
-     *
-     * @var string
-     */
-    protected $message_type = '';
-
-    /**
-     * The array of MIME boundary strings.
-     *
-     * @var array
-     */
-    protected $boundary = [];
-
-    /**
-     * The array of available text strings for the current language.
-     *
-     * @var array
-     */
-    protected $language = [];
-
-    /**
-     * The number of errors encountered.
-     *
-     * @var int
-     */
-    protected $error_count = 0;
-
-    /**
-     * The S/MIME certificate file path.
-     *
-     * @var string
-     */
-    protected $sign_cert_file = '';
-
-    /**
-     * The S/MIME key file path.
-     *
-     * @var string
-     */
-    protected $sign_key_file = '';
-
-    /**
-     * The optional S/MIME extra certificates ("CA Chain") file path.
-     *
-     * @var string
-     */
-    protected $sign_extracerts_file = '';
-
-    /**
-     * The S/MIME password for the key.
-     * Used only if the key is encrypted.
-     *
-     * @var string
-     */
-    protected $sign_key_pass = '';
-
-    /**
-     * Whether to throw exceptions for errors.
-     *
-     * @var bool
-     */
-    protected $exceptions = false;
-
-    /**
-     * Unique ID used for message ID and boundaries.
-     *
-     * @var string
-     */
-    protected $uniqueid = '';
-
-    /**
-     * The PHPMailer Version number.
-     *
-     * @var string
-     */
-    const VERSION = '6.9.3';
-
-    /**
-     * Error severity: message only, continue processing.
-     *
-     * @var int
-     */
-    const STOP_MESSAGE = 0;
-
-    /**
-     * Error severity: message, likely ok to continue processing.
-     *
-     * @var int
-     */
-    const STOP_CONTINUE = 1;
-
-    /**
-     * Error severity: message, plus full stop, critical error reached.
-     *
-     * @var int
-     */
-    const STOP_CRITICAL = 2;
-
-    /**
-     * The SMTP standard CRLF line break.
-     * If you want to change line break format, change static::$LE, not this.
-     */
-    const CRLF = "\r\n";
-
-    /**
-     * "Folding White Space" a white space string used for line folding.
-     */
-    const FWS = ' ';
-
-    /**
-     * SMTP RFC standard line ending; Carriage Return, Line Feed.
-     *
-     * @var string
-     */
-    protected static $LE = self::CRLF;
-
-    /**
-     * The maximum line length supported by mail().
-     *
-     * Background: mail() will sometimes corrupt messages
-     * with headers longer than 65 chars, see #818.
-     *
-     * @var int
-     */
-    const MAIL_MAX_LINE_LENGTH = 63;
-
-    /**
-     * The maximum line length allowed by RFC 2822 section 2.1.1.
-     *
-     * @var int
-     */
-    const MAX_LINE_LENGTH = 998;
-
-    /**
-     * The lower maximum line length allowed by RFC 2822 section 2.1.1.
-     * This length does NOT include the line break
-     * 76 means that lines will be 77 or 78 chars depending on whether
-     * the line break format is LF or CRLF; both are valid.
-     *
-     * @var int
-     */
-    const STD_LINE_LENGTH = 76;
-
-    /**
-     * Constructor.
-     *
-     * @param bool $exceptions Should we throw external exceptions?
-     */
-    public function __construct($exceptions = null)
-    {
-        if (null !== $exceptions) {
-            $this->exceptions = (bool) $exceptions;
-        }
-        //Pick an appropriate debug output format automatically
-        $this->Debugoutput = (strpos(PHP_SAPI, 'cli') !== false ? 'echo' : 'html');
-    }
-
-    /**
-     * Destructor.
-     */
-    public function __destruct()
-    {
-        //Close any open SMTP connection nicely
-        $this->smtpClose();
-    }
-
-    /**
-     * Call mail() in a safe_mode-aware fashion.
-     * Also, unless sendmail_path points to sendmail (or something that
-     * claims to be sendmail), don't pass params (not a perfect fix,
-     * but it will do).
-     *
-     * @param string      $to      To
-     * @param string      $subject Subject
-     * @param string      $body    Message Body
-     * @param string      $header  Additional Header(s)
-     * @param string|null $params  Params
-     *
-     * @return bool
-     */
-    private function mailPassthru($to, $subject, $body, $header, $params)
-    {
-        //Check overloading of mail function to avoid double-encoding
-        if ((int)ini_get('mbstring.func_overload') & 1) { // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.mbstring_func_overloadDeprecated
-            $subject = $this->secureHeader($subject);
-        } else {
-            $subject = $this->encodeHeader($this->secureHeader($subject));
-        }
-        //Calling mail() with null params breaks
-        $this->edebug('Sending with mail()');
-        $this->edebug('Sendmail path: ' . ini_get('sendmail_path'));
-        $this->edebug("Envelope sender: {$this->Sender}");
-        $this->edebug("To: {$to}");
-        $this->edebug("Subject: {$subject}");
-        $this->edebug("Headers: {$header}");
-        if (!$this->UseSendmailOptions || null === $params) {
-            $result = @mail($to, $subject, $body, $header);
-        } else {
-            $this->edebug("Additional params: {$params}");
-            $result = @mail($to, $subject, $body, $header, $params);
-        }
-        $this->edebug('Result: ' . ($result ? 'true' : 'false'));
-        return $result;
-    }
-
-    /**
-     * Output debugging info via a user-defined method.
-     * Only generates output if debug output is enabled.
-     *
-     * @see PHPMailer::$Debugoutput
-     * @see PHPMailer::$SMTPDebug
-     *
-     * @param string $str
-     */
-    protected function edebug($str)
-    {
-        if ($this->SMTPDebug <= 0) {
-            return;
-        }
-        //Is this a PSR-3 logger?
-        if ($this->Debugoutput instanceof \Psr\Log\LoggerInterface) {
-            $this->Debugoutput->debug(rtrim($str, "\r\n"));
-
-            return;
-        }
-        //Avoid clash with built-in function names
-        if (is_callable($this->Debugoutput) && !in_array($this->Debugoutput, ['error_log', 'html', 'echo'])) {
-            call_user_func($this->Debugoutput, $str, $this->SMTPDebug);
-
-            return;
-        }
-        switch ($this->Debugoutput) {
-            case 'error_log':
-                //Don't output, just log
-                /** @noinspection ForgottenDebugOutputInspection */
-                error_log($str);
-                break;
-            case 'html':
-                //Cleans up output a bit for a better looking, HTML-safe output
-                echo htmlentities(
-                    preg_replace('/[\r\n]+/', '', $str),
-                    ENT_QUOTES,
-                    'UTF-8'
-                ), "<br>\n";
-                break;
-            case 'echo':
-            default:
-                //Normalize line breaks
-                $str = preg_replace('/\r\n|\r/m', "\n", $str);
-                echo gmdate('Y-m-d H:i:s'),
-                "\t",
-                    //Trim trailing space
-                trim(
-                    //Indent for readability, except for trailing break
-                    str_replace(
-                        "\n",
-                        "\n                   \t                  ",
-                        trim($str)
-                    )
-                ),
-                "\n";
-        }
-    }
-
-    /**
-     * Sets message type to HTML or plain.
-     *
-     * @param bool $isHtml True for HTML mode
-     */
-    public function isHTML($isHtml = true)
-    {
-        if ($isHtml) {
-            $this->ContentType = static::CONTENT_TYPE_TEXT_HTML;
-        } else {
-            $this->ContentType = static::CONTENT_TYPE_PLAINTEXT;
-        }
-    }
-
-    /**
-     * Send messages using SMTP.
-     */
-    public function isSMTP()
-    {
-        $this->Mailer = 'smtp';
-    }
-
-    /**
-     * Send messages using PHP's mail() function.
-     */
-    public function isMail()
-    {
-        $this->Mailer = 'mail';
-    }
-
-    /**
-     * Send messages using $Sendmail.
-     */
-    public function isSendmail()
-    {
-        $ini_sendmail_path = ini_get('sendmail_path');
-
-        if (false === stripos($ini_sendmail_path, 'sendmail')) {
-            $this->Sendmail = '/usr/sbin/sendmail';
-        } else {
-            $this->Sendmail = $ini_sendmail_path;
-        }
-        $this->Mailer = 'sendmail';
-    }
-
-    /**
-     * Send messages using qmail.
-     */
-    public function isQmail()
-    {
-        $ini_sendmail_path = ini_get('sendmail_path');
-
-        if (false === stripos($ini_sendmail_path, 'qmail')) {
-            $this->Sendmail = '/var/qmail/bin/qmail-inject';
-        } else {
-            $this->Sendmail = $ini_sendmail_path;
-        }
-        $this->Mailer = 'qmail';
-    }
-
-    /**
-     * Add a "To" address.
-     *
-     * @param string $address The email address to send to
-     * @param string $name
-     *
-     * @throws Exception
-     *
-     * @return bool true on success, false if address already used or invalid in some way
-     */
-    public function addAddress($address, $name = '')
-    {
-        return $this->addOrEnqueueAnAddress('to', $address, $name);
-    }
-
-    /**
-     * Add a "CC" address.
-     *
-     * @param string $address The email address to send to
-     * @param string $name
-     *
-     * @throws Exception
-     *
-     * @return bool true on success, false if address already used or invalid in some way
-     */
-    public function addCC($address, $name = '')
-    {
-        return $this->addOrEnqueueAnAddress('cc', $address, $name);
-    }
-
-    /**
-     * Add a "BCC" address.
-     *
-     * @param string $address The email address to send to
-     * @param string $name
-     *
-     * @throws Exception
-     *
-     * @return bool true on success, false if address already used or invalid in some way
-     */
-    public function addBCC($address, $name = '')
-    {
-        return $this->addOrEnqueueAnAddress('bcc', $address, $name);
-    }
-
-    /**
-     * Add a "Reply-To" address.
-     *
-     * @param string $address The email address to reply to
-     * @param string $name
-     *
-     * @throws Exception
-     *
-     * @return bool true on success, false if address already used or invalid in some way
-     */
-    public function addReplyTo($address, $name = '')
-    {
-        return $this->addOrEnqueueAnAddress('Reply-To', $address, $name);
-    }
-
-    /**
-     * Add an address to one of the recipient arrays or to the ReplyTo array. Because PHPMailer
-     * can't validate addresses with an IDN without knowing the PHPMailer::$CharSet (that can still
-     * be modified after calling this function), addition of such addresses is delayed until send().
-     * Addresses that have been added already return false, but do not throw exceptions.
-     *
-     * @param string $kind    One of 'to', 'cc', 'bcc', or 'Reply-To'
-     * @param string $address The email address
-     * @param string $name    An optional username associated with the address
-     *
-     * @throws Exception
-     *
-     * @return bool true on success, false if address already used or invalid in some way
-     */
-    protected function addOrEnqueueAnAddress($kind, $address, $name)
-    {
-        $pos = false;
-        if ($address !== null) {
-            $address = trim($address);
-            $pos = strrpos($address, '@');
-        }
-        if (false === $pos) {
-            //At-sign is missing.
-            $error_message = sprintf(
-                '%s (%s): %s',
-                $this->lang('invalid_address'),
-                $kind,
-                $address
-            );
-            $this->setError($error_message);
-            $this->edebug($error_message);
-            if ($this->exceptions) {
-                throw new Exception($error_message);
-            }
-
-            return false;
-        }
-        if ($name !== null && is_string($name)) {
-            $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
-        } else {
-            $name = '';
-        }
-        $params = [$kind, $address, $name];
-        //Enqueue addresses with IDN until we know the PHPMailer::$CharSet.
-        //Domain is assumed to be whatever is after the last @ symbol in the address
-        if (static::idnSupported() && $this->has8bitChars(substr($address, ++$pos))) {
-            if ('Reply-To' !== $kind) {
-                if (!array_key_exists($address, $this->RecipientsQueue)) {
-                    $this->RecipientsQueue[$address] = $params;
-
-                    return true;
-                }
-            } elseif (!array_key_exists($address, $this->ReplyToQueue)) {
-                $this->ReplyToQueue[$address] = $params;
-
-                return true;
-            }
-
-            return false;
-        }
-
-        //Immediately add standard addresses without IDN.
-        return call_user_func_array([$this, 'addAnAddress'], $params);
-    }
-
-    /**
-     * Set the boundaries to use for delimiting MIME parts.
-     * If you override this, ensure you set all 3 boundaries to unique values.
-     * The default boundaries include a "=_" sequence which cannot occur in quoted-printable bodies,
-     * as suggested by https://www.rfc-editor.org/rfc/rfc2045#section-6.7
-     *
-     * @return void
-     */
-    public function setBoundaries()
-    {
-        $this->uniqueid = $this->generateId();
-        $this->boundary[1] = 'b1=_' . $this->uniqueid;
-        $this->boundary[2] = 'b2=_' . $this->uniqueid;
-        $this->boundary[3] = 'b3=_' . $this->uniqueid;
-    }
-
-    /**
-     * Add an address to one of the recipient arrays or to the ReplyTo array.
-     * Addresses that have been added already return false, but do not throw exceptions.
-     *
-     * @param string $kind    One of 'to', 'cc', 'bcc', or 'ReplyTo'
-     * @param string $address The email address to send, resp. to reply to
-     * @param string $name
-     *
-     * @throws Exception
-     *
-     * @return bool true on success, false if address already used or invalid in some way
-     */
-    protected function addAnAddress($kind, $address, $name = '')
-    {
-        if (!in_array($kind, ['to', 'cc', 'bcc', 'Reply-To'])) {
-            $error_message = sprintf(
-                '%s: %s',
-                $this->lang('Invalid recipient kind'),
-                $kind
-            );
-            $this->setError($error_message);
-            $this->edebug($error_message);
-            if ($this->exceptions) {
-                throw new Exception($error_message);
-            }
-
-            return false;
-        }
-        if (!static::validateAddress($address)) {
-            $error_message = sprintf(
-                '%s (%s): %s',
-                $this->lang('invalid_address'),
-                $kind,
-                $address
-            );
-            $this->setError($error_message);
-            $this->edebug($error_message);
-            if ($this->exceptions) {
-                throw new Exception($error_message);
-            }
-
-            return false;
-        }
-        if ('Reply-To' !== $kind) {
-            if (!array_key_exists(strtolower($address), $this->all_recipients)) {
-                $this->{$kind}[] = [$address, $name];
-                $this->all_recipients[strtolower($address)] = true;
-
-                return true;
-            }
-        } elseif (!array_key_exists(strtolower($address), $this->ReplyTo)) {
-            $this->ReplyTo[strtolower($address)] = [$address, $name];
-
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Parse and validate a string containing one or more RFC822-style comma-separated email addresses
-     * of the form "display name <address>" into an array of name/address pairs.
-     * Uses the imap_rfc822_parse_adrlist function if the IMAP extension is available.
-     * Note that quotes in the name part are removed.
-     *
-     * @see https://www.andrew.cmu.edu/user/agreen1/testing/mrbs/web/Mail/RFC822.php A more careful implementation
-     *
-     * @param string $addrstr The address list string
-     * @param bool   $useimap Whether to use the IMAP extension to parse the list
-     * @param string $charset The charset to use when decoding the address list string.
-     *
-     * @return array
-     */
-    public static function parseAddresses($addrstr, $useimap = true, $charset = self::CHARSET_ISO88591)
-    {
-        $addresses = [];
-        if ($useimap && function_exists('imap_rfc822_parse_adrlist')) {
-            //Use this built-in parser if it's available
-            $list = imap_rfc822_parse_adrlist($addrstr, '');
-            // Clear any potential IMAP errors to get rid of notices being thrown at end of script.
-            imap_errors();
-            foreach ($list as $address) {
-                if (
-                    '.SYNTAX-ERROR.' !== $address->host &&
-                    static::validateAddress($address->mailbox . '@' . $address->host)
-                ) {
-                    //Decode the name part if it's present and encoded
-                    if (
-                        property_exists($address, 'personal') &&
-                        //Check for a Mbstring constant rather than using extension_loaded, which is sometimes disabled
-                        defined('MB_CASE_UPPER') &&
-                        preg_match('/^=\?.*\?=$/s', $address->personal)
-                    ) {
-                        $origCharset = mb_internal_encoding();
-                        mb_internal_encoding($charset);
-                        //Undo any RFC2047-encoded spaces-as-underscores
-                        $address->personal = str_replace('_', '=20', $address->personal);
-                        //Decode the name
-                        $address->personal = mb_decode_mimeheader($address->personal);
-                        mb_internal_encoding($origCharset);
-                    }
-
-                    $addresses[] = [
-                        'name' => (property_exists($address, 'personal') ? $address->personal : ''),
-                        'address' => $address->mailbox . '@' . $address->host,
-                    ];
-                }
-            }
-        } else {
-            //Use this simpler parser
-            $list = explode(',', $addrstr);
-            foreach ($list as $address) {
-                $address = trim($address);
-                //Is there a separate name part?
-                if (strpos($address, '<') === false) {
-                    //No separate name, just use the whole thing
-                    if (static::validateAddress($address)) {
-                        $addresses[] = [
-                            'name' => '',
-                            'address' => $address,
-                        ];
-                    }
-                } else {
-                    list($name, $email) = explode('<', $address);
-                    $email = trim(str_replace('>', '', $email));
-                    $name = trim($name);
-                    if (static::validateAddress($email)) {
-                        //Check for a Mbstring constant rather than using extension_loaded, which is sometimes disabled
-                        //If this name is encoded, decode it
-                        if (defined('MB_CASE_UPPER') && preg_match('/^=\?.*\?=$/s', $name)) {
-                            $origCharset = mb_internal_encoding();
-                            mb_internal_encoding($charset);
-                            //Undo any RFC2047-encoded spaces-as-underscores
-                            $name = str_replace('_', '=20', $name);
-                            //Decode the name
-                            $name = mb_decode_mimeheader($name);
-                            mb_internal_encoding($origCharset);
-                        }
-                        $addresses[] = [
-                            //Remove any surrounding quotes and spaces from the name
-                            'name' => trim($name, '\'" '),
-                            'address' => $email,
-                        ];
-                    }
-                }
-            }
-        }
-
-        return $addresses;
-    }
-
-    /**
-     * Set the From and FromName properties.
-     *
-     * @param string $address
-     * @param string $name
-     * @param bool   $auto    Whether to also set the Sender address, defaults to true
-     *
-     * @throws Exception
-     *
-     * @return bool
-     */
-    public function setFrom($address, $name = '', $auto = true)
-    {
-        $address = trim((string)$address);
-        $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
-        //Don't validate now addresses with IDN. Will be done in send().
-        $pos = strrpos($address, '@');
-        if (
-            (false === $pos)
-            || ((!$this->has8bitChars(substr($address, ++$pos)) || !static::idnSupported())
-            && !static::validateAddress($address))
-        ) {
-            $error_message = sprintf(
-                '%s (From): %s',
-                $this->lang('invalid_address'),
-                $address
-            );
-            $this->setError($error_message);
-            $this->edebug($error_message);
-            if ($this->exceptions) {
-                throw new Exception($error_message);
-            }
-
-            return false;
-        }
-        $this->From = $address;
-        $this->FromName = $name;
-        if ($auto && empty($this->Sender)) {
-            $this->Sender = $address;
-        }
-
-        return true;
-    }
-
-    /**
-     * Return the Message-ID header of the last email.
-     * Technically this is the value from the last time the headers were created,
-     * but it's also the message ID of the last sent message except in
-     * pathological cases.
-     *
-     * @return string
-     */
-    public function getLastMessageID()
-    {
-        return $this->lastMessageID;
-    }
-
-    /**
-     * Check that a string looks like an email address.
-     * Validation patterns supported:
-     * * `auto` Pick best pattern automatically;
-     * * `pcre8` Use the squiloople.com pattern, requires PCRE > 8.0;
-     * * `pcre` Use old PCRE implementation;
-     * * `php` Use PHP built-in FILTER_VALIDATE_EMAIL;
-     * * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements.
-     * * `noregex` Don't use a regex: super fast, really dumb.
-     * Alternatively you may pass in a callable to inject your own validator, for example:
-     *
-     * ```php
-     * PHPMailer::validateAddress('user@example.com', function($address) {
-     *     return (strpos($address, '@') !== false);
-     * });
-     * ```
-     *
-     * You can also set the PHPMailer::$validator static to a callable, allowing built-in methods to use your validator.
-     *
-     * @param string          $address       The email address to check
-     * @param string|callable $patternselect Which pattern to use
-     *
-     * @return bool
-     */
-    public static function validateAddress($address, $patternselect = null)
-    {
-        if (null === $patternselect) {
-            $patternselect = static::$validator;
-        }
-        //Don't allow strings as callables, see SECURITY.md and CVE-2021-3603
-        if (is_callable($patternselect) && !is_string($patternselect)) {
-            return call_user_func($patternselect, $address);
-        }
-        //Reject line breaks in addresses; it's valid RFC5322, but not RFC5321
-        if (strpos($address, "\n") !== false || strpos($address, "\r") !== false) {
-            return false;
-        }
-        switch ($patternselect) {
-            case 'pcre': //Kept for BC
-            case 'pcre8':
-                /*
-                 * A more complex and more permissive version of the RFC5322 regex on which FILTER_VALIDATE_EMAIL
-                 * is based.
-                 * In addition to the addresses allowed by filter_var, also permits:
-                 *  * dotless domains: `a@b`
-                 *  * comments: `1234 @ local(blah) .machine .example`
-                 *  * quoted elements: `'"test blah"@example.org'`
-                 *  * numeric TLDs: `a@b.123`
-                 *  * unbracketed IPv4 literals: `a@192.168.0.1`
-                 *  * IPv6 literals: 'first.last@[IPv6:a1::]'
-                 * Not all of these will necessarily work for sending!
-                 *
-                 * @copyright 2009-2010 Michael Rushton
-                 * Feel free to use and redistribute this code. But please keep this copyright notice.
-                 */
-                return (bool) preg_match(
-                    '/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)' .
-                    '((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)' .
-                    '(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)' .
-                    '([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*' .
-                    '(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)' .
-                    '(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}' .
-                    '|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:' .
-                    '|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}' .
-                    '|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD',
-                    $address
-                );
-            case 'html5':
-                /*
-                 * This is the pattern used in the HTML5 spec for validation of 'email' type form input elements.
-                 *
-                 * @see https://html.spec.whatwg.org/#e-mail-state-(type=email)
-                 */
-                return (bool) preg_match(
-                    '/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}' .
-                    '[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD',
-                    $address
-                );
-            case 'php':
-            default:
-                return filter_var($address, FILTER_VALIDATE_EMAIL) !== false;
-        }
-    }
-
-    /**
-     * Tells whether IDNs (Internationalized Domain Names) are supported or not. This requires the
-     * `intl` and `mbstring` PHP extensions.
-     *
-     * @return bool `true` if required functions for IDN support are present
-     */
-    public static function idnSupported()
-    {
-        return function_exists('idn_to_ascii') && function_exists('mb_convert_encoding');
-    }
-
-    /**
-     * Converts IDN in given email address to its ASCII form, also known as punycode, if possible.
-     * Important: Address must be passed in same encoding as currently set in PHPMailer::$CharSet.
-     * This function silently returns unmodified address if:
-     * - No conversion is necessary (i.e. domain name is not an IDN, or is already in ASCII form)
-     * - Conversion to punycode is impossible (e.g. required PHP functions are not available)
-     *   or fails for any reason (e.g. domain contains characters not allowed in an IDN).
-     *
-     * @see PHPMailer::$CharSet
-     *
-     * @param string $address The email address to convert
-     *
-     * @return string The encoded address in ASCII form
-     */
-    public function punyencodeAddress($address)
-    {
-        //Verify we have required functions, CharSet, and at-sign.
-        $pos = strrpos($address, '@');
-        if (
-            !empty($this->CharSet) &&
-            false !== $pos &&
-            static::idnSupported()
-        ) {
-            $domain = substr($address, ++$pos);
-            //Verify CharSet string is a valid one, and domain properly encoded in this CharSet.
-            if ($this->has8bitChars($domain) && @mb_check_encoding($domain, $this->CharSet)) {
-                //Convert the domain from whatever charset it's in to UTF-8
-                $domain = mb_convert_encoding($domain, self::CHARSET_UTF8, $this->CharSet);
-                //Ignore IDE complaints about this line - method signature changed in PHP 5.4
-                $errorcode = 0;
-                if (defined('INTL_IDNA_VARIANT_UTS46')) {
-                    //Use the current punycode standard (appeared in PHP 7.2)
-                    $punycode = idn_to_ascii(
-                        $domain,
-                        \IDNA_DEFAULT | \IDNA_USE_STD3_RULES | \IDNA_CHECK_BIDI |
-                            \IDNA_CHECK_CONTEXTJ | \IDNA_NONTRANSITIONAL_TO_ASCII,
-                        \INTL_IDNA_VARIANT_UTS46
-                    );
-                } elseif (defined('INTL_IDNA_VARIANT_2003')) {
-                    //Fall back to this old, deprecated/removed encoding
+class PHPMailer {
+
+	const CHARSET_ASCII    = 'us-ascii';
+	const CHARSET_ISO88591 = 'iso-8859-1';
+	const CHARSET_UTF8     = 'utf-8';
+
+	const CONTENT_TYPE_PLAINTEXT             = 'text/plain';
+	const CONTENT_TYPE_TEXT_CALENDAR         = 'text/calendar';
+	const CONTENT_TYPE_TEXT_HTML             = 'text/html';
+	const CONTENT_TYPE_MULTIPART_ALTERNATIVE = 'multipart/alternative';
+	const CONTENT_TYPE_MULTIPART_MIXED       = 'multipart/mixed';
+	const CONTENT_TYPE_MULTIPART_RELATED     = 'multipart/related';
+
+	const ENCODING_7BIT             = '7bit';
+	const ENCODING_8BIT             = '8bit';
+	const ENCODING_BASE64           = 'base64';
+	const ENCODING_BINARY           = 'binary';
+	const ENCODING_QUOTED_PRINTABLE = 'quoted-printable';
+
+	const ENCRYPTION_STARTTLS = 'tls';
+	const ENCRYPTION_SMTPS    = 'ssl';
+
+	const ICAL_METHOD_REQUEST        = 'REQUEST';
+	const ICAL_METHOD_PUBLISH        = 'PUBLISH';
+	const ICAL_METHOD_REPLY          = 'REPLY';
+	const ICAL_METHOD_ADD            = 'ADD';
+	const ICAL_METHOD_CANCEL         = 'CANCEL';
+	const ICAL_METHOD_REFRESH        = 'REFRESH';
+	const ICAL_METHOD_COUNTER        = 'COUNTER';
+	const ICAL_METHOD_DECLINECOUNTER = 'DECLINECOUNTER';
+
+	/**
+	 * Email priority.
+	 * Options: null (default), 1 = High, 3 = Normal, 5 = low.
+	 * When null, the header is not set at all.
+	 *
+	 * @var int|null
+	 */
+	public $Priority;
+
+	/**
+	 * The character set of the message.
+	 *
+	 * @var string
+	 */
+	public $CharSet = self::CHARSET_ISO88591;
+
+	/**
+	 * The MIME Content-type of the message.
+	 *
+	 * @var string
+	 */
+	public $ContentType = self::CONTENT_TYPE_PLAINTEXT;
+
+	/**
+	 * The message encoding.
+	 * Options: "8bit", "7bit", "binary", "base64", and "quoted-printable".
+	 *
+	 * @var string
+	 */
+	public $Encoding = self::ENCODING_8BIT;
+
+	/**
+	 * Holds the most recent mailer error message.
+	 *
+	 * @var string
+	 */
+	public $ErrorInfo = '';
+
+	/**
+	 * The From email address for the message.
+	 *
+	 * @var string
+	 */
+	public $From = '';
+
+	/**
+	 * The From name of the message.
+	 *
+	 * @var string
+	 */
+	public $FromName = '';
+
+	/**
+	 * The envelope sender of the message.
+	 * This will usually be turned into a Return-Path header by the receiver,
+	 * and is the address that bounces will be sent to.
+	 * If not empty, will be passed via `-f` to sendmail or as the 'MAIL FROM' value over SMTP.
+	 *
+	 * @var string
+	 */
+	public $Sender = '';
+
+	/**
+	 * The Subject of the message.
+	 *
+	 * @var string
+	 */
+	public $Subject = '';
+
+	/**
+	 * An HTML or plain text message body.
+	 * If HTML then call isHTML(true).
+	 *
+	 * @var string
+	 */
+	public $Body = '';
+
+	/**
+	 * The plain-text message body.
+	 * This body can be read by mail clients that do not have HTML email
+	 * capability such as mutt & Eudora.
+	 * Clients that can read HTML will view the normal Body.
+	 *
+	 * @var string
+	 */
+	public $AltBody = '';
+
+	/**
+	 * An iCal message part body.
+	 * Only supported in simple alt or alt_inline message types
+	 * To generate iCal event structures, use classes like EasyPeasyICS or iCalcreator.
+	 *
+	 * @see https://kigkonsult.se/iCalcreator/
+	 *
+	 * @var string
+	 */
+	public $Ical = '';
+
+	/**
+	 * Value-array of "method" in Contenttype header "text/calendar"
+	 *
+	 * @var string[]
+	 */
+	protected static $IcalMethods = array(
+		self::ICAL_METHOD_REQUEST,
+		self::ICAL_METHOD_PUBLISH,
+		self::ICAL_METHOD_REPLY,
+		self::ICAL_METHOD_ADD,
+		self::ICAL_METHOD_CANCEL,
+		self::ICAL_METHOD_REFRESH,
+		self::ICAL_METHOD_COUNTER,
+		self::ICAL_METHOD_DECLINECOUNTER,
+	);
+
+	/**
+	 * The complete compiled MIME message body.
+	 *
+	 * @var string
+	 */
+	protected $MIMEBody = '';
+
+	/**
+	 * The complete compiled MIME message headers.
+	 *
+	 * @var string
+	 */
+	protected $MIMEHeader = '';
+
+	/**
+	 * Extra headers that createHeader() doesn't fold in.
+	 *
+	 * @var string
+	 */
+	protected $mailHeader = '';
+
+	/**
+	 * Word-wrap the message body to this number of chars.
+	 * Set to 0 to not wrap. A useful value here is 78, for RFC2822 section 2.1.1 compliance.
+	 *
+	 * @see static::STD_LINE_LENGTH
+	 *
+	 * @var int
+	 */
+	public $WordWrap = 0;
+
+	/**
+	 * Which method to use to send mail.
+	 * Options: "mail", "sendmail", or "smtp".
+	 *
+	 * @var string
+	 */
+	public $Mailer = 'mail';
+
+	/**
+	 * The path to the sendmail program.
+	 *
+	 * @var string
+	 */
+	public $Sendmail = '/usr/sbin/sendmail';
+
+	/**
+	 * Whether mail() uses a fully sendmail-compatible MTA.
+	 * One which supports sendmail's "-oi -f" options.
+	 *
+	 * @var bool
+	 */
+	public $UseSendmailOptions = true;
+
+	/**
+	 * The email address that a reading confirmation should be sent to, also known as read receipt.
+	 *
+	 * @var string
+	 */
+	public $ConfirmReadingTo = '';
+
+	/**
+	 * The hostname to use in the Message-ID header and as default HELO string.
+	 * If empty, PHPMailer attempts to find one with, in order,
+	 * $_SERVER['SERVER_NAME'], gethostname(), php_uname('n'), or the value
+	 * 'localhost.localdomain'.
+	 *
+	 * @see PHPMailer::$Helo
+	 *
+	 * @var string
+	 */
+	public $Hostname = '';
+
+	/**
+	 * An ID to be used in the Message-ID header.
+	 * If empty, a unique id will be generated.
+	 * You can set your own, but it must be in the format "<id@domain>",
+	 * as defined in RFC5322 section 3.6.4 or it will be ignored.
+	 *
+	 * @see https://www.rfc-editor.org/rfc/rfc5322#section-3.6.4
+	 *
+	 * @var string
+	 */
+	public $MessageID = '';
+
+	/**
+	 * The message Date to be used in the Date header.
+	 * If empty, the current date will be added.
+	 *
+	 * @var string
+	 */
+	public $MessageDate = '';
+
+	/**
+	 * SMTP hosts.
+	 * Either a single hostname or multiple semicolon-delimited hostnames.
+	 * You can also specify a different port
+	 * for each host by using this format: [hostname:port]
+	 * (e.g. "smtp1.example.com:25;smtp2.example.com").
+	 * You can also specify encryption type, for example:
+	 * (e.g. "tls://smtp1.example.com:587;ssl://smtp2.example.com:465").
+	 * Hosts will be tried in order.
+	 *
+	 * @var string
+	 */
+	public $Host = 'localhost';
+
+	/**
+	 * The default SMTP server port.
+	 *
+	 * @var int
+	 */
+	public $Port = 25;
+
+	/**
+	 * The SMTP HELO/EHLO name used for the SMTP connection.
+	 * Default is $Hostname. If $Hostname is empty, PHPMailer attempts to find
+	 * one with the same method described above for $Hostname.
+	 *
+	 * @see PHPMailer::$Hostname
+	 *
+	 * @var string
+	 */
+	public $Helo = '';
+
+	/**
+	 * What kind of encryption to use on the SMTP connection.
+	 * Options: '', static::ENCRYPTION_STARTTLS, or static::ENCRYPTION_SMTPS.
+	 *
+	 * @var string
+	 */
+	public $SMTPSecure = '';
+
+	/**
+	 * Whether to enable TLS encryption automatically if a server supports it,
+	 * even if `SMTPSecure` is not set to 'tls'.
+	 * Be aware that in PHP >= 5.6 this requires that the server's certificates are valid.
+	 *
+	 * @var bool
+	 */
+	public $SMTPAutoTLS = true;
+
+	/**
+	 * Whether to use SMTP authentication.
+	 * Uses the Username and Password properties.
+	 *
+	 * @see PHPMailer::$Username
+	 * @see PHPMailer::$Password
+	 *
+	 * @var bool
+	 */
+	public $SMTPAuth = false;
+
+	/**
+	 * Options array passed to stream_context_create when connecting via SMTP.
+	 *
+	 * @var array
+	 */
+	public $SMTPOptions = array();
+
+	/**
+	 * SMTP username.
+	 *
+	 * @var string
+	 */
+	public $Username = '';
+
+	/**
+	 * SMTP password.
+	 *
+	 * @var string
+	 */
+	public $Password = '';
+
+	/**
+	 * SMTP authentication type. Options are CRAM-MD5, LOGIN, PLAIN, XOAUTH2.
+	 * If not specified, the first one from that list that the server supports will be selected.
+	 *
+	 * @var string
+	 */
+	public $AuthType = '';
+
+	/**
+	 * SMTP SMTPXClient command attributes
+	 *
+	 * @var array
+	 */
+	protected $SMTPXClient = array();
+
+	/**
+	 * An implementation of the PHPMailer OAuthTokenProvider interface.
+	 *
+	 * @var OAuthTokenProvider
+	 */
+	protected $oauth;
+
+	/**
+	 * The SMTP server timeout in seconds.
+	 * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2.
+	 *
+	 * @var int
+	 */
+	public $Timeout = 300;
+
+	/**
+	 * Comma separated list of DSN notifications
+	 * 'NEVER' under no circumstances a DSN must be returned to the sender.
+	 *         If you use NEVER all other notifications will be ignored.
+	 * 'SUCCESS' will notify you when your mail has arrived at its destination.
+	 * 'FAILURE' will arrive if an error occurred during delivery.
+	 * 'DELAY'   will notify you if there is an unusual delay in delivery, but the actual
+	 *           delivery's outcome (success or failure) is not yet decided.
+	 *
+	 * @see https://www.rfc-editor.org/rfc/rfc3461.html#section-4.1 for more information about NOTIFY
+	 */
+	public $dsn = '';
+
+	/**
+	 * SMTP class debug output mode.
+	 * Debug output level.
+	 * Options:
+	 *
+	 * @see SMTP::DEBUG_OFF: No output
+	 * @see SMTP::DEBUG_CLIENT: Client messages
+	 * @see SMTP::DEBUG_SERVER: Client and server messages
+	 * @see SMTP::DEBUG_CONNECTION: As SERVER plus connection status
+	 * @see SMTP::DEBUG_LOWLEVEL: Noisy, low-level data output, rarely needed
+	 *
+	 * @see SMTP::$do_debug
+	 *
+	 * @var int
+	 */
+	public $SMTPDebug = 0;
+
+	/**
+	 * How to handle debug output.
+	 * Options:
+	 * * `echo` Output plain-text as-is, appropriate for CLI
+	 * * `html` Output escaped, line breaks converted to `<br>`, appropriate for browser output
+	 * * `error_log` Output to error log as configured in php.ini
+	 * By default PHPMailer will use `echo` if run from a `cli` or `cli-server` SAPI, `html` otherwise.
+	 * Alternatively, you can provide a callable expecting two params: a message string and the debug level:
+	 *
+	 * ```php
+	 * $mail->Debugoutput = function($str, $level) {echo "debug level $level; message: $str";};
+	 * ```
+	 *
+	 * Alternatively, you can pass in an instance of a PSR-3 compatible logger, though only `debug`
+	 * level output is used:
+	 *
+	 * ```php
+	 * $mail->Debugoutput = new myPsr3Logger;
+	 * ```
+	 *
+	 * @see SMTP::$Debugoutput
+	 *
+	 * @var string|callable|\Psr\Log\LoggerInterface
+	 */
+	public $Debugoutput = 'echo';
+
+	/**
+	 * Whether to keep the SMTP connection open after each message.
+	 * If this is set to true then the connection will remain open after a send,
+	 * and closing the connection will require an explicit call to smtpClose().
+	 * It's a good idea to use this if you are sending multiple messages as it reduces overhead.
+	 * See the mailing list example for how to use it.
+	 *
+	 * @var bool
+	 */
+	public $SMTPKeepAlive = false;
+
+	/**
+	 * Whether to split multiple to addresses into multiple messages
+	 * or send them all in one message.
+	 * Only supported in `mail` and `sendmail` transports, not in SMTP.
+	 *
+	 * @var bool
+	 *
+	 * @deprecated 6.0.0 PHPMailer isn't a mailing list manager!
+	 */
+	public $SingleTo = false;
+
+	/**
+	 * Storage for addresses when SingleTo is enabled.
+	 *
+	 * @var array
+	 */
+	protected $SingleToArray = array();
+
+	/**
+	 * Whether to generate VERP addresses on send.
+	 * Only applicable when sending via SMTP.
+	 *
+	 * @see https://en.wikipedia.org/wiki/Variable_envelope_return_path
+	 * @see https://www.postfix.org/VERP_README.html Postfix VERP info
+	 *
+	 * @var bool
+	 */
+	public $do_verp = false;
+
+	/**
+	 * Whether to allow sending messages with an empty body.
+	 *
+	 * @var bool
+	 */
+	public $AllowEmpty = false;
+
+	/**
+	 * DKIM selector.
+	 *
+	 * @var string
+	 */
+	public $DKIM_selector = '';
+
+	/**
+	 * DKIM Identity.
+	 * Usually the email address used as the source of the email.
+	 *
+	 * @var string
+	 */
+	public $DKIM_identity = '';
+
+	/**
+	 * DKIM passphrase.
+	 * Used if your key is encrypted.
+	 *
+	 * @var string
+	 */
+	public $DKIM_passphrase = '';
+
+	/**
+	 * DKIM signing domain name.
+	 *
+	 * @example 'example.com'
+	 *
+	 * @var string
+	 */
+	public $DKIM_domain = '';
+
+	/**
+	 * DKIM Copy header field values for diagnostic use.
+	 *
+	 * @var bool
+	 */
+	public $DKIM_copyHeaderFields = true;
+
+	/**
+	 * DKIM Extra signing headers.
+	 *
+	 * @example ['List-Unsubscribe', 'List-Help']
+	 *
+	 * @var array
+	 */
+	public $DKIM_extraHeaders = array();
+
+	/**
+	 * DKIM private key file path.
+	 *
+	 * @var string
+	 */
+	public $DKIM_private = '';
+
+	/**
+	 * DKIM private key string.
+	 *
+	 * If set, takes precedence over `$DKIM_private`.
+	 *
+	 * @var string
+	 */
+	public $DKIM_private_string = '';
+
+	/**
+	 * Callback Action function name.
+	 *
+	 * The function that handles the result of the send email action.
+	 * It is called out by send() for each email sent.
+	 *
+	 * Value can be any php callable: https://www.php.net/is_callable
+	 *
+	 * Parameters:
+	 *   bool $result           result of the send action
+	 *   array   $to            email addresses of the recipients
+	 *   array   $cc            cc email addresses
+	 *   array   $bcc           bcc email addresses
+	 *   string  $subject       the subject
+	 *   string  $body          the email body
+	 *   string  $from          email address of sender
+	 *   string  $extra         extra information of possible use
+	 *                          "smtp_transaction_id' => last smtp transaction id
+	 *
+	 * @var string
+	 */
+	public $action_function = '';
+
+	/**
+	 * What to put in the X-Mailer header.
+	 * Options: An empty string for PHPMailer default, whitespace/null for none, or a string to use.
+	 *
+	 * @var string|null
+	 */
+	public $XMailer = '';
+
+	/**
+	 * Which validator to use by default when validating email addresses.
+	 * May be a callable to inject your own validator, but there are several built-in validators.
+	 * The default validator uses PHP's FILTER_VALIDATE_EMAIL filter_var option.
+	 *
+	 * @see PHPMailer::validateAddress()
+	 *
+	 * @var string|callable
+	 */
+	public static $validator = 'php';
+
+	/**
+	 * An instance of the SMTP sender class.
+	 *
+	 * @var SMTP
+	 */
+	protected $smtp;
+
+	/**
+	 * The array of 'to' names and addresses.
+	 *
+	 * @var array
+	 */
+	protected $to = array();
+
+	/**
+	 * The array of 'cc' names and addresses.
+	 *
+	 * @var array
+	 */
+	protected $cc = array();
+
+	/**
+	 * The array of 'bcc' names and addresses.
+	 *
+	 * @var array
+	 */
+	protected $bcc = array();
+
+	/**
+	 * The array of reply-to names and addresses.
+	 *
+	 * @var array
+	 */
+	protected $ReplyTo = array();
+
+	/**
+	 * An array of all kinds of addresses.
+	 * Includes all of $to, $cc, $bcc.
+	 *
+	 * @see PHPMailer::$to
+	 * @see PHPMailer::$cc
+	 * @see PHPMailer::$bcc
+	 *
+	 * @var array
+	 */
+	protected $all_recipients = array();
+
+	/**
+	 * An array of names and addresses queued for validation.
+	 * In send(), valid and non duplicate entries are moved to $all_recipients
+	 * and one of $to, $cc, or $bcc.
+	 * This array is used only for addresses with IDN.
+	 *
+	 * @see PHPMailer::$to
+	 * @see PHPMailer::$cc
+	 * @see PHPMailer::$bcc
+	 * @see PHPMailer::$all_recipients
+	 *
+	 * @var array
+	 */
+	protected $RecipientsQueue = array();
+
+	/**
+	 * An array of reply-to names and addresses queued for validation.
+	 * In send(), valid and non duplicate entries are moved to $ReplyTo.
+	 * This array is used only for addresses with IDN.
+	 *
+	 * @see PHPMailer::$ReplyTo
+	 *
+	 * @var array
+	 */
+	protected $ReplyToQueue = array();
+
+	/**
+	 * The array of attachments.
+	 *
+	 * @var array
+	 */
+	protected $attachment = array();
+
+	/**
+	 * The array of custom headers.
+	 *
+	 * @var array
+	 */
+	protected $CustomHeader = array();
+
+	/**
+	 * The most recent Message-ID (including angular brackets).
+	 *
+	 * @var string
+	 */
+	protected $lastMessageID = '';
+
+	/**
+	 * The message's MIME type.
+	 *
+	 * @var string
+	 */
+	protected $message_type = '';
+
+	/**
+	 * The array of MIME boundary strings.
+	 *
+	 * @var array
+	 */
+	protected $boundary = array();
+
+	/**
+	 * The array of available text strings for the current language.
+	 *
+	 * @var array
+	 */
+	protected $language = array();
+
+	/**
+	 * The number of errors encountered.
+	 *
+	 * @var int
+	 */
+	protected $error_count = 0;
+
+	/**
+	 * The S/MIME certificate file path.
+	 *
+	 * @var string
+	 */
+	protected $sign_cert_file = '';
+
+	/**
+	 * The S/MIME key file path.
+	 *
+	 * @var string
+	 */
+	protected $sign_key_file = '';
+
+	/**
+	 * The optional S/MIME extra certificates ("CA Chain") file path.
+	 *
+	 * @var string
+	 */
+	protected $sign_extracerts_file = '';
+
+	/**
+	 * The S/MIME password for the key.
+	 * Used only if the key is encrypted.
+	 *
+	 * @var string
+	 */
+	protected $sign_key_pass = '';
+
+	/**
+	 * Whether to throw exceptions for errors.
+	 *
+	 * @var bool
+	 */
+	protected $exceptions = false;
+
+	/**
+	 * Unique ID used for message ID and boundaries.
+	 *
+	 * @var string
+	 */
+	protected $uniqueid = '';
+
+	/**
+	 * The PHPMailer Version number.
+	 *
+	 * @var string
+	 */
+	const VERSION = '6.9.3';
+
+	/**
+	 * Error severity: message only, continue processing.
+	 *
+	 * @var int
+	 */
+	const STOP_MESSAGE = 0;
+
+	/**
+	 * Error severity: message, likely ok to continue processing.
+	 *
+	 * @var int
+	 */
+	const STOP_CONTINUE = 1;
+
+	/**
+	 * Error severity: message, plus full stop, critical error reached.
+	 *
+	 * @var int
+	 */
+	const STOP_CRITICAL = 2;
+
+	/**
+	 * The SMTP standard CRLF line break.
+	 * If you want to change line break format, change static::$LE, not this.
+	 */
+	const CRLF = "\r\n";
+
+	/**
+	 * "Folding White Space" a white space string used for line folding.
+	 */
+	const FWS = ' ';
+
+	/**
+	 * SMTP RFC standard line ending; Carriage Return, Line Feed.
+	 *
+	 * @var string
+	 */
+	protected static $LE = self::CRLF;
+
+	/**
+	 * The maximum line length supported by mail().
+	 *
+	 * Background: mail() will sometimes corrupt messages
+	 * with headers longer than 65 chars, see #818.
+	 *
+	 * @var int
+	 */
+	const MAIL_MAX_LINE_LENGTH = 63;
+
+	/**
+	 * The maximum line length allowed by RFC 2822 section 2.1.1.
+	 *
+	 * @var int
+	 */
+	const MAX_LINE_LENGTH = 998;
+
+	/**
+	 * The lower maximum line length allowed by RFC 2822 section 2.1.1.
+	 * This length does NOT include the line break
+	 * 76 means that lines will be 77 or 78 chars depending on whether
+	 * the line break format is LF or CRLF; both are valid.
+	 *
+	 * @var int
+	 */
+	const STD_LINE_LENGTH = 76;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param bool $exceptions Should we throw external exceptions?
+	 */
+	public function __construct( $exceptions = null ) {
+		if ( null !== $exceptions ) {
+			$this->exceptions = (bool) $exceptions;
+		}
+		// Pick an appropriate debug output format automatically
+		$this->Debugoutput = ( strpos( PHP_SAPI, 'cli' ) !== false ? 'echo' : 'html' );
+	}
+
+	/**
+	 * Destructor.
+	 */
+	public function __destruct() {
+		// Close any open SMTP connection nicely
+		$this->smtpClose();
+	}
+
+	/**
+	 * Call mail() in a safe_mode-aware fashion.
+	 * Also, unless sendmail_path points to sendmail (or something that
+	 * claims to be sendmail), don't pass params (not a perfect fix,
+	 * but it will do).
+	 *
+	 * @param string      $to      To
+	 * @param string      $subject Subject
+	 * @param string      $body    Message Body
+	 * @param string      $header  Additional Header(s)
+	 * @param string|null $params  Params
+	 *
+	 * @return bool
+	 */
+	private function mailPassthru( $to, $subject, $body, $header, $params ) {
+		// Check overloading of mail function to avoid double-encoding
+		if ( (int) ini_get( 'mbstring.func_overload' ) & 1 ) { // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.mbstring_func_overloadDeprecated
+			$subject = $this->secureHeader( $subject );
+		} else {
+			$subject = $this->encodeHeader( $this->secureHeader( $subject ) );
+		}
+		// Calling mail() with null params breaks
+		$this->edebug( 'Sending with mail()' );
+		$this->edebug( 'Sendmail path: ' . ini_get( 'sendmail_path' ) );
+		$this->edebug( "Envelope sender: {$this->Sender}" );
+		$this->edebug( "To: {$to}" );
+		$this->edebug( "Subject: {$subject}" );
+		$this->edebug( "Headers: {$header}" );
+		if ( ! $this->UseSendmailOptions || null === $params ) {
+			$result = @mail( $to, $subject, $body, $header );
+		} else {
+			$this->edebug( "Additional params: {$params}" );
+			$result = @mail( $to, $subject, $body, $header, $params );
+		}
+		$this->edebug( 'Result: ' . ( $result ? 'true' : 'false' ) );
+		return $result;
+	}
+
+	/**
+	 * Output debugging info via a user-defined method.
+	 * Only generates output if debug output is enabled.
+	 *
+	 * @see PHPMailer::$Debugoutput
+	 * @see PHPMailer::$SMTPDebug
+	 *
+	 * @param string $str
+	 */
+	protected function edebug( $str ) {
+		if ( $this->SMTPDebug <= 0 ) {
+			return;
+		}
+		// Is this a PSR-3 logger?
+		if ( $this->Debugoutput instanceof \Psr\Log\LoggerInterface ) {
+			$this->Debugoutput->debug( rtrim( $str, "\r\n" ) );
+
+			return;
+		}
+		// Avoid clash with built-in function names
+		if ( is_callable( $this->Debugoutput ) && ! in_array( $this->Debugoutput, array( 'error_log', 'html', 'echo' ) ) ) {
+			call_user_func( $this->Debugoutput, $str, $this->SMTPDebug );
+
+			return;
+		}
+		switch ( $this->Debugoutput ) {
+			case 'error_log':
+				// Don't output, just log
+				/** @noinspection ForgottenDebugOutputInspection */
+				error_log( $str );
+				break;
+			case 'html':
+				// Cleans up output a bit for a better looking, HTML-safe output
+				echo htmlentities(
+					preg_replace( '/[\r\n]+/', '', $str ),
+					ENT_QUOTES,
+					'UTF-8'
+				), "<br>\n";
+				break;
+			case 'echo':
+			default:
+				// Normalize line breaks
+				$str = preg_replace( '/\r\n|\r/m', "\n", $str );
+				echo gmdate( 'Y-m-d H:i:s' ),
+				"\t",
+					// Trim trailing space
+				trim(
+					// Indent for readability, except for trailing break
+					str_replace(
+						"\n",
+						"\n                   \t                  ",
+						trim( $str )
+					)
+				),
+				"\n";
+		}
+	}
+
+	/**
+	 * Sets message type to HTML or plain.
+	 *
+	 * @param bool $isHtml True for HTML mode
+	 */
+	public function isHTML( $isHtml = true ) {
+		if ( $isHtml ) {
+			$this->ContentType = static::CONTENT_TYPE_TEXT_HTML;
+		} else {
+			$this->ContentType = static::CONTENT_TYPE_PLAINTEXT;
+		}
+	}
+
+	/**
+	 * Send messages using SMTP.
+	 */
+	public function isSMTP() {
+		$this->Mailer = 'smtp';
+	}
+
+	/**
+	 * Send messages using PHP's mail() function.
+	 */
+	public function isMail() {
+		$this->Mailer = 'mail';
+	}
+
+	/**
+	 * Send messages using $Sendmail.
+	 */
+	public function isSendmail() {
+		$ini_sendmail_path = ini_get( 'sendmail_path' );
+
+		if ( false === stripos( $ini_sendmail_path, 'sendmail' ) ) {
+			$this->Sendmail = '/usr/sbin/sendmail';
+		} else {
+			$this->Sendmail = $ini_sendmail_path;
+		}
+		$this->Mailer = 'sendmail';
+	}
+
+	/**
+	 * Send messages using qmail.
+	 */
+	public function isQmail() {
+		$ini_sendmail_path = ini_get( 'sendmail_path' );
+
+		if ( false === stripos( $ini_sendmail_path, 'qmail' ) ) {
+			$this->Sendmail = '/var/qmail/bin/qmail-inject';
+		} else {
+			$this->Sendmail = $ini_sendmail_path;
+		}
+		$this->Mailer = 'qmail';
+	}
+
+	/**
+	 * Add a "To" address.
+	 *
+	 * @param string $address The email address to send to
+	 * @param string $name
+	 *
+	 * @throws Exception
+	 *
+	 * @return bool true on success, false if address already used or invalid in some way
+	 */
+	public function addAddress( $address, $name = '' ) {
+		return $this->addOrEnqueueAnAddress( 'to', $address, $name );
+	}
+
+	/**
+	 * Add a "CC" address.
+	 *
+	 * @param string $address The email address to send to
+	 * @param string $name
+	 *
+	 * @throws Exception
+	 *
+	 * @return bool true on success, false if address already used or invalid in some way
+	 */
+	public function addCC( $address, $name = '' ) {
+		return $this->addOrEnqueueAnAddress( 'cc', $address, $name );
+	}
+
+	/**
+	 * Add a "BCC" address.
+	 *
+	 * @param string $address The email address to send to
+	 * @param string $name
+	 *
+	 * @throws Exception
+	 *
+	 * @return bool true on success, false if address already used or invalid in some way
+	 */
+	public function addBCC( $address, $name = '' ) {
+		return $this->addOrEnqueueAnAddress( 'bcc', $address, $name );
+	}
+
+	/**
+	 * Add a "Reply-To" address.
+	 *
+	 * @param string $address The email address to reply to
+	 * @param string $name
+	 *
+	 * @throws Exception
+	 *
+	 * @return bool true on success, false if address already used or invalid in some way
+	 */
+	public function addReplyTo( $address, $name = '' ) {
+		return $this->addOrEnqueueAnAddress( 'Reply-To', $address, $name );
+	}
+
+	/**
+	 * Add an address to one of the recipient arrays or to the ReplyTo array. Because PHPMailer
+	 * can't validate addresses with an IDN without knowing the PHPMailer::$CharSet (that can still
+	 * be modified after calling this function), addition of such addresses is delayed until send().
+	 * Addresses that have been added already return false, but do not throw exceptions.
+	 *
+	 * @param string $kind    One of 'to', 'cc', 'bcc', or 'Reply-To'
+	 * @param string $address The email address
+	 * @param string $name    An optional username associated with the address
+	 *
+	 * @throws Exception
+	 *
+	 * @return bool true on success, false if address already used or invalid in some way
+	 */
+	protected function addOrEnqueueAnAddress( $kind, $address, $name ) {
+		$pos = false;
+		if ( $address !== null ) {
+			$address = trim( $address );
+			$pos     = strrpos( $address, '@' );
+		}
+		if ( false === $pos ) {
+			// At-sign is missing.
+			$error_message = sprintf(
+				'%s (%s): %s',
+				$this->lang( 'invalid_address' ),
+				$kind,
+				$address
+			);
+			$this->setError( $error_message );
+			$this->edebug( $error_message );
+			if ( $this->exceptions ) {
+				throw new Exception( $error_message );
+			}
+
+			return false;
+		}
+		if ( $name !== null && is_string( $name ) ) {
+			$name = trim( preg_replace( '/[\r\n]+/', '', $name ) ); // Strip breaks and trim
+		} else {
+			$name = '';
+		}
+		$params = array( $kind, $address, $name );
+		// Enqueue addresses with IDN until we know the PHPMailer::$CharSet.
+		// Domain is assumed to be whatever is after the last @ symbol in the address
+		if ( static::idnSupported() && $this->has8bitChars( substr( $address, ++$pos ) ) ) {
+			if ( 'Reply-To' !== $kind ) {
+				if ( ! array_key_exists( $address, $this->RecipientsQueue ) ) {
+					$this->RecipientsQueue[ $address ] = $params;
+
+					return true;
+				}
+			} elseif ( ! array_key_exists( $address, $this->ReplyToQueue ) ) {
+				$this->ReplyToQueue[ $address ] = $params;
+
+				return true;
+			}
+
+			return false;
+		}
+
+		// Immediately add standard addresses without IDN.
+		return call_user_func_array( array( $this, 'addAnAddress' ), $params );
+	}
+
+	/**
+	 * Set the boundaries to use for delimiting MIME parts.
+	 * If you override this, ensure you set all 3 boundaries to unique values.
+	 * The default boundaries include a "=_" sequence which cannot occur in quoted-printable bodies,
+	 * as suggested by https://www.rfc-editor.org/rfc/rfc2045#section-6.7
+	 *
+	 * @return void
+	 */
+	public function setBoundaries() {
+		$this->uniqueid    = $this->generateId();
+		$this->boundary[1] = 'b1=_' . $this->uniqueid;
+		$this->boundary[2] = 'b2=_' . $this->uniqueid;
+		$this->boundary[3] = 'b3=_' . $this->uniqueid;
+	}
+
+	/**
+	 * Add an address to one of the recipient arrays or to the ReplyTo array.
+	 * Addresses that have been added already return false, but do not throw exceptions.
+	 *
+	 * @param string $kind    One of 'to', 'cc', 'bcc', or 'ReplyTo'
+	 * @param string $address The email address to send, resp. to reply to
+	 * @param string $name
+	 *
+	 * @throws Exception
+	 *
+	 * @return bool true on success, false if address already used or invalid in some way
+	 */
+	protected function addAnAddress( $kind, $address, $name = '' ) {
+		if ( ! in_array( $kind, array( 'to', 'cc', 'bcc', 'Reply-To' ) ) ) {
+			$error_message = sprintf(
+				'%s: %s',
+				$this->lang( 'Invalid recipient kind' ),
+				$kind
+			);
+			$this->setError( $error_message );
+			$this->edebug( $error_message );
+			if ( $this->exceptions ) {
+				throw new Exception( $error_message );
+			}
+
+			return false;
+		}
+		if ( ! static::validateAddress( $address ) ) {
+			$error_message = sprintf(
+				'%s (%s): %s',
+				$this->lang( 'invalid_address' ),
+				$kind,
+				$address
+			);
+			$this->setError( $error_message );
+			$this->edebug( $error_message );
+			if ( $this->exceptions ) {
+				throw new Exception( $error_message );
+			}
+
+			return false;
+		}
+		if ( 'Reply-To' !== $kind ) {
+			if ( ! array_key_exists( strtolower( $address ), $this->all_recipients ) ) {
+				$this->{$kind}[]                                = array( $address, $name );
+				$this->all_recipients[ strtolower( $address ) ] = true;
+
+				return true;
+			}
+		} elseif ( ! array_key_exists( strtolower( $address ), $this->ReplyTo ) ) {
+			$this->ReplyTo[ strtolower( $address ) ] = array( $address, $name );
+
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * Parse and validate a string containing one or more RFC822-style comma-separated email addresses
+	 * of the form "display name <address>" into an array of name/address pairs.
+	 * Uses the imap_rfc822_parse_adrlist function if the IMAP extension is available.
+	 * Note that quotes in the name part are removed.
+	 *
+	 * @see https://www.andrew.cmu.edu/user/agreen1/testing/mrbs/web/Mail/RFC822.php A more careful implementation
+	 *
+	 * @param string $addrstr The address list string
+	 * @param bool   $useimap Whether to use the IMAP extension to parse the list
+	 * @param string $charset The charset to use when decoding the address list string.
+	 *
+	 * @return array
+	 */
+	public static function parseAddresses( $addrstr, $useimap = true, $charset = self::CHARSET_ISO88591 ) {
+		$addresses = array();
+		if ( $useimap && function_exists( 'imap_rfc822_parse_adrlist' ) ) {
+			// Use this built-in parser if it's available
+			$list = imap_rfc822_parse_adrlist( $addrstr, '' );
+			// Clear any potential IMAP errors to get rid of notices being thrown at end of script.
+			imap_errors();
+			foreach ( $list as $address ) {
+				if (
+					'.SYNTAX-ERROR.' !== $address->host &&
+					static::validateAddress( $address->mailbox . '@' . $address->host )
+				) {
+					// Decode the name part if it's present and encoded
+					if (
+						property_exists( $address, 'personal' ) &&
+						// Check for a Mbstring constant rather than using extension_loaded, which is sometimes disabled
+						defined( 'MB_CASE_UPPER' ) &&
+						preg_match( '/^=\?.*\?=$/s', $address->personal )
+					) {
+						$origCharset = mb_internal_encoding();
+						mb_internal_encoding( $charset );
+						// Undo any RFC2047-encoded spaces-as-underscores
+						$address->personal = str_replace( '_', '=20', $address->personal );
+						// Decode the name
+						$address->personal = mb_decode_mimeheader( $address->personal );
+						mb_internal_encoding( $origCharset );
+					}
+
+					$addresses[] = array(
+						'name'    => ( property_exists( $address, 'personal' ) ? $address->personal : '' ),
+						'address' => $address->mailbox . '@' . $address->host,
+					);
+				}
+			}
+		} else {
+			// Use this simpler parser
+			$list = explode( ',', $addrstr );
+			foreach ( $list as $address ) {
+				$address = trim( $address );
+				// Is there a separate name part?
+				if ( strpos( $address, '<' ) === false ) {
+					// No separate name, just use the whole thing
+					if ( static::validateAddress( $address ) ) {
+						$addresses[] = array(
+							'name'    => '',
+							'address' => $address,
+						);
+					}
+				} else {
+					list($name, $email) = explode( '<', $address );
+					$email              = trim( str_replace( '>', '', $email ) );
+					$name               = trim( $name );
+					if ( static::validateAddress( $email ) ) {
+						// Check for a Mbstring constant rather than using extension_loaded, which is sometimes disabled
+						// If this name is encoded, decode it
+						if ( defined( 'MB_CASE_UPPER' ) && preg_match( '/^=\?.*\?=$/s', $name ) ) {
+							$origCharset = mb_internal_encoding();
+							mb_internal_encoding( $charset );
+							// Undo any RFC2047-encoded spaces-as-underscores
+							$name = str_replace( '_', '=20', $name );
+							// Decode the name
+							$name = mb_decode_mimeheader( $name );
+							mb_internal_encoding( $origCharset );
+						}
+						$addresses[] = array(
+							// Remove any surrounding quotes and spaces from the name
+							'name'    => trim( $name, '\'" ' ),
+							'address' => $email,
+						);
+					}
+				}
+			}
+		}
+
+		return $addresses;
+	}
+
+	/**
+	 * Set the From and FromName properties.
+	 *
+	 * @param string $address
+	 * @param string $name
+	 * @param bool   $auto    Whether to also set the Sender address, defaults to true
+	 *
+	 * @throws Exception
+	 *
+	 * @return bool
+	 */
+	public function setFrom( $address, $name = '', $auto = true ) {
+		$address = trim( (string) $address );
+		$name    = trim( preg_replace( '/[\r\n]+/', '', $name ) ); // Strip breaks and trim
+		// Don't validate now addresses with IDN. Will be done in send().
+		$pos = strrpos( $address, '@' );
+		if (
+			( false === $pos )
+			|| ( ( ! $this->has8bitChars( substr( $address, ++$pos ) ) || ! static::idnSupported() )
+			&& ! static::validateAddress( $address ) )
+		) {
+			$error_message = sprintf(
+				'%s (From): %s',
+				$this->lang( 'invalid_address' ),
+				$address
+			);
+			$this->setError( $error_message );
+			$this->edebug( $error_message );
+			if ( $this->exceptions ) {
+				throw new Exception( $error_message );
+			}
+
+			return false;
+		}
+		$this->From     = $address;
+		$this->FromName = $name;
+		if ( $auto && empty( $this->Sender ) ) {
+			$this->Sender = $address;
+		}
+
+		return true;
+	}
+
+	/**
+	 * Return the Message-ID header of the last email.
+	 * Technically this is the value from the last time the headers were created,
+	 * but it's also the message ID of the last sent message except in
+	 * pathological cases.
+	 *
+	 * @return string
+	 */
+	public function getLastMessageID() {
+		return $this->lastMessageID;
+	}
+
+	/**
+	 * Check that a string looks like an email address.
+	 * Validation patterns supported:
+	 * * `auto` Pick best pattern automatically;
+	 * * `pcre8` Use the squiloople.com pattern, requires PCRE > 8.0;
+	 * * `pcre` Use old PCRE implementation;
+	 * * `php` Use PHP built-in FILTER_VALIDATE_EMAIL;
+	 * * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements.
+	 * * `noregex` Don't use a regex: super fast, really dumb.
+	 * Alternatively you may pass in a callable to inject your own validator, for example:
+	 *
+	 * ```php
+	 * PHPMailer::validateAddress('user@example.com', function($address) {
+	 *     return (strpos($address, '@') !== false);
+	 * });
+	 * ```
+	 *
+	 * You can also set the PHPMailer::$validator static to a callable, allowing built-in methods to use your validator.
+	 *
+	 * @param string          $address       The email address to check
+	 * @param string|callable $patternselect Which pattern to use
+	 *
+	 * @return bool
+	 */
+	public static function validateAddress( $address, $patternselect = null ) {
+		if ( null === $patternselect ) {
+			$patternselect = static::$validator;
+		}
+		// Don't allow strings as callables, see SECURITY.md and CVE-2021-3603
+		if ( is_callable( $patternselect ) && ! is_string( $patternselect ) ) {
+			return call_user_func( $patternselect, $address );
+		}
+		// Reject line breaks in addresses; it's valid RFC5322, but not RFC5321
+		if ( strpos( $address, "\n" ) !== false || strpos( $address, "\r" ) !== false ) {
+			return false;
+		}
+		switch ( $patternselect ) {
+			case 'pcre': // Kept for BC
+			case 'pcre8':
+				/*
+				 * A more complex and more permissive version of the RFC5322 regex on which FILTER_VALIDATE_EMAIL
+				 * is based.
+				 * In addition to the addresses allowed by filter_var, also permits:
+				 *  * dotless domains: `a@b`
+				 *  * comments: `1234 @ local(blah) .machine .example`
+				 *  * quoted elements: `'"test blah"@example.org'`
+				 *  * numeric TLDs: `a@b.123`
+				 *  * unbracketed IPv4 literals: `a@192.168.0.1`
+				 *  * IPv6 literals: 'first.last@[IPv6:a1::]'
+				 * Not all of these will necessarily work for sending!
+				 *
+				 * @copyright 2009-2010 Michael Rushton
+				 * Feel free to use and redistribute this code. But please keep this copyright notice.
+				 */
+				return (bool) preg_match(
+					'/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)' .
+					'((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)' .
+					'(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)' .
+					'([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*' .
+					'(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)' .
+					'(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}' .
+					'|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:' .
+					'|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}' .
+					'|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD',
+					$address
+				);
+			case 'html5':
+				/*
+				 * This is the pattern used in the HTML5 spec for validation of 'email' type form input elements.
+				 *
+				 * @see https://html.spec.whatwg.org/#e-mail-state-(type=email)
+				 */
+				return (bool) preg_match(
+					'/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}' .
+					'[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD',
+					$address
+				);
+			case 'php':
+			default:
+				return filter_var( $address, FILTER_VALIDATE_EMAIL ) !== false;
+		}
+	}
+
+	/**
+	 * Tells whether IDNs (Internationalized Domain Names) are supported or not. This requires the
+	 * `intl` and `mbstring` PHP extensions.
+	 *
+	 * @return bool `true` if required functions for IDN support are present
+	 */
+	public static function idnSupported() {
+		return function_exists( 'idn_to_ascii' ) && function_exists( 'mb_convert_encoding' );
+	}
+
+	/**
+	 * Converts IDN in given email address to its ASCII form, also known as punycode, if possible.
+	 * Important: Address must be passed in same encoding as currently set in PHPMailer::$CharSet.
+	 * This function silently returns unmodified address if:
+	 * - No conversion is necessary (i.e. domain name is not an IDN, or is already in ASCII form)
+	 * - Conversion to punycode is impossible (e.g. required PHP functions are not available)
+	 *   or fails for any reason (e.g. domain contains characters not allowed in an IDN).
+	 *
+	 * @see PHPMailer::$CharSet
+	 *
+	 * @param string $address The email address to convert
+	 *
+	 * @return string The encoded address in ASCII form
+	 */
+	public function punyencodeAddress( $address ) {
+		// Verify we have required functions, CharSet, and at-sign.
+		$pos = strrpos( $address, '@' );
+		if (
+			! empty( $this->CharSet ) &&
+			false !== $pos &&
+			static::idnSupported()
+		) {
+			$domain = substr( $address, ++$pos );
+			// Verify CharSet string is a valid one, and domain properly encoded in this CharSet.
+			if ( $this->has8bitChars( $domain ) && @mb_check_encoding( $domain, $this->CharSet ) ) {
+				// Convert the domain from whatever charset it's in to UTF-8
+				$domain = mb_convert_encoding( $domain, self::CHARSET_UTF8, $this->CharSet );
+				// Ignore IDE complaints about this line - method signature changed in PHP 5.4
+				$errorcode = 0;
+				if ( defined( 'INTL_IDNA_VARIANT_UTS46' ) ) {
+					// Use the current punycode standard (appeared in PHP 7.2)
+					$punycode = idn_to_ascii(
+						$domain,
+						\IDNA_DEFAULT | \IDNA_USE_STD3_RULES | \IDNA_CHECK_BIDI |
+							\IDNA_CHECK_CONTEXTJ | \IDNA_NONTRANSITIONAL_TO_ASCII,
+						\INTL_IDNA_VARIANT_UTS46
+					);
+				} elseif ( defined( 'INTL_IDNA_VARIANT_2003' ) ) {
+					// Fall back to this old, deprecated/removed encoding
                     // phpcs:ignore PHPCompatibility.Constants.RemovedConstants.intl_idna_variant_2003Deprecated
-                    $punycode = idn_to_ascii($domain, $errorcode, \INTL_IDNA_VARIANT_2003);
-                } else {
-                    //Fall back to a default we don't know about
+					$punycode = idn_to_ascii( $domain, $errorcode, \INTL_IDNA_VARIANT_2003 );
+				} else {
+					// Fall back to a default we don't know about
                     // phpcs:ignore PHPCompatibility.ParameterValues.NewIDNVariantDefault.NotSet
-                    $punycode = idn_to_ascii($domain, $errorcode);
-                }
-                if (false !== $punycode) {
-                    return substr($address, 0, $pos) . $punycode;
-                }
-            }
-        }
-
-        return $address;
-    }
-
-    /**
-     * Create a message and send it.
-     * Uses the sending method specified by $Mailer.
-     *
-     * @throws Exception
-     *
-     * @return bool false on error - See the ErrorInfo property for details of the error
-     */
-    public function send()
-    {
-        try {
-            if (!$this->preSend()) {
-                return false;
-            }
-
-            return $this->postSend();
-        } catch (Exception $exc) {
-            $this->mailHeader = '';
-            $this->setError($exc->getMessage());
-            if ($this->exceptions) {
-                throw $exc;
-            }
-
-            return false;
-        }
-    }
-
-    /**
-     * Prepare a message for sending.
-     *
-     * @throws Exception
-     *
-     * @return bool
-     */
-    public function preSend()
-    {
-        if (
-            'smtp' === $this->Mailer
-            || ('mail' === $this->Mailer && (\PHP_VERSION_ID >= 80000 || stripos(PHP_OS, 'WIN') === 0))
-        ) {
-            //SMTP mandates RFC-compliant line endings
-            //and it's also used with mail() on Windows
-            static::setLE(self::CRLF);
-        } else {
-            //Maintain backward compatibility with legacy Linux command line mailers
-            static::setLE(PHP_EOL);
-        }
-        //Check for buggy PHP versions that add a header with an incorrect line break
-        if (
-            'mail' === $this->Mailer
-            && ((\PHP_VERSION_ID >= 70000 && \PHP_VERSION_ID < 70017)
-                || (\PHP_VERSION_ID >= 70100 && \PHP_VERSION_ID < 70103))
-            && ini_get('mail.add_x_header') === '1'
-            && stripos(PHP_OS, 'WIN') === 0
-        ) {
-            trigger_error($this->lang('buggy_php'), E_USER_WARNING);
-        }
-
-        try {
-            $this->error_count = 0; //Reset errors
-            $this->mailHeader = '';
-
-            //Dequeue recipient and Reply-To addresses with IDN
-            foreach (array_merge($this->RecipientsQueue, $this->ReplyToQueue) as $params) {
-                $params[1] = $this->punyencodeAddress($params[1]);
-                call_user_func_array([$this, 'addAnAddress'], $params);
-            }
-            if (count($this->to) + count($this->cc) + count($this->bcc) < 1) {
-                throw new Exception($this->lang('provide_address'), self::STOP_CRITICAL);
-            }
-
-            //Validate From, Sender, and ConfirmReadingTo addresses
-            foreach (['From', 'Sender', 'ConfirmReadingTo'] as $address_kind) {
-                if ($this->{$address_kind} === null) {
-                    $this->{$address_kind} = '';
-                    continue;
-                }
-                $this->{$address_kind} = trim($this->{$address_kind});
-                if (empty($this->{$address_kind})) {
-                    continue;
-                }
-                $this->{$address_kind} = $this->punyencodeAddress($this->{$address_kind});
-                if (!static::validateAddress($this->{$address_kind})) {
-                    $error_message = sprintf(
-                        '%s (%s): %s',
-                        $this->lang('invalid_address'),
-                        $address_kind,
-                        $this->{$address_kind}
-                    );
-                    $this->setError($error_message);
-                    $this->edebug($error_message);
-                    if ($this->exceptions) {
-                        throw new Exception($error_message);
-                    }
-
-                    return false;
-                }
-            }
-
-            //Set whether the message is multipart/alternative
-            if ($this->alternativeExists()) {
-                $this->ContentType = static::CONTENT_TYPE_MULTIPART_ALTERNATIVE;
-            }
-
-            $this->setMessageType();
-            //Refuse to send an empty message unless we are specifically allowing it
-            if (!$this->AllowEmpty && empty($this->Body)) {
-                throw new Exception($this->lang('empty_message'), self::STOP_CRITICAL);
-            }
-
-            //Trim subject consistently
-            $this->Subject = trim($this->Subject);
-            //Create body before headers in case body makes changes to headers (e.g. altering transfer encoding)
-            $this->MIMEHeader = '';
-            $this->MIMEBody = $this->createBody();
-            //createBody may have added some headers, so retain them
-            $tempheaders = $this->MIMEHeader;
-            $this->MIMEHeader = $this->createHeader();
-            $this->MIMEHeader .= $tempheaders;
-
-            //To capture the complete message when using mail(), create
-            //an extra header list which createHeader() doesn't fold in
-            if ('mail' === $this->Mailer) {
-                if (count($this->to) > 0) {
-                    $this->mailHeader .= $this->addrAppend('To', $this->to);
-                } else {
-                    $this->mailHeader .= $this->headerLine('To', 'undisclosed-recipients:;');
-                }
-                $this->mailHeader .= $this->headerLine(
-                    'Subject',
-                    $this->encodeHeader($this->secureHeader($this->Subject))
-                );
-            }
-
-            //Sign with DKIM if enabled
-            if (
-                !empty($this->DKIM_domain)
-                && !empty($this->DKIM_selector)
-                && (!empty($this->DKIM_private_string)
-                    || (!empty($this->DKIM_private)
-                        && static::isPermittedPath($this->DKIM_private)
-                        && file_exists($this->DKIM_private)
-                    )
-                )
-            ) {
-                $header_dkim = $this->DKIM_Add(
-                    $this->MIMEHeader . $this->mailHeader,
-                    $this->encodeHeader($this->secureHeader($this->Subject)),
-                    $this->MIMEBody
-                );
-                $this->MIMEHeader = static::stripTrailingWSP($this->MIMEHeader) . static::$LE .
-                    static::normalizeBreaks($header_dkim) . static::$LE;
-            }
-
-            return true;
-        } catch (Exception $exc) {
-            $this->setError($exc->getMessage());
-            if ($this->exceptions) {
-                throw $exc;
-            }
-
-            return false;
-        }
-    }
-
-    /**
-     * Actually send a message via the selected mechanism.
-     *
-     * @throws Exception
-     *
-     * @return bool
-     */
-    public function postSend()
-    {
-        try {
-            //Choose the mailer and send through it
-            switch ($this->Mailer) {
-                case 'sendmail':
-                case 'qmail':
-                    return $this->sendmailSend($this->MIMEHeader, $this->MIMEBody);
-                case 'smtp':
-                    return $this->smtpSend($this->MIMEHeader, $this->MIMEBody);
-                case 'mail':
-                    return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
-                default:
-                    $sendMethod = $this->Mailer . 'Send';
-                    if (method_exists($this, $sendMethod)) {
-                        return $this->{$sendMethod}($this->MIMEHeader, $this->MIMEBody);
-                    }
-
-                    return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
-            }
-        } catch (Exception $exc) {
-            $this->setError($exc->getMessage());
-            $this->edebug($exc->getMessage());
-            if ($this->Mailer === 'smtp' && $this->SMTPKeepAlive == true && $this->smtp->connected()) {
-                $this->smtp->reset();
-            }
-            if ($this->exceptions) {
-                throw $exc;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Send mail using the $Sendmail program.
-     *
-     * @see PHPMailer::$Sendmail
-     *
-     * @param string $header The message headers
-     * @param string $body   The message body
-     *
-     * @throws Exception
-     *
-     * @return bool
-     */
-    protected function sendmailSend($header, $body)
-    {
-        if ($this->Mailer === 'qmail') {
-            $this->edebug('Sending with qmail');
-        } else {
-            $this->edebug('Sending with sendmail');
-        }
-        $header = static::stripTrailingWSP($header) . static::$LE . static::$LE;
-        //This sets the SMTP envelope sender which gets turned into a return-path header by the receiver
-        //A space after `-f` is optional, but there is a long history of its presence
-        //causing problems, so we don't use one
-        //Exim docs: https://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html
-        //Sendmail docs: https://www.sendmail.org/~ca/email/man/sendmail.html
-        //Example problem: https://www.drupal.org/node/1057954
-
-        //PHP 5.6 workaround
-        $sendmail_from_value = ini_get('sendmail_from');
-        if (empty($this->Sender) && !empty($sendmail_from_value)) {
-            //PHP config has a sender address we can use
-            $this->Sender = ini_get('sendmail_from');
-        }
-        //CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.
-        if (!empty($this->Sender) && static::validateAddress($this->Sender) && self::isShellSafe($this->Sender)) {
-            if ($this->Mailer === 'qmail') {
-                $sendmailFmt = '%s -f%s';
-            } else {
-                $sendmailFmt = '%s -oi -f%s -t';
-            }
-        } else {
-            //allow sendmail to choose a default envelope sender. It may
-            //seem preferable to force it to use the From header as with
-            //SMTP, but that introduces new problems (see
-            //<https://github.com/PHPMailer/PHPMailer/issues/2298>), and
-            //it has historically worked this way.
-            $sendmailFmt = '%s -oi -t';
-        }
-
-        $sendmail = sprintf($sendmailFmt, escapeshellcmd($this->Sendmail), $this->Sender);
-        $this->edebug('Sendmail path: ' . $this->Sendmail);
-        $this->edebug('Sendmail command: ' . $sendmail);
-        $this->edebug('Envelope sender: ' . $this->Sender);
-        $this->edebug("Headers: {$header}");
-
-        if ($this->SingleTo) {
-            foreach ($this->SingleToArray as $toAddr) {
-                $mail = @popen($sendmail, 'w');
-                if (!$mail) {
-                    throw new Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
-                }
-                $this->edebug("To: {$toAddr}");
-                fwrite($mail, 'To: ' . $toAddr . "\n");
-                fwrite($mail, $header);
-                fwrite($mail, $body);
-                $result = pclose($mail);
-                $addrinfo = static::parseAddresses($toAddr, true, $this->CharSet);
-                $this->doCallback(
-                    ($result === 0),
-                    [[$addrinfo['address'], $addrinfo['name']]],
-                    $this->cc,
-                    $this->bcc,
-                    $this->Subject,
-                    $body,
-                    $this->From,
-                    []
-                );
-                $this->edebug("Result: " . ($result === 0 ? 'true' : 'false'));
-                if (0 !== $result) {
-                    throw new Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
-                }
-            }
-        } else {
-            $mail = @popen($sendmail, 'w');
-            if (!$mail) {
-                throw new Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
-            }
-            fwrite($mail, $header);
-            fwrite($mail, $body);
-            $result = pclose($mail);
-            $this->doCallback(
-                ($result === 0),
-                $this->to,
-                $this->cc,
-                $this->bcc,
-                $this->Subject,
-                $body,
-                $this->From,
-                []
-            );
-            $this->edebug("Result: " . ($result === 0 ? 'true' : 'false'));
-            if (0 !== $result) {
-                throw new Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Fix CVE-2016-10033 and CVE-2016-10045 by disallowing potentially unsafe shell characters.
-     * Note that escapeshellarg and escapeshellcmd are inadequate for our purposes, especially on Windows.
-     *
-     * @see https://github.com/PHPMailer/PHPMailer/issues/924 CVE-2016-10045 bug report
-     *
-     * @param string $string The string to be validated
-     *
-     * @return bool
-     */
-    protected static function isShellSafe($string)
-    {
-        //It's not possible to use shell commands safely (which includes the mail() function) without escapeshellarg,
-        //but some hosting providers disable it, creating a security problem that we don't want to have to deal with,
-        //so we don't.
-        if (!function_exists('escapeshellarg') || !function_exists('escapeshellcmd')) {
-            return false;
-        }
-
-        if (
-            escapeshellcmd($string) !== $string
-            || !in_array(escapeshellarg($string), ["'$string'", "\"$string\""])
-        ) {
-            return false;
-        }
-
-        $length = strlen($string);
-
-        for ($i = 0; $i < $length; ++$i) {
-            $c = $string[$i];
-
-            //All other characters have a special meaning in at least one common shell, including = and +.
-            //Full stop (.) has a special meaning in cmd.exe, but its impact should be negligible here.
-            //Note that this does permit non-Latin alphanumeric characters based on the current locale.
-            if (!ctype_alnum($c) && strpos('@_-.', $c) === false) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Check whether a file path is of a permitted type.
-     * Used to reject URLs and phar files from functions that access local file paths,
-     * such as addAttachment.
-     *
-     * @param string $path A relative or absolute path to a file
-     *
-     * @return bool
-     */
-    protected static function isPermittedPath($path)
-    {
-        //Matches scheme definition from https://www.rfc-editor.org/rfc/rfc3986#section-3.1
-        return !preg_match('#^[a-z][a-z\d+.-]*://#i', $path);
-    }
-
-    /**
-     * Check whether a file path is safe, accessible, and readable.
-     *
-     * @param string $path A relative or absolute path to a file
-     *
-     * @return bool
-     */
-    protected static function fileIsAccessible($path)
-    {
-        if (!static::isPermittedPath($path)) {
-            return false;
-        }
-        $readable = is_file($path);
-        //If not a UNC path (expected to start with \\), check read permission, see #2069
-        if (strpos($path, '\\\\') !== 0) {
-            $readable = $readable && is_readable($path);
-        }
-        return  $readable;
-    }
-
-    /**
-     * Send mail using the PHP mail() function.
-     *
-     * @see https://www.php.net/manual/en/book.mail.php
-     *
-     * @param string $header The message headers
-     * @param string $body   The message body
-     *
-     * @throws Exception
-     *
-     * @return bool
-     */
-    protected function mailSend($header, $body)
-    {
-        $header = static::stripTrailingWSP($header) . static::$LE . static::$LE;
-
-        $toArr = [];
-        foreach ($this->to as $toaddr) {
-            $toArr[] = $this->addrFormat($toaddr);
-        }
-        $to = trim(implode(', ', $toArr));
-
-        //If there are no To-addresses (e.g. when sending only to BCC-addresses)
-        //the following should be added to get a correct DKIM-signature.
-        //Compare with $this->preSend()
-        if ($to === '') {
-            $to = 'undisclosed-recipients:;';
-        }
-
-        $params = null;
-        //This sets the SMTP envelope sender which gets turned into a return-path header by the receiver
-        //A space after `-f` is optional, but there is a long history of its presence
-        //causing problems, so we don't use one
-        //Exim docs: https://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html
-        //Sendmail docs: https://www.sendmail.org/~ca/email/man/sendmail.html
-        //Example problem: https://www.drupal.org/node/1057954
-        //CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.
-
-        //PHP 5.6 workaround
-        $sendmail_from_value = ini_get('sendmail_from');
-        if (empty($this->Sender) && !empty($sendmail_from_value)) {
-            //PHP config has a sender address we can use
-            $this->Sender = ini_get('sendmail_from');
-        }
-        if (!empty($this->Sender) && static::validateAddress($this->Sender)) {
-            if (self::isShellSafe($this->Sender)) {
-                $params = sprintf('-f%s', $this->Sender);
-            }
-            $old_from = ini_get('sendmail_from');
-            ini_set('sendmail_from', $this->Sender);
-        }
-        $result = false;
-        if ($this->SingleTo && count($toArr) > 1) {
-            foreach ($toArr as $toAddr) {
-                $result = $this->mailPassthru($toAddr, $this->Subject, $body, $header, $params);
-                $addrinfo = static::parseAddresses($toAddr, true, $this->CharSet);
-                $this->doCallback(
-                    $result,
-                    [[$addrinfo['address'], $addrinfo['name']]],
-                    $this->cc,
-                    $this->bcc,
-                    $this->Subject,
-                    $body,
-                    $this->From,
-                    []
-                );
-            }
-        } else {
-            $result = $this->mailPassthru($to, $this->Subject, $body, $header, $params);
-            $this->doCallback($result, $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From, []);
-        }
-        if (isset($old_from)) {
-            ini_set('sendmail_from', $old_from);
-        }
-        if (!$result) {
-            throw new Exception($this->lang('instantiate'), self::STOP_CRITICAL);
-        }
-
-        return true;
-    }
-
-    /**
-     * Get an instance to use for SMTP operations.
-     * Override this function to load your own SMTP implementation,
-     * or set one with setSMTPInstance.
-     *
-     * @return SMTP
-     */
-    public function getSMTPInstance()
-    {
-        if (!is_object($this->smtp)) {
-            $this->smtp = new SMTP();
-        }
-
-        return $this->smtp;
-    }
-
-    /**
-     * Provide an instance to use for SMTP operations.
-     *
-     * @return SMTP
-     */
-    public function setSMTPInstance(SMTP $smtp)
-    {
-        $this->smtp = $smtp;
-
-        return $this->smtp;
-    }
-
-    /**
-     * Provide SMTP XCLIENT attributes
-     *
-     * @param string $name  Attribute name
-     * @param ?string $value Attribute value
-     *
-     * @return bool
-     */
-    public function setSMTPXclientAttribute($name, $value)
-    {
-        if (!in_array($name, SMTP::$xclient_allowed_attributes)) {
-            return false;
-        }
-        if (isset($this->SMTPXClient[$name]) && $value === null) {
-            unset($this->SMTPXClient[$name]);
-        } elseif ($value !== null) {
-            $this->SMTPXClient[$name] = $value;
-        }
-
-        return true;
-    }
-
-    /**
-     * Get SMTP XCLIENT attributes
-     *
-     * @return array
-     */
-    public function getSMTPXclientAttributes()
-    {
-        return $this->SMTPXClient;
-    }
-
-    /**
-     * Send mail via SMTP.
-     * Returns false if there is a bad MAIL FROM, RCPT, or DATA input.
-     *
-     * @see PHPMailer::setSMTPInstance() to use a different class.
-     *
-     * @uses \PHPMailer\PHPMailer\SMTP
-     *
-     * @param string $header The message headers
-     * @param string $body   The message body
-     *
-     * @throws Exception
-     *
-     * @return bool
-     */
-    protected function smtpSend($header, $body)
-    {
-        $header = static::stripTrailingWSP($header) . static::$LE . static::$LE;
-        $bad_rcpt = [];
-        if (!$this->smtpConnect($this->SMTPOptions)) {
-            throw new Exception($this->lang('smtp_connect_failed'), self::STOP_CRITICAL);
-        }
-        //Sender already validated in preSend()
-        if ('' === $this->Sender) {
-            $smtp_from = $this->From;
-        } else {
-            $smtp_from = $this->Sender;
-        }
-        if (count($this->SMTPXClient)) {
-            $this->smtp->xclient($this->SMTPXClient);
-        }
-        if (!$this->smtp->mail($smtp_from)) {
-            $this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError()));
-            throw new Exception($this->ErrorInfo, self::STOP_CRITICAL);
-        }
-
-        $callbacks = [];
-        //Attempt to send to all recipients
-        foreach ([$this->to, $this->cc, $this->bcc] as $togroup) {
-            foreach ($togroup as $to) {
-                if (!$this->smtp->recipient($to[0], $this->dsn)) {
-                    $error = $this->smtp->getError();
-                    $bad_rcpt[] = ['to' => $to[0], 'error' => $error['detail']];
-                    $isSent = false;
-                } else {
-                    $isSent = true;
-                }
-
-                $callbacks[] = ['issent' => $isSent, 'to' => $to[0], 'name' => $to[1]];
-            }
-        }
-
-        //Only send the DATA command if we have viable recipients
-        if ((count($this->all_recipients) > count($bad_rcpt)) && !$this->smtp->data($header . $body)) {
-            throw new Exception($this->lang('data_not_accepted'), self::STOP_CRITICAL);
-        }
-
-        $smtp_transaction_id = $this->smtp->getLastTransactionID();
-
-        if ($this->SMTPKeepAlive) {
-            $this->smtp->reset();
-        } else {
-            $this->smtp->quit();
-            $this->smtp->close();
-        }
-
-        foreach ($callbacks as $cb) {
-            $this->doCallback(
-                $cb['issent'],
-                [[$cb['to'], $cb['name']]],
-                [],
-                [],
-                $this->Subject,
-                $body,
-                $this->From,
-                ['smtp_transaction_id' => $smtp_transaction_id]
-            );
-        }
-
-        //Create error message for any bad addresses
-        if (count($bad_rcpt) > 0) {
-            $errstr = '';
-            foreach ($bad_rcpt as $bad) {
-                $errstr .= $bad['to'] . ': ' . $bad['error'];
-            }
-            throw new Exception($this->lang('recipients_failed') . $errstr, self::STOP_CONTINUE);
-        }
-
-        return true;
-    }
-
-    /**
-     * Initiate a connection to an SMTP server.
-     * Returns false if the operation failed.
-     *
-     * @param array $options An array of options compatible with stream_context_create()
-     *
-     * @throws Exception
-     *
-     * @uses \PHPMailer\PHPMailer\SMTP
-     *
-     * @return bool
-     */
-    public function smtpConnect($options = null)
-    {
-        if (null === $this->smtp) {
-            $this->smtp = $this->getSMTPInstance();
-        }
-
-        //If no options are provided, use whatever is set in the instance
-        if (null === $options) {
-            $options = $this->SMTPOptions;
-        }
-
-        //Already connected?
-        if ($this->smtp->connected()) {
-            return true;
-        }
-
-        $this->smtp->setTimeout($this->Timeout);
-        $this->smtp->setDebugLevel($this->SMTPDebug);
-        $this->smtp->setDebugOutput($this->Debugoutput);
-        $this->smtp->setVerp($this->do_verp);
-        if ($this->Host === null) {
-            $this->Host = 'localhost';
-        }
-        $hosts = explode(';', $this->Host);
-        $lastexception = null;
-
-        foreach ($hosts as $hostentry) {
-            $hostinfo = [];
-            if (
-                !preg_match(
-                    '/^(?:(ssl|tls):\/\/)?(.+?)(?::(\d+))?$/',
-                    trim($hostentry),
-                    $hostinfo
-                )
-            ) {
-                $this->edebug($this->lang('invalid_hostentry') . ' ' . trim($hostentry));
-                //Not a valid host entry
-                continue;
-            }
-            //$hostinfo[1]: optional ssl or tls prefix
-            //$hostinfo[2]: the hostname
-            //$hostinfo[3]: optional port number
-            //The host string prefix can temporarily override the current setting for SMTPSecure
-            //If it's not specified, the default value is used
-
-            //Check the host name is a valid name or IP address before trying to use it
-            if (!static::isValidHost($hostinfo[2])) {
-                $this->edebug($this->lang('invalid_host') . ' ' . $hostinfo[2]);
-                continue;
-            }
-            $prefix = '';
-            $secure = $this->SMTPSecure;
-            $tls = (static::ENCRYPTION_STARTTLS === $this->SMTPSecure);
-            if ('ssl' === $hostinfo[1] || ('' === $hostinfo[1] && static::ENCRYPTION_SMTPS === $this->SMTPSecure)) {
-                $prefix = 'ssl://';
-                $tls = false; //Can't have SSL and TLS at the same time
-                $secure = static::ENCRYPTION_SMTPS;
-            } elseif ('tls' === $hostinfo[1]) {
-                $tls = true;
-                //TLS doesn't use a prefix
-                $secure = static::ENCRYPTION_STARTTLS;
-            }
-            //Do we need the OpenSSL extension?
-            $sslext = defined('OPENSSL_ALGO_SHA256');
-            if (static::ENCRYPTION_STARTTLS === $secure || static::ENCRYPTION_SMTPS === $secure) {
-                //Check for an OpenSSL constant rather than using extension_loaded, which is sometimes disabled
-                if (!$sslext) {
-                    throw new Exception($this->lang('extension_missing') . 'openssl', self::STOP_CRITICAL);
-                }
-            }
-            $host = $hostinfo[2];
-            $port = $this->Port;
-            if (
-                array_key_exists(3, $hostinfo) &&
-                is_numeric($hostinfo[3]) &&
-                $hostinfo[3] > 0 &&
-                $hostinfo[3] < 65536
-            ) {
-                $port = (int) $hostinfo[3];
-            }
-            if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) {
-                try {
-                    if ($this->Helo) {
-                        $hello = $this->Helo;
-                    } else {
-                        $hello = $this->serverHostname();
-                    }
-                    $this->smtp->hello($hello);
-                    //Automatically enable TLS encryption if:
-                    //* it's not disabled
-                    //* we are not connecting to localhost
-                    //* we have openssl extension
-                    //* we are not already using SSL
-                    //* the server offers STARTTLS
-                    if (
-                        $this->SMTPAutoTLS &&
-                        $this->Host !== 'localhost' &&
-                        $sslext &&
-                        $secure !== 'ssl' &&
-                        $this->smtp->getServerExt('STARTTLS')
-                    ) {
-                        $tls = true;
-                    }
-                    if ($tls) {
-                        if (!$this->smtp->startTLS()) {
-                            $message = $this->getSmtpErrorMessage('connect_host');
-                            throw new Exception($message);
-                        }
-                        //We must resend EHLO after TLS negotiation
-                        $this->smtp->hello($hello);
-                    }
-                    if (
-                        $this->SMTPAuth && !$this->smtp->authenticate(
-                            $this->Username,
-                            $this->Password,
-                            $this->AuthType,
-                            $this->oauth
-                        )
-                    ) {
-                        throw new Exception($this->lang('authenticate'));
-                    }
-
-                    return true;
-                } catch (Exception $exc) {
-                    $lastexception = $exc;
-                    $this->edebug($exc->getMessage());
-                    //We must have connected, but then failed TLS or Auth, so close connection nicely
-                    $this->smtp->quit();
-                }
-            }
-        }
-        //If we get here, all connection attempts have failed, so close connection hard
-        $this->smtp->close();
-        //As we've caught all exceptions, just report whatever the last one was
-        if ($this->exceptions && null !== $lastexception) {
-            throw $lastexception;
-        }
-        if ($this->exceptions) {
-            // no exception was thrown, likely $this->smtp->connect() failed
-            $message = $this->getSmtpErrorMessage('connect_host');
-            throw new Exception($message);
-        }
-
-        return false;
-    }
-
-    /**
-     * Close the active SMTP session if one exists.
-     */
-    public function smtpClose()
-    {
-        if ((null !== $this->smtp) && $this->smtp->connected()) {
-            $this->smtp->quit();
-            $this->smtp->close();
-        }
-    }
-
-    /**
-     * Set the language for error messages.
-     * The default language is English.
-     *
-     * @param string $langcode  ISO 639-1 2-character language code (e.g. French is "fr")
-     *                          Optionally, the language code can be enhanced with a 4-character
-     *                          script annotation and/or a 2-character country annotation.
-     * @param string $lang_path Path to the language file directory, with trailing separator (slash)
-     *                          Do not set this from user input!
-     *
-     * @return bool Returns true if the requested language was loaded, false otherwise.
-     */
-    public function setLanguage($langcode = 'en', $lang_path = '')
-    {
-        //Backwards compatibility for renamed language codes
-        $renamed_langcodes = [
-            'br' => 'pt_br',
-            'cz' => 'cs',
-            'dk' => 'da',
-            'no' => 'nb',
-            'se' => 'sv',
-            'rs' => 'sr',
-            'tg' => 'tl',
-            'am' => 'hy',
-        ];
-
-        if (array_key_exists($langcode, $renamed_langcodes)) {
-            $langcode = $renamed_langcodes[$langcode];
-        }
-
-        //Define full set of translatable strings in English
-        $PHPMAILER_LANG = [
-            'authenticate' => 'SMTP Error: Could not authenticate.',
-            'buggy_php' => 'Your version of PHP is affected by a bug that may result in corrupted messages.' .
-                ' To fix it, switch to sending using SMTP, disable the mail.add_x_header option in' .
-                ' your php.ini, switch to MacOS or Linux, or upgrade your PHP to version 7.0.17+ or 7.1.3+.',
-            'connect_host' => 'SMTP Error: Could not connect to SMTP host.',
-            'data_not_accepted' => 'SMTP Error: data not accepted.',
-            'empty_message' => 'Message body empty',
-            'encoding' => 'Unknown encoding: ',
-            'execute' => 'Could not execute: ',
-            'extension_missing' => 'Extension missing: ',
-            'file_access' => 'Could not access file: ',
-            'file_open' => 'File Error: Could not open file: ',
-            'from_failed' => 'The following From address failed: ',
-            'instantiate' => 'Could not instantiate mail function.',
-            'invalid_address' => 'Invalid address: ',
-            'invalid_header' => 'Invalid header name or value',
-            'invalid_hostentry' => 'Invalid hostentry: ',
-            'invalid_host' => 'Invalid host: ',
-            'mailer_not_supported' => ' mailer is not supported.',
-            'provide_address' => 'You must provide at least one recipient email address.',
-            'recipients_failed' => 'SMTP Error: The following recipients failed: ',
-            'signing' => 'Signing Error: ',
-            'smtp_code' => 'SMTP code: ',
-            'smtp_code_ex' => 'Additional SMTP info: ',
-            'smtp_connect_failed' => 'SMTP connect() failed.',
-            'smtp_detail' => 'Detail: ',
-            'smtp_error' => 'SMTP server error: ',
-            'variable_set' => 'Cannot set or reset variable: ',
-        ];
-        if (empty($lang_path)) {
-            //Calculate an absolute path so it can work if CWD is not here
-            $lang_path = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'language' . DIRECTORY_SEPARATOR;
-        }
-
-        //Validate $langcode
-        $foundlang = true;
-        $langcode  = strtolower($langcode);
-        if (
-            !preg_match('/^(?P<lang>[a-z]{2})(?P<script>_[a-z]{4})?(?P<country>_[a-z]{2})?$/', $langcode, $matches)
-            && $langcode !== 'en'
-        ) {
-            $foundlang = false;
-            $langcode = 'en';
-        }
-
-        //There is no English translation file
-        if ('en' !== $langcode) {
-            $langcodes = [];
-            if (!empty($matches['script']) && !empty($matches['country'])) {
-                $langcodes[] = $matches['lang'] . $matches['script'] . $matches['country'];
-            }
-            if (!empty($matches['country'])) {
-                $langcodes[] = $matches['lang'] . $matches['country'];
-            }
-            if (!empty($matches['script'])) {
-                $langcodes[] = $matches['lang'] . $matches['script'];
-            }
-            $langcodes[] = $matches['lang'];
-
-            //Try and find a readable language file for the requested language.
-            $foundFile = false;
-            foreach ($langcodes as $code) {
-                $lang_file = $lang_path . 'phpmailer.lang-' . $code . '.php';
-                if (static::fileIsAccessible($lang_file)) {
-                    $foundFile = true;
-                    break;
-                }
-            }
-
-            if ($foundFile === false) {
-                $foundlang = false;
-            } else {
-                $lines = file($lang_file);
-                foreach ($lines as $line) {
-                    //Translation file lines look like this:
-                    //$PHPMAILER_LANG['authenticate'] = 'SMTP-Fehler: Authentifizierung fehlgeschlagen.';
-                    //These files are parsed as text and not PHP so as to avoid the possibility of code injection
-                    //See https://blog.stevenlevithan.com/archives/match-quoted-string
-                    $matches = [];
-                    if (
-                        preg_match(
-                            '/^\$PHPMAILER_LANG\[\'([a-z\d_]+)\'\]\s*=\s*(["\'])(.+)*?\2;/',
-                            $line,
-                            $matches
-                        ) &&
-                        //Ignore unknown translation keys
-                        array_key_exists($matches[1], $PHPMAILER_LANG)
-                    ) {
-                        //Overwrite language-specific strings so we'll never have missing translation keys.
-                        $PHPMAILER_LANG[$matches[1]] = (string)$matches[3];
-                    }
-                }
-            }
-        }
-        $this->language = $PHPMAILER_LANG;
-
-        return $foundlang; //Returns false if language not found
-    }
-
-    /**
-     * Get the array of strings for the current language.
-     *
-     * @return array
-     */
-    public function getTranslations()
-    {
-        if (empty($this->language)) {
-            $this->setLanguage(); // Set the default language.
-        }
-
-        return $this->language;
-    }
-
-    /**
-     * Create recipient headers.
-     *
-     * @param string $type
-     * @param array  $addr An array of recipients,
-     *                     where each recipient is a 2-element indexed array with element 0 containing an address
-     *                     and element 1 containing a name, like:
-     *                     [['joe@example.com', 'Joe User'], ['zoe@example.com', 'Zoe User']]
-     *
-     * @return string
-     */
-    public function addrAppend($type, $addr)
-    {
-        $addresses = [];
-        foreach ($addr as $address) {
-            $addresses[] = $this->addrFormat($address);
-        }
-
-        return $type . ': ' . implode(', ', $addresses) . static::$LE;
-    }
-
-    /**
-     * Format an address for use in a message header.
-     *
-     * @param array $addr A 2-element indexed array, element 0 containing an address, element 1 containing a name like
-     *                    ['joe@example.com', 'Joe User']
-     *
-     * @return string
-     */
-    public function addrFormat($addr)
-    {
-        if (!isset($addr[1]) || ($addr[1] === '')) { //No name provided
-            return $this->secureHeader($addr[0]);
-        }
-
-        return $this->encodeHeader($this->secureHeader($addr[1]), 'phrase') .
-            ' <' . $this->secureHeader($addr[0]) . '>';
-    }
-
-    /**
-     * Word-wrap message.
-     * For use with mailers that do not automatically perform wrapping
-     * and for quoted-printable encoded messages.
-     * Original written by philippe.
-     *
-     * @param string $message The message to wrap
-     * @param int    $length  The line length to wrap to
-     * @param bool   $qp_mode Whether to run in Quoted-Printable mode
-     *
-     * @return string
-     */
-    public function wrapText($message, $length, $qp_mode = false)
-    {
-        if ($qp_mode) {
-            $soft_break = sprintf(' =%s', static::$LE);
-        } else {
-            $soft_break = static::$LE;
-        }
-        //If utf-8 encoding is used, we will need to make sure we don't
-        //split multibyte characters when we wrap
-        $is_utf8 = static::CHARSET_UTF8 === strtolower($this->CharSet);
-        $lelen = strlen(static::$LE);
-        $crlflen = strlen(static::$LE);
-
-        $message = static::normalizeBreaks($message);
-        //Remove a trailing line break
-        if (substr($message, -$lelen) === static::$LE) {
-            $message = substr($message, 0, -$lelen);
-        }
-
-        //Split message into lines
-        $lines = explode(static::$LE, $message);
-        //Message will be rebuilt in here
-        $message = '';
-        foreach ($lines as $line) {
-            $words = explode(' ', $line);
-            $buf = '';
-            $firstword = true;
-            foreach ($words as $word) {
-                if ($qp_mode && (strlen($word) > $length)) {
-                    $space_left = $length - strlen($buf) - $crlflen;
-                    if (!$firstword) {
-                        if ($space_left > 20) {
-                            $len = $space_left;
-                            if ($is_utf8) {
-                                $len = $this->utf8CharBoundary($word, $len);
-                            } elseif ('=' === substr($word, $len - 1, 1)) {
-                                --$len;
-                            } elseif ('=' === substr($word, $len - 2, 1)) {
-                                $len -= 2;
-                            }
-                            $part = substr($word, 0, $len);
-                            $word = substr($word, $len);
-                            $buf .= ' ' . $part;
-                            $message .= $buf . sprintf('=%s', static::$LE);
-                        } else {
-                            $message .= $buf . $soft_break;
-                        }
-                        $buf = '';
-                    }
-                    while ($word !== '') {
-                        if ($length <= 0) {
-                            break;
-                        }
-                        $len = $length;
-                        if ($is_utf8) {
-                            $len = $this->utf8CharBoundary($word, $len);
-                        } elseif ('=' === substr($word, $len - 1, 1)) {
-                            --$len;
-                        } elseif ('=' === substr($word, $len - 2, 1)) {
-                            $len -= 2;
-                        }
-                        $part = substr($word, 0, $len);
-                        $word = (string) substr($word, $len);
-
-                        if ($word !== '') {
-                            $message .= $part . sprintf('=%s', static::$LE);
-                        } else {
-                            $buf = $part;
-                        }
-                    }
-                } else {
-                    $buf_o = $buf;
-                    if (!$firstword) {
-                        $buf .= ' ';
-                    }
-                    $buf .= $word;
-
-                    if ('' !== $buf_o && strlen($buf) > $length) {
-                        $message .= $buf_o . $soft_break;
-                        $buf = $word;
-                    }
-                }
-                $firstword = false;
-            }
-            $message .= $buf . static::$LE;
-        }
-
-        return $message;
-    }
-
-    /**
-     * Find the last character boundary prior to $maxLength in a utf-8
-     * quoted-printable encoded string.
-     * Original written by Colin Brown.
-     *
-     * @param string $encodedText utf-8 QP text
-     * @param int    $maxLength   Find the last character boundary prior to this length
-     *
-     * @return int
-     */
-    public function utf8CharBoundary($encodedText, $maxLength)
-    {
-        $foundSplitPos = false;
-        $lookBack = 3;
-        while (!$foundSplitPos) {
-            $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
-            $encodedCharPos = strpos($lastChunk, '=');
-            if (false !== $encodedCharPos) {
-                //Found start of encoded character byte within $lookBack block.
-                //Check the encoded byte value (the 2 chars after the '=')
-                $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
-                $dec = hexdec($hex);
-                if ($dec < 128) {
-                    //Single byte character.
-                    //If the encoded char was found at pos 0, it will fit
-                    //otherwise reduce maxLength to start of the encoded char
-                    if ($encodedCharPos > 0) {
-                        $maxLength -= $lookBack - $encodedCharPos;
-                    }
-                    $foundSplitPos = true;
-                } elseif ($dec >= 192) {
-                    //First byte of a multi byte character
-                    //Reduce maxLength to split at start of character
-                    $maxLength -= $lookBack - $encodedCharPos;
-                    $foundSplitPos = true;
-                } elseif ($dec < 192) {
-                    //Middle byte of a multi byte character, look further back
-                    $lookBack += 3;
-                }
-            } else {
-                //No encoded character found
-                $foundSplitPos = true;
-            }
-        }
-
-        return $maxLength;
-    }
-
-    /**
-     * Apply word wrapping to the message body.
-     * Wraps the message body to the number of chars set in the WordWrap property.
-     * You should only do this to plain-text bodies as wrapping HTML tags may break them.
-     * This is called automatically by createBody(), so you don't need to call it yourself.
-     */
-    public function setWordWrap()
-    {
-        if ($this->WordWrap < 1) {
-            return;
-        }
-
-        switch ($this->message_type) {
-            case 'alt':
-            case 'alt_inline':
-            case 'alt_attach':
-            case 'alt_inline_attach':
-                $this->AltBody = $this->wrapText($this->AltBody, $this->WordWrap);
-                break;
-            default:
-                $this->Body = $this->wrapText($this->Body, $this->WordWrap);
-                break;
-        }
-    }
-
-    /**
-     * Assemble message headers.
-     *
-     * @return string The assembled headers
-     */
-    public function createHeader()
-    {
-        $result = '';
-
-        $result .= $this->headerLine('Date', '' === $this->MessageDate ? self::rfcDate() : $this->MessageDate);
-
-        //The To header is created automatically by mail(), so needs to be omitted here
-        if ('mail' !== $this->Mailer) {
-            if ($this->SingleTo) {
-                foreach ($this->to as $toaddr) {
-                    $this->SingleToArray[] = $this->addrFormat($toaddr);
-                }
-            } elseif (count($this->to) > 0) {
-                $result .= $this->addrAppend('To', $this->to);
-            } elseif (count($this->cc) === 0) {
-                $result .= $this->headerLine('To', 'undisclosed-recipients:;');
-            }
-        }
-        $result .= $this->addrAppend('From', [[trim($this->From), $this->FromName]]);
-
-        //sendmail and mail() extract Cc from the header before sending
-        if (count($this->cc) > 0) {
-            $result .= $this->addrAppend('Cc', $this->cc);
-        }
-
-        //sendmail and mail() extract Bcc from the header before sending
-        if (
-            (
-                'sendmail' === $this->Mailer || 'qmail' === $this->Mailer || 'mail' === $this->Mailer
-            )
-            && count($this->bcc) > 0
-        ) {
-            $result .= $this->addrAppend('Bcc', $this->bcc);
-        }
-
-        if (count($this->ReplyTo) > 0) {
-            $result .= $this->addrAppend('Reply-To', $this->ReplyTo);
-        }
-
-        //mail() sets the subject itself
-        if ('mail' !== $this->Mailer) {
-            $result .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader($this->Subject)));
-        }
-
-        //Only allow a custom message ID if it conforms to RFC 5322 section 3.6.4
-        //https://www.rfc-editor.org/rfc/rfc5322#section-3.6.4
-        if (
-            '' !== $this->MessageID &&
-            preg_match(
-                '/^<((([a-z\d!#$%&\'*+\/=?^_`{|}~-]+(\.[a-z\d!#$%&\'*+\/=?^_`{|}~-]+)*)' .
-                '|("(([\x01-\x08\x0B\x0C\x0E-\x1F\x7F]|[\x21\x23-\x5B\x5D-\x7E])' .
-                '|(\\[\x01-\x09\x0B\x0C\x0E-\x7F]))*"))@(([a-z\d!#$%&\'*+\/=?^_`{|}~-]+' .
-                '(\.[a-z\d!#$%&\'*+\/=?^_`{|}~-]+)*)|(\[(([\x01-\x08\x0B\x0C\x0E-\x1F\x7F]' .
-                '|[\x21-\x5A\x5E-\x7E])|(\\[\x01-\x09\x0B\x0C\x0E-\x7F]))*\])))>$/Di',
-                $this->MessageID
-            )
-        ) {
-            $this->lastMessageID = $this->MessageID;
-        } else {
-            $this->lastMessageID = sprintf('<%s@%s>', $this->uniqueid, $this->serverHostname());
-        }
-        $result .= $this->headerLine('Message-ID', $this->lastMessageID);
-        if (null !== $this->Priority) {
-            $result .= $this->headerLine('X-Priority', $this->Priority);
-        }
-        if ('' === $this->XMailer) {
-            //Empty string for default X-Mailer header
-            $result .= $this->headerLine(
-                'X-Mailer',
-                'PHPMailer ' . self::VERSION . ' (https://github.com/PHPMailer/PHPMailer)'
-            );
-        } elseif (is_string($this->XMailer) && trim($this->XMailer) !== '') {
-            //Some string
-            $result .= $this->headerLine('X-Mailer', trim($this->XMailer));
-        } //Other values result in no X-Mailer header
-
-        if ('' !== $this->ConfirmReadingTo) {
-            $result .= $this->headerLine('Disposition-Notification-To', '<' . $this->ConfirmReadingTo . '>');
-        }
-
-        //Add custom headers
-        foreach ($this->CustomHeader as $header) {
-            $result .= $this->headerLine(
-                trim($header[0]),
-                $this->encodeHeader(trim($header[1]))
-            );
-        }
-        if (!$this->sign_key_file) {
-            $result .= $this->headerLine('MIME-Version', '1.0');
-            $result .= $this->getMailMIME();
-        }
-
-        return $result;
-    }
-
-    /**
-     * Get the message MIME type headers.
-     *
-     * @return string
-     */
-    public function getMailMIME()
-    {
-        $result = '';
-        $ismultipart = true;
-        switch ($this->message_type) {
-            case 'inline':
-                $result .= $this->headerLine('Content-Type', static::CONTENT_TYPE_MULTIPART_RELATED . ';');
-                $result .= $this->textLine(' boundary="' . $this->boundary[1] . '"');
-                break;
-            case 'attach':
-            case 'inline_attach':
-            case 'alt_attach':
-            case 'alt_inline_attach':
-                $result .= $this->headerLine('Content-Type', static::CONTENT_TYPE_MULTIPART_MIXED . ';');
-                $result .= $this->textLine(' boundary="' . $this->boundary[1] . '"');
-                break;
-            case 'alt':
-            case 'alt_inline':
-                $result .= $this->headerLine('Content-Type', static::CONTENT_TYPE_MULTIPART_ALTERNATIVE . ';');
-                $result .= $this->textLine(' boundary="' . $this->boundary[1] . '"');
-                break;
-            default:
-                //Catches case 'plain': and case '':
-                $result .= $this->textLine('Content-Type: ' . $this->ContentType . '; charset=' . $this->CharSet);
-                $ismultipart = false;
-                break;
-        }
-        //RFC1341 part 5 says 7bit is assumed if not specified
-        if (static::ENCODING_7BIT !== $this->Encoding) {
-            //RFC 2045 section 6.4 says multipart MIME parts may only use 7bit, 8bit or binary CTE
-            if ($ismultipart) {
-                if (static::ENCODING_8BIT === $this->Encoding) {
-                    $result .= $this->headerLine('Content-Transfer-Encoding', static::ENCODING_8BIT);
-                }
-                //The only remaining alternatives are quoted-printable and base64, which are both 7bit compatible
-            } else {
-                $result .= $this->headerLine('Content-Transfer-Encoding', $this->Encoding);
-            }
-        }
-
-        return $result;
-    }
-
-    /**
-     * Returns the whole MIME message.
-     * Includes complete headers and body.
-     * Only valid post preSend().
-     *
-     * @see PHPMailer::preSend()
-     *
-     * @return string
-     */
-    public function getSentMIMEMessage()
-    {
-        return static::stripTrailingWSP($this->MIMEHeader . $this->mailHeader) .
-            static::$LE . static::$LE . $this->MIMEBody;
-    }
-
-    /**
-     * Create a unique ID to use for boundaries.
-     *
-     * @return string
-     */
-    protected function generateId()
-    {
-        $len = 32; //32 bytes = 256 bits
-        $bytes = '';
-        if (function_exists('random_bytes')) {
-            try {
-                $bytes = random_bytes($len);
-            } catch (\Exception $e) {
-                //Do nothing
-            }
-        } elseif (function_exists('openssl_random_pseudo_bytes')) {
-            /** @noinspection CryptographicallySecureRandomnessInspection */
-            $bytes = openssl_random_pseudo_bytes($len);
-        }
-        if ($bytes === '') {
-            //We failed to produce a proper random string, so make do.
-            //Use a hash to force the length to the same as the other methods
-            $bytes = hash('sha256', uniqid((string) mt_rand(), true), true);
-        }
-
-        //We don't care about messing up base64 format here, just want a random string
-        return str_replace(['=', '+', '/'], '', base64_encode(hash('sha256', $bytes, true)));
-    }
-
-    /**
-     * Assemble the message body.
-     * Returns an empty string on failure.
-     *
-     * @throws Exception
-     *
-     * @return string The assembled message body
-     */
-    public function createBody()
-    {
-        $body = '';
-        //Create unique IDs and preset boundaries
-        $this->setBoundaries();
-
-        if ($this->sign_key_file) {
-            $body .= $this->getMailMIME() . static::$LE;
-        }
-
-        $this->setWordWrap();
-
-        $bodyEncoding = $this->Encoding;
-        $bodyCharSet = $this->CharSet;
-        //Can we do a 7-bit downgrade?
-        if (static::ENCODING_8BIT === $bodyEncoding && !$this->has8bitChars($this->Body)) {
-            $bodyEncoding = static::ENCODING_7BIT;
-            //All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit
-            $bodyCharSet = static::CHARSET_ASCII;
-        }
-        //If lines are too long, and we're not already using an encoding that will shorten them,
-        //change to quoted-printable transfer encoding for the body part only
-        if (static::ENCODING_BASE64 !== $this->Encoding && static::hasLineLongerThanMax($this->Body)) {
-            $bodyEncoding = static::ENCODING_QUOTED_PRINTABLE;
-        }
-
-        $altBodyEncoding = $this->Encoding;
-        $altBodyCharSet = $this->CharSet;
-        //Can we do a 7-bit downgrade?
-        if (static::ENCODING_8BIT === $altBodyEncoding && !$this->has8bitChars($this->AltBody)) {
-            $altBodyEncoding = static::ENCODING_7BIT;
-            //All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit
-            $altBodyCharSet = static::CHARSET_ASCII;
-        }
-        //If lines are too long, and we're not already using an encoding that will shorten them,
-        //change to quoted-printable transfer encoding for the alt body part only
-        if (static::ENCODING_BASE64 !== $altBodyEncoding && static::hasLineLongerThanMax($this->AltBody)) {
-            $altBodyEncoding = static::ENCODING_QUOTED_PRINTABLE;
-        }
-        //Use this as a preamble in all multipart message types
-        $mimepre = '';
-        switch ($this->message_type) {
-            case 'inline':
-                $body .= $mimepre;
-                $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding);
-                $body .= $this->encodeString($this->Body, $bodyEncoding);
-                $body .= static::$LE;
-                $body .= $this->attachAll('inline', $this->boundary[1]);
-                break;
-            case 'attach':
-                $body .= $mimepre;
-                $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding);
-                $body .= $this->encodeString($this->Body, $bodyEncoding);
-                $body .= static::$LE;
-                $body .= $this->attachAll('attachment', $this->boundary[1]);
-                break;
-            case 'inline_attach':
-                $body .= $mimepre;
-                $body .= $this->textLine('--' . $this->boundary[1]);
-                $body .= $this->headerLine('Content-Type', static::CONTENT_TYPE_MULTIPART_RELATED . ';');
-                $body .= $this->textLine(' boundary="' . $this->boundary[2] . '";');
-                $body .= $this->textLine(' type="' . static::CONTENT_TYPE_TEXT_HTML . '"');
-                $body .= static::$LE;
-                $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, '', $bodyEncoding);
-                $body .= $this->encodeString($this->Body, $bodyEncoding);
-                $body .= static::$LE;
-                $body .= $this->attachAll('inline', $this->boundary[2]);
-                $body .= static::$LE;
-                $body .= $this->attachAll('attachment', $this->boundary[1]);
-                break;
-            case 'alt':
-                $body .= $mimepre;
-                $body .= $this->getBoundary(
-                    $this->boundary[1],
-                    $altBodyCharSet,
-                    static::CONTENT_TYPE_PLAINTEXT,
-                    $altBodyEncoding
-                );
-                $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
-                $body .= static::$LE;
-                $body .= $this->getBoundary(
-                    $this->boundary[1],
-                    $bodyCharSet,
-                    static::CONTENT_TYPE_TEXT_HTML,
-                    $bodyEncoding
-                );
-                $body .= $this->encodeString($this->Body, $bodyEncoding);
-                $body .= static::$LE;
-                if (!empty($this->Ical)) {
-                    $method = static::ICAL_METHOD_REQUEST;
-                    foreach (static::$IcalMethods as $imethod) {
-                        if (stripos($this->Ical, 'METHOD:' . $imethod) !== false) {
-                            $method = $imethod;
-                            break;
-                        }
-                    }
-                    $body .= $this->getBoundary(
-                        $this->boundary[1],
-                        '',
-                        static::CONTENT_TYPE_TEXT_CALENDAR . '; method=' . $method,
-                        ''
-                    );
-                    $body .= $this->encodeString($this->Ical, $this->Encoding);
-                    $body .= static::$LE;
-                }
-                $body .= $this->endBoundary($this->boundary[1]);
-                break;
-            case 'alt_inline':
-                $body .= $mimepre;
-                $body .= $this->getBoundary(
-                    $this->boundary[1],
-                    $altBodyCharSet,
-                    static::CONTENT_TYPE_PLAINTEXT,
-                    $altBodyEncoding
-                );
-                $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
-                $body .= static::$LE;
-                $body .= $this->textLine('--' . $this->boundary[1]);
-                $body .= $this->headerLine('Content-Type', static::CONTENT_TYPE_MULTIPART_RELATED . ';');
-                $body .= $this->textLine(' boundary="' . $this->boundary[2] . '";');
-                $body .= $this->textLine(' type="' . static::CONTENT_TYPE_TEXT_HTML . '"');
-                $body .= static::$LE;
-                $body .= $this->getBoundary(
-                    $this->boundary[2],
-                    $bodyCharSet,
-                    static::CONTENT_TYPE_TEXT_HTML,
-                    $bodyEncoding
-                );
-                $body .= $this->encodeString($this->Body, $bodyEncoding);
-                $body .= static::$LE;
-                $body .= $this->attachAll('inline', $this->boundary[2]);
-                $body .= static::$LE;
-                $body .= $this->endBoundary($this->boundary[1]);
-                break;
-            case 'alt_attach':
-                $body .= $mimepre;
-                $body .= $this->textLine('--' . $this->boundary[1]);
-                $body .= $this->headerLine('Content-Type', static::CONTENT_TYPE_MULTIPART_ALTERNATIVE . ';');
-                $body .= $this->textLine(' boundary="' . $this->boundary[2] . '"');
-                $body .= static::$LE;
-                $body .= $this->getBoundary(
-                    $this->boundary[2],
-                    $altBodyCharSet,
-                    static::CONTENT_TYPE_PLAINTEXT,
-                    $altBodyEncoding
-                );
-                $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
-                $body .= static::$LE;
-                $body .= $this->getBoundary(
-                    $this->boundary[2],
-                    $bodyCharSet,
-                    static::CONTENT_TYPE_TEXT_HTML,
-                    $bodyEncoding
-                );
-                $body .= $this->encodeString($this->Body, $bodyEncoding);
-                $body .= static::$LE;
-                if (!empty($this->Ical)) {
-                    $method = static::ICAL_METHOD_REQUEST;
-                    foreach (static::$IcalMethods as $imethod) {
-                        if (stripos($this->Ical, 'METHOD:' . $imethod) !== false) {
-                            $method = $imethod;
-                            break;
-                        }
-                    }
-                    $body .= $this->getBoundary(
-                        $this->boundary[2],
-                        '',
-                        static::CONTENT_TYPE_TEXT_CALENDAR . '; method=' . $method,
-                        ''
-                    );
-                    $body .= $this->encodeString($this->Ical, $this->Encoding);
-                }
-                $body .= $this->endBoundary($this->boundary[2]);
-                $body .= static::$LE;
-                $body .= $this->attachAll('attachment', $this->boundary[1]);
-                break;
-            case 'alt_inline_attach':
-                $body .= $mimepre;
-                $body .= $this->textLine('--' . $this->boundary[1]);
-                $body .= $this->headerLine('Content-Type', static::CONTENT_TYPE_MULTIPART_ALTERNATIVE . ';');
-                $body .= $this->textLine(' boundary="' . $this->boundary[2] . '"');
-                $body .= static::$LE;
-                $body .= $this->getBoundary(
-                    $this->boundary[2],
-                    $altBodyCharSet,
-                    static::CONTENT_TYPE_PLAINTEXT,
-                    $altBodyEncoding
-                );
-                $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
-                $body .= static::$LE;
-                $body .= $this->textLine('--' . $this->boundary[2]);
-                $body .= $this->headerLine('Content-Type', static::CONTENT_TYPE_MULTIPART_RELATED . ';');
-                $body .= $this->textLine(' boundary="' . $this->boundary[3] . '";');
-                $body .= $this->textLine(' type="' . static::CONTENT_TYPE_TEXT_HTML . '"');
-                $body .= static::$LE;
-                $body .= $this->getBoundary(
-                    $this->boundary[3],
-                    $bodyCharSet,
-                    static::CONTENT_TYPE_TEXT_HTML,
-                    $bodyEncoding
-                );
-                $body .= $this->encodeString($this->Body, $bodyEncoding);
-                $body .= static::$LE;
-                $body .= $this->attachAll('inline', $this->boundary[3]);
-                $body .= static::$LE;
-                $body .= $this->endBoundary($this->boundary[2]);
-                $body .= static::$LE;
-                $body .= $this->attachAll('attachment', $this->boundary[1]);
-                break;
-            default:
-                //Catch case 'plain' and case '', applies to simple `text/plain` and `text/html` body content types
-                //Reset the `Encoding` property in case we changed it for line length reasons
-                $this->Encoding = $bodyEncoding;
-                $body .= $this->encodeString($this->Body, $this->Encoding);
-                break;
-        }
-
-        if ($this->isError()) {
-            $body = '';
-            if ($this->exceptions) {
-                throw new Exception($this->lang('empty_message'), self::STOP_CRITICAL);
-            }
-        } elseif ($this->sign_key_file) {
-            try {
-                if (!defined('PKCS7_TEXT')) {
-                    throw new Exception($this->lang('extension_missing') . 'openssl');
-                }
-
-                $file = tempnam(sys_get_temp_dir(), 'srcsign');
-                $signed = tempnam(sys_get_temp_dir(), 'mailsign');
-                file_put_contents($file, $body);
-
-                //Workaround for PHP bug https://bugs.php.net/bug.php?id=69197
-                if (empty($this->sign_extracerts_file)) {
-                    $sign = @openssl_pkcs7_sign(
-                        $file,
-                        $signed,
-                        'file://' . realpath($this->sign_cert_file),
-                        ['file://' . realpath($this->sign_key_file), $this->sign_key_pass],
-                        []
-                    );
-                } else {
-                    $sign = @openssl_pkcs7_sign(
-                        $file,
-                        $signed,
-                        'file://' . realpath($this->sign_cert_file),
-                        ['file://' . realpath($this->sign_key_file), $this->sign_key_pass],
-                        [],
-                        PKCS7_DETACHED,
-                        $this->sign_extracerts_file
-                    );
-                }
-
-                @unlink($file);
-                if ($sign) {
-                    $body = file_get_contents($signed);
-                    @unlink($signed);
-                    //The message returned by openssl contains both headers and body, so need to split them up
-                    $parts = explode("\n\n", $body, 2);
-                    $this->MIMEHeader .= $parts[0] . static::$LE . static::$LE;
-                    $body = $parts[1];
-                } else {
-                    @unlink($signed);
-                    throw new Exception($this->lang('signing') . openssl_error_string());
-                }
-            } catch (Exception $exc) {
-                $body = '';
-                if ($this->exceptions) {
-                    throw $exc;
-                }
-            }
-        }
-
-        return $body;
-    }
-
-    /**
-     * Get the boundaries that this message will use
-     * @return array
-     */
-    public function getBoundaries()
-    {
-        if (empty($this->boundary)) {
-            $this->setBoundaries();
-        }
-        return $this->boundary;
-    }
-
-    /**
-     * Return the start of a message boundary.
-     *
-     * @param string $boundary
-     * @param string $charSet
-     * @param string $contentType
-     * @param string $encoding
-     *
-     * @return string
-     */
-    protected function getBoundary($boundary, $charSet, $contentType, $encoding)
-    {
-        $result = '';
-        if ('' === $charSet) {
-            $charSet = $this->CharSet;
-        }
-        if ('' === $contentType) {
-            $contentType = $this->ContentType;
-        }
-        if ('' === $encoding) {
-            $encoding = $this->Encoding;
-        }
-        $result .= $this->textLine('--' . $boundary);
-        $result .= sprintf('Content-Type: %s; charset=%s', $contentType, $charSet);
-        $result .= static::$LE;
-        //RFC1341 part 5 says 7bit is assumed if not specified
-        if (static::ENCODING_7BIT !== $encoding) {
-            $result .= $this->headerLine('Content-Transfer-Encoding', $encoding);
-        }
-        $result .= static::$LE;
-
-        return $result;
-    }
-
-    /**
-     * Return the end of a message boundary.
-     *
-     * @param string $boundary
-     *
-     * @return string
-     */
-    protected function endBoundary($boundary)
-    {
-        return static::$LE . '--' . $boundary . '--' . static::$LE;
-    }
-
-    /**
-     * Set the message type.
-     * PHPMailer only supports some preset message types, not arbitrary MIME structures.
-     */
-    protected function setMessageType()
-    {
-        $type = [];
-        if ($this->alternativeExists()) {
-            $type[] = 'alt';
-        }
-        if ($this->inlineImageExists()) {
-            $type[] = 'inline';
-        }
-        if ($this->attachmentExists()) {
-            $type[] = 'attach';
-        }
-        $this->message_type = implode('_', $type);
-        if ('' === $this->message_type) {
-            //The 'plain' message_type refers to the message having a single body element, not that it is plain-text
-            $this->message_type = 'plain';
-        }
-    }
-
-    /**
-     * Format a header line.
-     *
-     * @param string     $name
-     * @param string|int $value
-     *
-     * @return string
-     */
-    public function headerLine($name, $value)
-    {
-        return $name . ': ' . $value . static::$LE;
-    }
-
-    /**
-     * Return a formatted mail line.
-     *
-     * @param string $value
-     *
-     * @return string
-     */
-    public function textLine($value)
-    {
-        return $value . static::$LE;
-    }
-
-    /**
-     * Add an attachment from a path on the filesystem.
-     * Never use a user-supplied path to a file!
-     * Returns false if the file could not be found or read.
-     * Explicitly *does not* support passing URLs; PHPMailer is not an HTTP client.
-     * If you need to do that, fetch the resource yourself and pass it in via a local file or string.
-     *
-     * @param string $path        Path to the attachment
-     * @param string $name        Overrides the attachment name
-     * @param string $encoding    File encoding (see $Encoding)
-     * @param string $type        MIME type, e.g. `image/jpeg`; determined automatically from $path if not specified
-     * @param string $disposition Disposition to use
-     *
-     * @throws Exception
-     *
-     * @return bool
-     */
-    public function addAttachment(
-        $path,
-        $name = '',
-        $encoding = self::ENCODING_BASE64,
-        $type = '',
-        $disposition = 'attachment'
-    ) {
-        try {
-            if (!static::fileIsAccessible($path)) {
-                throw new Exception($this->lang('file_access') . $path, self::STOP_CONTINUE);
-            }
-
-            //If a MIME type is not specified, try to work it out from the file name
-            if ('' === $type) {
-                $type = static::filenameToType($path);
-            }
-
-            $filename = (string) static::mb_pathinfo($path, PATHINFO_BASENAME);
-            if ('' === $name) {
-                $name = $filename;
-            }
-            if (!$this->validateEncoding($encoding)) {
-                throw new Exception($this->lang('encoding') . $encoding);
-            }
-
-            $this->attachment[] = [
-                0 => $path,
-                1 => $filename,
-                2 => $name,
-                3 => $encoding,
-                4 => $type,
-                5 => false, //isStringAttachment
-                6 => $disposition,
-                7 => $name,
-            ];
-        } catch (Exception $exc) {
-            $this->setError($exc->getMessage());
-            $this->edebug($exc->getMessage());
-            if ($this->exceptions) {
-                throw $exc;
-            }
-
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Return the array of attachments.
-     *
-     * @return array
-     */
-    public function getAttachments()
-    {
-        return $this->attachment;
-    }
-
-    /**
-     * Attach all file, string, and binary attachments to the message.
-     * Returns an empty string on failure.
-     *
-     * @param string $disposition_type
-     * @param string $boundary
-     *
-     * @throws Exception
-     *
-     * @return string
-     */
-    protected function attachAll($disposition_type, $boundary)
-    {
-        //Return text of body
-        $mime = [];
-        $cidUniq = [];
-        $incl = [];
-
-        //Add all attachments
-        foreach ($this->attachment as $attachment) {
-            //Check if it is a valid disposition_filter
-            if ($attachment[6] === $disposition_type) {
-                //Check for string attachment
-                $string = '';
-                $path = '';
-                $bString = $attachment[5];
-                if ($bString) {
-                    $string = $attachment[0];
-                } else {
-                    $path = $attachment[0];
-                }
-
-                $inclhash = hash('sha256', serialize($attachment));
-                if (in_array($inclhash, $incl, true)) {
-                    continue;
-                }
-                $incl[] = $inclhash;
-                $name = $attachment[2];
-                $encoding = $attachment[3];
-                $type = $attachment[4];
-                $disposition = $attachment[6];
-                $cid = $attachment[7];
-                if ('inline' === $disposition && array_key_exists($cid, $cidUniq)) {
-                    continue;
-                }
-                $cidUniq[$cid] = true;
-
-                $mime[] = sprintf('--%s%s', $boundary, static::$LE);
-                //Only include a filename property if we have one
-                if (!empty($name)) {
-                    $mime[] = sprintf(
-                        'Content-Type: %s; name=%s%s',
-                        $type,
-                        static::quotedString($this->encodeHeader($this->secureHeader($name))),
-                        static::$LE
-                    );
-                } else {
-                    $mime[] = sprintf(
-                        'Content-Type: %s%s',
-                        $type,
-                        static::$LE
-                    );
-                }
-                //RFC1341 part 5 says 7bit is assumed if not specified
-                if (static::ENCODING_7BIT !== $encoding) {
-                    $mime[] = sprintf('Content-Transfer-Encoding: %s%s', $encoding, static::$LE);
-                }
-
-                //Only set Content-IDs on inline attachments
-                if ((string) $cid !== '' && $disposition === 'inline') {
-                    $mime[] = 'Content-ID: <' . $this->encodeHeader($this->secureHeader($cid)) . '>' . static::$LE;
-                }
-
-                //Allow for bypassing the Content-Disposition header
-                if (!empty($disposition)) {
-                    $encoded_name = $this->encodeHeader($this->secureHeader($name));
-                    if (!empty($encoded_name)) {
-                        $mime[] = sprintf(
-                            'Content-Disposition: %s; filename=%s%s',
-                            $disposition,
-                            static::quotedString($encoded_name),
-                            static::$LE . static::$LE
-                        );
-                    } else {
-                        $mime[] = sprintf(
-                            'Content-Disposition: %s%s',
-                            $disposition,
-                            static::$LE . static::$LE
-                        );
-                    }
-                } else {
-                    $mime[] = static::$LE;
-                }
-
-                //Encode as string attachment
-                if ($bString) {
-                    $mime[] = $this->encodeString($string, $encoding);
-                } else {
-                    $mime[] = $this->encodeFile($path, $encoding);
-                }
-                if ($this->isError()) {
-                    return '';
-                }
-                $mime[] = static::$LE;
-            }
-        }
-
-        $mime[] = sprintf('--%s--%s', $boundary, static::$LE);
-
-        return implode('', $mime);
-    }
-
-    /**
-     * Encode a file attachment in requested format.
-     * Returns an empty string on failure.
-     *
-     * @param string $path     The full path to the file
-     * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
-     *
-     * @return string
-     */
-    protected function encodeFile($path, $encoding = self::ENCODING_BASE64)
-    {
-        try {
-            if (!static::fileIsAccessible($path)) {
-                throw new Exception($this->lang('file_open') . $path, self::STOP_CONTINUE);
-            }
-            $file_buffer = file_get_contents($path);
-            if (false === $file_buffer) {
-                throw new Exception($this->lang('file_open') . $path, self::STOP_CONTINUE);
-            }
-            $file_buffer = $this->encodeString($file_buffer, $encoding);
-
-            return $file_buffer;
-        } catch (Exception $exc) {
-            $this->setError($exc->getMessage());
-            $this->edebug($exc->getMessage());
-            if ($this->exceptions) {
-                throw $exc;
-            }
-
-            return '';
-        }
-    }
-
-    /**
-     * Encode a string in requested format.
-     * Returns an empty string on failure.
-     *
-     * @param string $str      The text to encode
-     * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
-     *
-     * @throws Exception
-     *
-     * @return string
-     */
-    public function encodeString($str, $encoding = self::ENCODING_BASE64)
-    {
-        $encoded = '';
-        switch (strtolower($encoding)) {
-            case static::ENCODING_BASE64:
-                $encoded = chunk_split(
-                    base64_encode($str),
-                    static::STD_LINE_LENGTH,
-                    static::$LE
-                );
-                break;
-            case static::ENCODING_7BIT:
-            case static::ENCODING_8BIT:
-                $encoded = static::normalizeBreaks($str);
-                //Make sure it ends with a line break
-                if (substr($encoded, -(strlen(static::$LE))) !== static::$LE) {
-                    $encoded .= static::$LE;
-                }
-                break;
-            case static::ENCODING_BINARY:
-                $encoded = $str;
-                break;
-            case static::ENCODING_QUOTED_PRINTABLE:
-                $encoded = $this->encodeQP($str);
-                break;
-            default:
-                $this->setError($this->lang('encoding') . $encoding);
-                if ($this->exceptions) {
-                    throw new Exception($this->lang('encoding') . $encoding);
-                }
-                break;
-        }
-
-        return $encoded;
-    }
-
-    /**
-     * Encode a header value (not including its label) optimally.
-     * Picks shortest of Q, B, or none. Result includes folding if needed.
-     * See RFC822 definitions for phrase, comment and text positions.
-     *
-     * @param string $str      The header value to encode
-     * @param string $position What context the string will be used in
-     *
-     * @return string
-     */
-    public function encodeHeader($str, $position = 'text')
-    {
-        $matchcount = 0;
-        switch (strtolower($position)) {
-            case 'phrase':
-                if (!preg_match('/[\200-\377]/', $str)) {
-                    //Can't use addslashes as we don't know the value of magic_quotes_sybase
-                    $encoded = addcslashes($str, "\0..\37\177\\\"");
-                    if (($str === $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
-                        return $encoded;
-                    }
-
-                    return "\"$encoded\"";
-                }
-                $matchcount = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
-                break;
-            /* @noinspection PhpMissingBreakStatementInspection */
-            case 'comment':
-                $matchcount = preg_match_all('/[()"]/', $str, $matches);
-            //fallthrough
-            case 'text':
-            default:
-                $matchcount += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
-                break;
-        }
-
-        if ($this->has8bitChars($str)) {
-            $charset = $this->CharSet;
-        } else {
-            $charset = static::CHARSET_ASCII;
-        }
-
-        //Q/B encoding adds 8 chars and the charset ("` =?<charset>?[QB]?<content>?=`").
-        $overhead = 8 + strlen($charset);
-
-        if ('mail' === $this->Mailer) {
-            $maxlen = static::MAIL_MAX_LINE_LENGTH - $overhead;
-        } else {
-            $maxlen = static::MAX_LINE_LENGTH - $overhead;
-        }
-
-        //Select the encoding that produces the shortest output and/or prevents corruption.
-        if ($matchcount > strlen($str) / 3) {
-            //More than 1/3 of the content needs encoding, use B-encode.
-            $encoding = 'B';
-        } elseif ($matchcount > 0) {
-            //Less than 1/3 of the content needs encoding, use Q-encode.
-            $encoding = 'Q';
-        } elseif (strlen($str) > $maxlen) {
-            //No encoding needed, but value exceeds max line length, use Q-encode to prevent corruption.
-            $encoding = 'Q';
-        } else {
-            //No reformatting needed
-            $encoding = false;
-        }
-
-        switch ($encoding) {
-            case 'B':
-                if ($this->hasMultiBytes($str)) {
-                    //Use a custom function which correctly encodes and wraps long
-                    //multibyte strings without breaking lines within a character
-                    $encoded = $this->base64EncodeWrapMB($str, "\n");
-                } else {
-                    $encoded = base64_encode($str);
-                    $maxlen -= $maxlen % 4;
-                    $encoded = trim(chunk_split($encoded, $maxlen, "\n"));
-                }
-                $encoded = preg_replace('/^(.*)$/m', ' =?' . $charset . "?$encoding?\\1?=", $encoded);
-                break;
-            case 'Q':
-                $encoded = $this->encodeQ($str, $position);
-                $encoded = $this->wrapText($encoded, $maxlen, true);
-                $encoded = str_replace('=' . static::$LE, "\n", trim($encoded));
-                $encoded = preg_replace('/^(.*)$/m', ' =?' . $charset . "?$encoding?\\1?=", $encoded);
-                break;
-            default:
-                return $str;
-        }
-
-        return trim(static::normalizeBreaks($encoded));
-    }
-
-    /**
-     * Check if a string contains multi-byte characters.
-     *
-     * @param string $str multi-byte text to wrap encode
-     *
-     * @return bool
-     */
-    public function hasMultiBytes($str)
-    {
-        if (function_exists('mb_strlen')) {
-            return strlen($str) > mb_strlen($str, $this->CharSet);
-        }
-
-        //Assume no multibytes (we can't handle without mbstring functions anyway)
-        return false;
-    }
-
-    /**
-     * Does a string contain any 8-bit chars (in any charset)?
-     *
-     * @param string $text
-     *
-     * @return bool
-     */
-    public function has8bitChars($text)
-    {
-        return (bool) preg_match('/[\x80-\xFF]/', $text);
-    }
-
-    /**
-     * Encode and wrap long multibyte strings for mail headers
-     * without breaking lines within a character.
-     * Adapted from a function by paravoid.
-     *
-     * @see https://www.php.net/manual/en/function.mb-encode-mimeheader.php#60283
-     *
-     * @param string $str       multi-byte text to wrap encode
-     * @param string $linebreak string to use as linefeed/end-of-line
-     *
-     * @return string
-     */
-    public function base64EncodeWrapMB($str, $linebreak = null)
-    {
-        $start = '=?' . $this->CharSet . '?B?';
-        $end = '?=';
-        $encoded = '';
-        if (null === $linebreak) {
-            $linebreak = static::$LE;
-        }
-
-        $mb_length = mb_strlen($str, $this->CharSet);
-        //Each line must have length <= 75, including $start and $end
-        $length = 75 - strlen($start) - strlen($end);
-        //Average multi-byte ratio
-        $ratio = $mb_length / strlen($str);
-        //Base64 has a 4:3 ratio
-        $avgLength = floor($length * $ratio * .75);
-
-        $offset = 0;
-        for ($i = 0; $i < $mb_length; $i += $offset) {
-            $lookBack = 0;
-            do {
-                $offset = $avgLength - $lookBack;
-                $chunk = mb_substr($str, $i, $offset, $this->CharSet);
-                $chunk = base64_encode($chunk);
-                ++$lookBack;
-            } while (strlen($chunk) > $length);
-            $encoded .= $chunk . $linebreak;
-        }
-
-        //Chomp the last linefeed
-        return substr($encoded, 0, -strlen($linebreak));
-    }
-
-    /**
-     * Encode a string in quoted-printable format.
-     * According to RFC2045 section 6.7.
-     *
-     * @param string $string The text to encode
-     *
-     * @return string
-     */
-    public function encodeQP($string)
-    {
-        return static::normalizeBreaks(quoted_printable_encode($string));
-    }
-
-    /**
-     * Encode a string using Q encoding.
-     *
-     * @see https://www.rfc-editor.org/rfc/rfc2047#section-4.2
-     *
-     * @param string $str      the text to encode
-     * @param string $position Where the text is going to be used, see the RFC for what that means
-     *
-     * @return string
-     */
-    public function encodeQ($str, $position = 'text')
-    {
-        //There should not be any EOL in the string
-        $pattern = '';
-        $encoded = str_replace(["\r", "\n"], '', $str);
-        switch (strtolower($position)) {
-            case 'phrase':
-                //RFC 2047 section 5.3
-                $pattern = '^A-Za-z0-9!*+\/ -';
-                break;
-            /*
-             * RFC 2047 section 5.2.
-             * Build $pattern without including delimiters and []
-             */
-            /* @noinspection PhpMissingBreakStatementInspection */
-            case 'comment':
-                $pattern = '\(\)"';
-            /* Intentional fall through */
-            case 'text':
-            default:
-                //RFC 2047 section 5.1
-                //Replace every high ascii, control, =, ? and _ characters
-                $pattern = '\000-\011\013\014\016-\037\075\077\137\177-\377' . $pattern;
-                break;
-        }
-        $matches = [];
-        if (preg_match_all("/[{$pattern}]/", $encoded, $matches)) {
-            //If the string contains an '=', make sure it's the first thing we replace
-            //so as to avoid double-encoding
-            $eqkey = array_search('=', $matches[0], true);
-            if (false !== $eqkey) {
-                unset($matches[0][$eqkey]);
-                array_unshift($matches[0], '=');
-            }
-            foreach (array_unique($matches[0]) as $char) {
-                $encoded = str_replace($char, '=' . sprintf('%02X', ord($char)), $encoded);
-            }
-        }
-        //Replace spaces with _ (more readable than =20)
-        //RFC 2047 section 4.2(2)
-        return str_replace(' ', '_', $encoded);
-    }
-
-    /**
-     * Add a string or binary attachment (non-filesystem).
-     * This method can be used to attach ascii or binary data,
-     * such as a BLOB record from a database.
-     *
-     * @param string $string      String attachment data
-     * @param string $filename    Name of the attachment
-     * @param string $encoding    File encoding (see $Encoding)
-     * @param string $type        File extension (MIME) type
-     * @param string $disposition Disposition to use
-     *
-     * @throws Exception
-     *
-     * @return bool True on successfully adding an attachment
-     */
-    public function addStringAttachment(
-        $string,
-        $filename,
-        $encoding = self::ENCODING_BASE64,
-        $type = '',
-        $disposition = 'attachment'
-    ) {
-        try {
-            //If a MIME type is not specified, try to work it out from the file name
-            if ('' === $type) {
-                $type = static::filenameToType($filename);
-            }
-
-            if (!$this->validateEncoding($encoding)) {
-                throw new Exception($this->lang('encoding') . $encoding);
-            }
-
-            //Append to $attachment array
-            $this->attachment[] = [
-                0 => $string,
-                1 => $filename,
-                2 => static::mb_pathinfo($filename, PATHINFO_BASENAME),
-                3 => $encoding,
-                4 => $type,
-                5 => true, //isStringAttachment
-                6 => $disposition,
-                7 => 0,
-            ];
-        } catch (Exception $exc) {
-            $this->setError($exc->getMessage());
-            $this->edebug($exc->getMessage());
-            if ($this->exceptions) {
-                throw $exc;
-            }
-
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Add an embedded (inline) attachment from a file.
-     * This can include images, sounds, and just about any other document type.
-     * These differ from 'regular' attachments in that they are intended to be
-     * displayed inline with the message, not just attached for download.
-     * This is used in HTML messages that embed the images
-     * the HTML refers to using the `$cid` value in `img` tags, for example `<img src="cid:mylogo">`.
-     * Never use a user-supplied path to a file!
-     *
-     * @param string $path        Path to the attachment
-     * @param string $cid         Content ID of the attachment; Use this to reference
-     *                            the content when using an embedded image in HTML
-     * @param string $name        Overrides the attachment filename
-     * @param string $encoding    File encoding (see $Encoding) defaults to `base64`
-     * @param string $type        File MIME type (by default mapped from the `$path` filename's extension)
-     * @param string $disposition Disposition to use: `inline` (default) or `attachment`
-     *                            (unlikely you want this ΓÇô {@see `addAttachment()`} instead)
-     *
-     * @return bool True on successfully adding an attachment
-     * @throws Exception
-     *
-     */
-    public function addEmbeddedImage(
-        $path,
-        $cid,
-        $name = '',
-        $encoding = self::ENCODING_BASE64,
-        $type = '',
-        $disposition = 'inline'
-    ) {
-        try {
-            if (!static::fileIsAccessible($path)) {
-                throw new Exception($this->lang('file_access') . $path, self::STOP_CONTINUE);
-            }
-
-            //If a MIME type is not specified, try to work it out from the file name
-            if ('' === $type) {
-                $type = static::filenameToType($path);
-            }
-
-            if (!$this->validateEncoding($encoding)) {
-                throw new Exception($this->lang('encoding') . $encoding);
-            }
-
-            $filename = (string) static::mb_pathinfo($path, PATHINFO_BASENAME);
-            if ('' === $name) {
-                $name = $filename;
-            }
-
-            //Append to $attachment array
-            $this->attachment[] = [
-                0 => $path,
-                1 => $filename,
-                2 => $name,
-                3 => $encoding,
-                4 => $type,
-                5 => false, //isStringAttachment
-                6 => $disposition,
-                7 => $cid,
-            ];
-        } catch (Exception $exc) {
-            $this->setError($exc->getMessage());
-            $this->edebug($exc->getMessage());
-            if ($this->exceptions) {
-                throw $exc;
-            }
-
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Add an embedded stringified attachment.
-     * This can include images, sounds, and just about any other document type.
-     * If your filename doesn't contain an extension, be sure to set the $type to an appropriate MIME type.
-     *
-     * @param string $string      The attachment binary data
-     * @param string $cid         Content ID of the attachment; Use this to reference
-     *                            the content when using an embedded image in HTML
-     * @param string $name        A filename for the attachment. If this contains an extension,
-     *                            PHPMailer will attempt to set a MIME type for the attachment.
-     *                            For example 'file.jpg' would get an 'image/jpeg' MIME type.
-     * @param string $encoding    File encoding (see $Encoding), defaults to 'base64'
-     * @param string $type        MIME type - will be used in preference to any automatically derived type
-     * @param string $disposition Disposition to use
-     *
-     * @throws Exception
-     *
-     * @return bool True on successfully adding an attachment
-     */
-    public function addStringEmbeddedImage(
-        $string,
-        $cid,
-        $name = '',
-        $encoding = self::ENCODING_BASE64,
-        $type = '',
-        $disposition = 'inline'
-    ) {
-        try {
-            //If a MIME type is not specified, try to work it out from the name
-            if ('' === $type && !empty($name)) {
-                $type = static::filenameToType($name);
-            }
-
-            if (!$this->validateEncoding($encoding)) {
-                throw new Exception($this->lang('encoding') . $encoding);
-            }
-
-            //Append to $attachment array
-            $this->attachment[] = [
-                0 => $string,
-                1 => $name,
-                2 => $name,
-                3 => $encoding,
-                4 => $type,
-                5 => true, //isStringAttachment
-                6 => $disposition,
-                7 => $cid,
-            ];
-        } catch (Exception $exc) {
-            $this->setError($exc->getMessage());
-            $this->edebug($exc->getMessage());
-            if ($this->exceptions) {
-                throw $exc;
-            }
-
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Validate encodings.
-     *
-     * @param string $encoding
-     *
-     * @return bool
-     */
-    protected function validateEncoding($encoding)
-    {
-        return in_array(
-            $encoding,
-            [
-                self::ENCODING_7BIT,
-                self::ENCODING_QUOTED_PRINTABLE,
-                self::ENCODING_BASE64,
-                self::ENCODING_8BIT,
-                self::ENCODING_BINARY,
-            ],
-            true
-        );
-    }
-
-    /**
-     * Check if an embedded attachment is present with this cid.
-     *
-     * @param string $cid
-     *
-     * @return bool
-     */
-    protected function cidExists($cid)
-    {
-        foreach ($this->attachment as $attachment) {
-            if ('inline' === $attachment[6] && $cid === $attachment[7]) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Check if an inline attachment is present.
-     *
-     * @return bool
-     */
-    public function inlineImageExists()
-    {
-        foreach ($this->attachment as $attachment) {
-            if ('inline' === $attachment[6]) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Check if an attachment (non-inline) is present.
-     *
-     * @return bool
-     */
-    public function attachmentExists()
-    {
-        foreach ($this->attachment as $attachment) {
-            if ('attachment' === $attachment[6]) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Check if this message has an alternative body set.
-     *
-     * @return bool
-     */
-    public function alternativeExists()
-    {
-        return !empty($this->AltBody);
-    }
-
-    /**
-     * Clear queued addresses of given kind.
-     *
-     * @param string $kind 'to', 'cc', or 'bcc'
-     */
-    public function clearQueuedAddresses($kind)
-    {
-        $this->RecipientsQueue = array_filter(
-            $this->RecipientsQueue,
-            static function ($params) use ($kind) {
-                return $params[0] !== $kind;
-            }
-        );
-    }
-
-    /**
-     * Clear all To recipients.
-     */
-    public function clearAddresses()
-    {
-        foreach ($this->to as $to) {
-            unset($this->all_recipients[strtolower($to[0])]);
-        }
-        $this->to = [];
-        $this->clearQueuedAddresses('to');
-    }
-
-    /**
-     * Clear all CC recipients.
-     */
-    public function clearCCs()
-    {
-        foreach ($this->cc as $cc) {
-            unset($this->all_recipients[strtolower($cc[0])]);
-        }
-        $this->cc = [];
-        $this->clearQueuedAddresses('cc');
-    }
-
-    /**
-     * Clear all BCC recipients.
-     */
-    public function clearBCCs()
-    {
-        foreach ($this->bcc as $bcc) {
-            unset($this->all_recipients[strtolower($bcc[0])]);
-        }
-        $this->bcc = [];
-        $this->clearQueuedAddresses('bcc');
-    }
-
-    /**
-     * Clear all ReplyTo recipients.
-     */
-    public function clearReplyTos()
-    {
-        $this->ReplyTo = [];
-        $this->ReplyToQueue = [];
-    }
-
-    /**
-     * Clear all recipient types.
-     */
-    public function clearAllRecipients()
-    {
-        $this->to = [];
-        $this->cc = [];
-        $this->bcc = [];
-        $this->all_recipients = [];
-        $this->RecipientsQueue = [];
-    }
-
-    /**
-     * Clear all filesystem, string, and binary attachments.
-     */
-    public function clearAttachments()
-    {
-        $this->attachment = [];
-    }
-
-    /**
-     * Clear all custom headers.
-     */
-    public function clearCustomHeaders()
-    {
-        $this->CustomHeader = [];
-    }
-
-    /**
-     * Clear a specific custom header by name or name and value.
-     * $name value can be overloaded to contain
-     * both header name and value (name:value).
-     *
-     * @param string      $name  Custom header name
-     * @param string|null $value Header value
-     *
-     * @return bool True if a header was replaced successfully
-     */
-    public function clearCustomHeader($name, $value = null)
-    {
-        if (null === $value && strpos($name, ':') !== false) {
-            //Value passed in as name:value
-            list($name, $value) = explode(':', $name, 2);
-        }
-        $name = trim($name);
-        $value = (null === $value) ? null : trim($value);
-
-        foreach ($this->CustomHeader as $k => $pair) {
-            if ($pair[0] == $name) {
-                // We remove the header if the value is not provided or it matches.
-                if (null === $value ||  $pair[1] == $value) {
-                    unset($this->CustomHeader[$k]);
-                }
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Replace a custom header.
-     * $name value can be overloaded to contain
-     * both header name and value (name:value).
-     *
-     * @param string      $name  Custom header name
-     * @param string|null $value Header value
-     *
-     * @return bool True if a header was replaced successfully
-     * @throws Exception
-     */
-    public function replaceCustomHeader($name, $value = null)
-    {
-        if (null === $value && strpos($name, ':') !== false) {
-            //Value passed in as name:value
-            list($name, $value) = explode(':', $name, 2);
-        }
-        $name = trim($name);
-        $value = (null === $value) ? '' : trim($value);
-
-        $replaced = false;
-        foreach ($this->CustomHeader as $k => $pair) {
-            if ($pair[0] == $name) {
-                if ($replaced) {
-                    unset($this->CustomHeader[$k]);
-                    continue;
-                }
-                if (strpbrk($name . $value, "\r\n") !== false) {
-                    if ($this->exceptions) {
-                        throw new Exception($this->lang('invalid_header'));
-                    }
-
-                    return false;
-                }
-                $this->CustomHeader[$k] = [$name, $value];
-                $replaced = true;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Add an error message to the error container.
-     *
-     * @param string $msg
-     */
-    protected function setError($msg)
-    {
-        ++$this->error_count;
-        if ('smtp' === $this->Mailer && null !== $this->smtp) {
-            $lasterror = $this->smtp->getError();
-            if (!empty($lasterror['error'])) {
-                $msg .= $this->lang('smtp_error') . $lasterror['error'];
-                if (!empty($lasterror['detail'])) {
-                    $msg .= ' ' . $this->lang('smtp_detail') . $lasterror['detail'];
-                }
-                if (!empty($lasterror['smtp_code'])) {
-                    $msg .= ' ' . $this->lang('smtp_code') . $lasterror['smtp_code'];
-                }
-                if (!empty($lasterror['smtp_code_ex'])) {
-                    $msg .= ' ' . $this->lang('smtp_code_ex') . $lasterror['smtp_code_ex'];
-                }
-            }
-        }
-        $this->ErrorInfo = $msg;
-    }
-
-    /**
-     * Return an RFC 822 formatted date.
-     *
-     * @return string
-     */
-    public static function rfcDate()
-    {
-        //Set the time zone to whatever the default is to avoid 500 errors
-        //Will default to UTC if it's not set properly in php.ini
-        date_default_timezone_set(@date_default_timezone_get());
-
-        return date('D, j M Y H:i:s O');
-    }
-
-    /**
-     * Get the server hostname.
-     * Returns 'localhost.localdomain' if unknown.
-     *
-     * @return string
-     */
-    protected function serverHostname()
-    {
-        $result = '';
-        if (!empty($this->Hostname)) {
-            $result = $this->Hostname;
-        } elseif (isset($_SERVER) && array_key_exists('SERVER_NAME', $_SERVER)) {
-            $result = $_SERVER['SERVER_NAME'];
-        } elseif (function_exists('gethostname') && gethostname() !== false) {
-            $result = gethostname();
-        } elseif (php_uname('n') !== '') {
-            $result = php_uname('n');
-        }
-        if (!static::isValidHost($result)) {
-            return 'localhost.localdomain';
-        }
-
-        return $result;
-    }
-
-    /**
-     * Validate whether a string contains a valid value to use as a hostname or IP address.
-     * IPv6 addresses must include [], e.g. `[::1]`, not just `::1`.
-     *
-     * @param string $host The host name or IP address to check
-     *
-     * @return bool
-     */
-    public static function isValidHost($host)
-    {
-        //Simple syntax limits
-        if (
-            empty($host)
-            || !is_string($host)
-            || strlen($host) > 256
-            || !preg_match('/^([a-z\d.-]*|\[[a-f\d:]+\])$/i', $host)
-        ) {
-            return false;
-        }
-        //Looks like a bracketed IPv6 address
-        if (strlen($host) > 2 && substr($host, 0, 1) === '[' && substr($host, -1, 1) === ']') {
-            return filter_var(substr($host, 1, -1), FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false;
-        }
-        //If removing all the dots results in a numeric string, it must be an IPv4 address.
-        //Need to check this first because otherwise things like `999.0.0.0` are considered valid host names
-        if (is_numeric(str_replace('.', '', $host))) {
-            //Is it a valid IPv4 address?
-            return filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false;
-        }
-        //Is it a syntactically valid hostname (when embedded in a URL)?
-        return filter_var('https://' . $host, FILTER_VALIDATE_URL) !== false;
-    }
-
-    /**
-     * Get an error message in the current language.
-     *
-     * @param string $key
-     *
-     * @return string
-     */
-    protected function lang($key)
-    {
-        if (count($this->language) < 1) {
-            $this->setLanguage(); //Set the default language
-        }
-
-        if (array_key_exists($key, $this->language)) {
-            if ('smtp_connect_failed' === $key) {
-                //Include a link to troubleshooting docs on SMTP connection failure.
-                //This is by far the biggest cause of support questions
-                //but it's usually not PHPMailer's fault.
-                return $this->language[$key] . ' https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting';
-            }
-
-            return $this->language[$key];
-        }
-
-        //Return the key as a fallback
-        return $key;
-    }
-
-    /**
-     * Build an error message starting with a generic one and adding details if possible.
-     *
-     * @param string $base_key
-     * @return string
-     */
-    private function getSmtpErrorMessage($base_key)
-    {
-        $message = $this->lang($base_key);
-        $error = $this->smtp->getError();
-        if (!empty($error['error'])) {
-            $message .= ' ' . $error['error'];
-            if (!empty($error['detail'])) {
-                $message .= ' ' . $error['detail'];
-            }
-        }
-
-        return $message;
-    }
-
-    /**
-     * Check if an error occurred.
-     *
-     * @return bool True if an error did occur
-     */
-    public function isError()
-    {
-        return $this->error_count > 0;
-    }
-
-    /**
-     * Add a custom header.
-     * $name value can be overloaded to contain
-     * both header name and value (name:value).
-     *
-     * @param string      $name  Custom header name
-     * @param string|null $value Header value
-     *
-     * @return bool True if a header was set successfully
-     * @throws Exception
-     */
-    public function addCustomHeader($name, $value = null)
-    {
-        if (null === $value && strpos($name, ':') !== false) {
-            //Value passed in as name:value
-            list($name, $value) = explode(':', $name, 2);
-        }
-        $name = trim($name);
-        $value = (null === $value) ? '' : trim($value);
-        //Ensure name is not empty, and that neither name nor value contain line breaks
-        if (empty($name) || strpbrk($name . $value, "\r\n") !== false) {
-            if ($this->exceptions) {
-                throw new Exception($this->lang('invalid_header'));
-            }
-
-            return false;
-        }
-        $this->CustomHeader[] = [$name, $value];
-
-        return true;
-    }
-
-    /**
-     * Returns all custom headers.
-     *
-     * @return array
-     */
-    public function getCustomHeaders()
-    {
-        return $this->CustomHeader;
-    }
-
-    /**
-     * Create a message body from an HTML string.
-     * Automatically inlines images and creates a plain-text version by converting the HTML,
-     * overwriting any existing values in Body and AltBody.
-     * Do not source $message content from user input!
-     * $basedir is prepended when handling relative URLs, e.g. <img src="/images/a.png"> and must not be empty
-     * will look for an image file in $basedir/images/a.png and convert it to inline.
-     * If you don't provide a $basedir, relative paths will be left untouched (and thus probably break in email)
-     * Converts data-uri images into embedded attachments.
-     * If you don't want to apply these transformations to your HTML, just set Body and AltBody directly.
-     *
-     * @param string        $message  HTML message string
-     * @param string        $basedir  Absolute path to a base directory to prepend to relative paths to images
-     * @param bool|callable $advanced Whether to use the internal HTML to text converter
-     *                                or your own custom converter
-     * @return string The transformed message body
-     *
-     * @throws Exception
-     *
-     * @see PHPMailer::html2text()
-     */
-    public function msgHTML($message, $basedir = '', $advanced = false)
-    {
-        preg_match_all('/(?<!-)(src|background)=["\'](.*)["\']/Ui', $message, $images);
-        if (array_key_exists(2, $images)) {
-            if (strlen($basedir) > 1 && '/' !== substr($basedir, -1)) {
-                //Ensure $basedir has a trailing /
-                $basedir .= '/';
-            }
-            foreach ($images[2] as $imgindex => $url) {
-                //Convert data URIs into embedded images
-                //e.g. "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
-                $match = [];
-                if (preg_match('#^data:(image/(?:jpe?g|gif|png));?(base64)?,(.+)#', $url, $match)) {
-                    if (count($match) === 4 && static::ENCODING_BASE64 === $match[2]) {
-                        $data = base64_decode($match[3]);
-                    } elseif ('' === $match[2]) {
-                        $data = rawurldecode($match[3]);
-                    } else {
-                        //Not recognised so leave it alone
-                        continue;
-                    }
-                    //Hash the decoded data, not the URL, so that the same data-URI image used in multiple places
-                    //will only be embedded once, even if it used a different encoding
-                    $cid = substr(hash('sha256', $data), 0, 32) . '@phpmailer.0'; //RFC2392 S 2
-
-                    if (!$this->cidExists($cid)) {
-                        $this->addStringEmbeddedImage(
-                            $data,
-                            $cid,
-                            'embed' . $imgindex,
-                            static::ENCODING_BASE64,
-                            $match[1]
-                        );
-                    }
-                    $message = str_replace(
-                        $images[0][$imgindex],
-                        $images[1][$imgindex] . '="cid:' . $cid . '"',
-                        $message
-                    );
-                    continue;
-                }
-                if (
-                    //Only process relative URLs if a basedir is provided (i.e. no absolute local paths)
-                    !empty($basedir)
-                    //Ignore URLs containing parent dir traversal (..)
-                    && (strpos($url, '..') === false)
-                    //Do not change urls that are already inline images
-                    && 0 !== strpos($url, 'cid:')
-                    //Do not change absolute URLs, including anonymous protocol
-                    && !preg_match('#^[a-z][a-z0-9+.-]*:?//#i', $url)
-                ) {
-                    $filename = static::mb_pathinfo($url, PATHINFO_BASENAME);
-                    $directory = dirname($url);
-                    if ('.' === $directory) {
-                        $directory = '';
-                    }
-                    //RFC2392 S 2
-                    $cid = substr(hash('sha256', $url), 0, 32) . '@phpmailer.0';
-                    if (strlen($basedir) > 1 && '/' !== substr($basedir, -1)) {
-                        $basedir .= '/';
-                    }
-                    if (strlen($directory) > 1 && '/' !== substr($directory, -1)) {
-                        $directory .= '/';
-                    }
-                    if (
-                        $this->addEmbeddedImage(
-                            $basedir . $directory . $filename,
-                            $cid,
-                            $filename,
-                            static::ENCODING_BASE64,
-                            static::_mime_types((string) static::mb_pathinfo($filename, PATHINFO_EXTENSION))
-                        )
-                    ) {
-                        $message = preg_replace(
-                            '/' . $images[1][$imgindex] . '=["\']' . preg_quote($url, '/') . '["\']/Ui',
-                            $images[1][$imgindex] . '="cid:' . $cid . '"',
-                            $message
-                        );
-                    }
-                }
-            }
-        }
-        $this->isHTML();
-        //Convert all message body line breaks to LE, makes quoted-printable encoding work much better
-        $this->Body = static::normalizeBreaks($message);
-        $this->AltBody = static::normalizeBreaks($this->html2text($message, $advanced));
-        if (!$this->alternativeExists()) {
-            $this->AltBody = 'This is an HTML-only message. To view it, activate HTML in your email application.'
-                . static::$LE;
-        }
-
-        return $this->Body;
-    }
-
-    /**
-     * Convert an HTML string into plain text.
-     * This is used by msgHTML().
-     * Note - older versions of this function used a bundled advanced converter
-     * which was removed for license reasons in #232.
-     * Example usage:
-     *
-     * ```php
-     * //Use default conversion
-     * $plain = $mail->html2text($html);
-     * //Use your own custom converter
-     * $plain = $mail->html2text($html, function($html) {
-     *     $converter = new MyHtml2text($html);
-     *     return $converter->get_text();
-     * });
-     * ```
-     *
-     * @param string        $html     The HTML text to convert
-     * @param bool|callable $advanced Any boolean value to use the internal converter,
-     *                                or provide your own callable for custom conversion.
-     *                                *Never* pass user-supplied data into this parameter
-     *
-     * @return string
-     */
-    public function html2text($html, $advanced = false)
-    {
-        if (is_callable($advanced)) {
-            return call_user_func($advanced, $html);
-        }
-
-        return html_entity_decode(
-            trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/si', '', $html))),
-            ENT_QUOTES,
-            $this->CharSet
-        );
-    }
-
-    /**
-     * Get the MIME type for a file extension.
-     *
-     * @param string $ext File extension
-     *
-     * @return string MIME type of file
-     */
-    public static function _mime_types($ext = '')
-    {
-        $mimes = [
-            'xl' => 'application/excel',
-            'js' => 'application/javascript',
-            'hqx' => 'application/mac-binhex40',
-            'cpt' => 'application/mac-compactpro',
-            'bin' => 'application/macbinary',
-            'doc' => 'application/msword',
-            'word' => 'application/msword',
-            'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
-            'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
-            'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
-            'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
-            'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
-            'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
-            'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
-            'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
-            'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
-            'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
-            'class' => 'application/octet-stream',
-            'dll' => 'application/octet-stream',
-            'dms' => 'application/octet-stream',
-            'exe' => 'application/octet-stream',
-            'lha' => 'application/octet-stream',
-            'lzh' => 'application/octet-stream',
-            'psd' => 'application/octet-stream',
-            'sea' => 'application/octet-stream',
-            'so' => 'application/octet-stream',
-            'oda' => 'application/oda',
-            'pdf' => 'application/pdf',
-            'ai' => 'application/postscript',
-            'eps' => 'application/postscript',
-            'ps' => 'application/postscript',
-            'smi' => 'application/smil',
-            'smil' => 'application/smil',
-            'mif' => 'application/vnd.mif',
-            'xls' => 'application/vnd.ms-excel',
-            'ppt' => 'application/vnd.ms-powerpoint',
-            'wbxml' => 'application/vnd.wap.wbxml',
-            'wmlc' => 'application/vnd.wap.wmlc',
-            'dcr' => 'application/x-director',
-            'dir' => 'application/x-director',
-            'dxr' => 'application/x-director',
-            'dvi' => 'application/x-dvi',
-            'gtar' => 'application/x-gtar',
-            'php3' => 'application/x-httpd-php',
-            'php4' => 'application/x-httpd-php',
-            'php' => 'application/x-httpd-php',
-            'phtml' => 'application/x-httpd-php',
-            'phps' => 'application/x-httpd-php-source',
-            'swf' => 'application/x-shockwave-flash',
-            'sit' => 'application/x-stuffit',
-            'tar' => 'application/x-tar',
-            'tgz' => 'application/x-tar',
-            'xht' => 'application/xhtml+xml',
-            'xhtml' => 'application/xhtml+xml',
-            'zip' => 'application/zip',
-            'mid' => 'audio/midi',
-            'midi' => 'audio/midi',
-            'mp2' => 'audio/mpeg',
-            'mp3' => 'audio/mpeg',
-            'm4a' => 'audio/mp4',
-            'mpga' => 'audio/mpeg',
-            'aif' => 'audio/x-aiff',
-            'aifc' => 'audio/x-aiff',
-            'aiff' => 'audio/x-aiff',
-            'ram' => 'audio/x-pn-realaudio',
-            'rm' => 'audio/x-pn-realaudio',
-            'rpm' => 'audio/x-pn-realaudio-plugin',
-            'ra' => 'audio/x-realaudio',
-            'wav' => 'audio/x-wav',
-            'mka' => 'audio/x-matroska',
-            'bmp' => 'image/bmp',
-            'gif' => 'image/gif',
-            'jpeg' => 'image/jpeg',
-            'jpe' => 'image/jpeg',
-            'jpg' => 'image/jpeg',
-            'png' => 'image/png',
-            'tiff' => 'image/tiff',
-            'tif' => 'image/tiff',
-            'webp' => 'image/webp',
-            'avif' => 'image/avif',
-            'heif' => 'image/heif',
-            'heifs' => 'image/heif-sequence',
-            'heic' => 'image/heic',
-            'heics' => 'image/heic-sequence',
-            'eml' => 'message/rfc822',
-            'css' => 'text/css',
-            'html' => 'text/html',
-            'htm' => 'text/html',
-            'shtml' => 'text/html',
-            'log' => 'text/plain',
-            'text' => 'text/plain',
-            'txt' => 'text/plain',
-            'rtx' => 'text/richtext',
-            'rtf' => 'text/rtf',
-            'vcf' => 'text/vcard',
-            'vcard' => 'text/vcard',
-            'ics' => 'text/calendar',
-            'xml' => 'text/xml',
-            'xsl' => 'text/xml',
-            'csv' => 'text/csv',
-            'wmv' => 'video/x-ms-wmv',
-            'mpeg' => 'video/mpeg',
-            'mpe' => 'video/mpeg',
-            'mpg' => 'video/mpeg',
-            'mp4' => 'video/mp4',
-            'm4v' => 'video/mp4',
-            'mov' => 'video/quicktime',
-            'qt' => 'video/quicktime',
-            'rv' => 'video/vnd.rn-realvideo',
-            'avi' => 'video/x-msvideo',
-            'movie' => 'video/x-sgi-movie',
-            'webm' => 'video/webm',
-            'mkv' => 'video/x-matroska',
-        ];
-        $ext = strtolower($ext);
-        if (array_key_exists($ext, $mimes)) {
-            return $mimes[$ext];
-        }
-
-        return 'application/octet-stream';
-    }
-
-    /**
-     * Map a file name to a MIME type.
-     * Defaults to 'application/octet-stream', i.e.. arbitrary binary data.
-     *
-     * @param string $filename A file name or full path, does not need to exist as a file
-     *
-     * @return string
-     */
-    public static function filenameToType($filename)
-    {
-        //In case the path is a URL, strip any query string before getting extension
-        $qpos = strpos($filename, '?');
-        if (false !== $qpos) {
-            $filename = substr($filename, 0, $qpos);
-        }
-        $ext = static::mb_pathinfo($filename, PATHINFO_EXTENSION);
-
-        return static::_mime_types($ext);
-    }
-
-    /**
-     * Multi-byte-safe pathinfo replacement.
-     * Drop-in replacement for pathinfo(), but multibyte- and cross-platform-safe.
-     *
-     * @see https://www.php.net/manual/en/function.pathinfo.php#107461
-     *
-     * @param string     $path    A filename or path, does not need to exist as a file
-     * @param int|string $options Either a PATHINFO_* constant,
-     *                            or a string name to return only the specified piece
-     *
-     * @return string|array
-     */
-    public static function mb_pathinfo($path, $options = null)
-    {
-        $ret = ['dirname' => '', 'basename' => '', 'extension' => '', 'filename' => ''];
-        $pathinfo = [];
-        if (preg_match('#^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^.\\\\/]+?)|))[\\\\/.]*$#m', $path, $pathinfo)) {
-            if (array_key_exists(1, $pathinfo)) {
-                $ret['dirname'] = $pathinfo[1];
-            }
-            if (array_key_exists(2, $pathinfo)) {
-                $ret['basename'] = $pathinfo[2];
-            }
-            if (array_key_exists(5, $pathinfo)) {
-                $ret['extension'] = $pathinfo[5];
-            }
-            if (array_key_exists(3, $pathinfo)) {
-                $ret['filename'] = $pathinfo[3];
-            }
-        }
-        switch ($options) {
-            case PATHINFO_DIRNAME:
-            case 'dirname':
-                return $ret['dirname'];
-            case PATHINFO_BASENAME:
-            case 'basename':
-                return $ret['basename'];
-            case PATHINFO_EXTENSION:
-            case 'extension':
-                return $ret['extension'];
-            case PATHINFO_FILENAME:
-            case 'filename':
-                return $ret['filename'];
-            default:
-                return $ret;
-        }
-    }
-
-    /**
-     * Set or reset instance properties.
-     * You should avoid this function - it's more verbose, less efficient, more error-prone and
-     * harder to debug than setting properties directly.
-     * Usage Example:
-     * `$mail->set('SMTPSecure', static::ENCRYPTION_STARTTLS);`
-     *   is the same as:
-     * `$mail->SMTPSecure = static::ENCRYPTION_STARTTLS;`.
-     *
-     * @param string $name  The property name to set
-     * @param mixed  $value The value to set the property to
-     *
-     * @return bool
-     */
-    public function set($name, $value = '')
-    {
-        if (property_exists($this, $name)) {
-            $this->{$name} = $value;
-
-            return true;
-        }
-        $this->setError($this->lang('variable_set') . $name);
-
-        return false;
-    }
-
-    /**
-     * Strip newlines to prevent header injection.
-     *
-     * @param string $str
-     *
-     * @return string
-     */
-    public function secureHeader($str)
-    {
-        return trim(str_replace(["\r", "\n"], '', $str));
-    }
-
-    /**
-     * Normalize line breaks in a string.
-     * Converts UNIX LF, Mac CR and Windows CRLF line breaks into a single line break format.
-     * Defaults to CRLF (for message bodies) and preserves consecutive breaks.
-     *
-     * @param string $text
-     * @param string $breaktype What kind of line break to use; defaults to static::$LE
-     *
-     * @return string
-     */
-    public static function normalizeBreaks($text, $breaktype = null)
-    {
-        if (null === $breaktype) {
-            $breaktype = static::$LE;
-        }
-        //Normalise to \n
-        $text = str_replace([self::CRLF, "\r"], "\n", $text);
-        //Now convert LE as needed
-        if ("\n" !== $breaktype) {
-            $text = str_replace("\n", $breaktype, $text);
-        }
-
-        return $text;
-    }
-
-    /**
-     * Remove trailing whitespace from a string.
-     *
-     * @param string $text
-     *
-     * @return string The text to remove whitespace from
-     */
-    public static function stripTrailingWSP($text)
-    {
-        return rtrim($text, " \r\n\t");
-    }
-
-    /**
-     * Strip trailing line breaks from a string.
-     *
-     * @param string $text
-     *
-     * @return string The text to remove breaks from
-     */
-    public static function stripTrailingBreaks($text)
-    {
-        return rtrim($text, "\r\n");
-    }
-
-    /**
-     * Return the current line break format string.
-     *
-     * @return string
-     */
-    public static function getLE()
-    {
-        return static::$LE;
-    }
-
-    /**
-     * Set the line break format string, e.g. "\r\n".
-     *
-     * @param string $le
-     */
-    protected static function setLE($le)
-    {
-        static::$LE = $le;
-    }
-
-    /**
-     * Set the public and private key files and password for S/MIME signing.
-     *
-     * @param string $cert_filename
-     * @param string $key_filename
-     * @param string $key_pass            Password for private key
-     * @param string $extracerts_filename Optional path to chain certificate
-     */
-    public function sign($cert_filename, $key_filename, $key_pass, $extracerts_filename = '')
-    {
-        $this->sign_cert_file = $cert_filename;
-        $this->sign_key_file = $key_filename;
-        $this->sign_key_pass = $key_pass;
-        $this->sign_extracerts_file = $extracerts_filename;
-    }
-
-    /**
-     * Quoted-Printable-encode a DKIM header.
-     *
-     * @param string $txt
-     *
-     * @return string
-     */
-    public function DKIM_QP($txt)
-    {
-        $line = '';
-        $len = strlen($txt);
-        for ($i = 0; $i < $len; ++$i) {
-            $ord = ord($txt[$i]);
-            if (((0x21 <= $ord) && ($ord <= 0x3A)) || $ord === 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E))) {
-                $line .= $txt[$i];
-            } else {
-                $line .= '=' . sprintf('%02X', $ord);
-            }
-        }
-
-        return $line;
-    }
-
-    /**
-     * Generate a DKIM signature.
-     *
-     * @param string $signHeader
-     *
-     * @throws Exception
-     *
-     * @return string The DKIM signature value
-     */
-    public function DKIM_Sign($signHeader)
-    {
-        if (!defined('PKCS7_TEXT')) {
-            if ($this->exceptions) {
-                throw new Exception($this->lang('extension_missing') . 'openssl');
-            }
-
-            return '';
-        }
-        $privKeyStr = !empty($this->DKIM_private_string) ?
-            $this->DKIM_private_string :
-            file_get_contents($this->DKIM_private);
-        if ('' !== $this->DKIM_passphrase) {
-            $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase);
-        } else {
-            $privKey = openssl_pkey_get_private($privKeyStr);
-        }
-        if (openssl_sign($signHeader, $signature, $privKey, 'sha256WithRSAEncryption')) {
-            if (\PHP_MAJOR_VERSION < 8) {
-                openssl_pkey_free($privKey);
-            }
-
-            return base64_encode($signature);
-        }
-        if (\PHP_MAJOR_VERSION < 8) {
-            openssl_pkey_free($privKey);
-        }
-
-        return '';
-    }
-
-    /**
-     * Generate a DKIM canonicalization header.
-     * Uses the 'relaxed' algorithm from RFC6376 section 3.4.2.
-     * Canonicalized headers should *always* use CRLF, regardless of mailer setting.
-     *
-     * @see https://www.rfc-editor.org/rfc/rfc6376#section-3.4.2
-     *
-     * @param string $signHeader Header
-     *
-     * @return string
-     */
-    public function DKIM_HeaderC($signHeader)
-    {
-        //Normalize breaks to CRLF (regardless of the mailer)
-        $signHeader = static::normalizeBreaks($signHeader, self::CRLF);
-        //Unfold header lines
-        //Note PCRE \s is too broad a definition of whitespace; RFC5322 defines it as `[ \t]`
-        //@see https://www.rfc-editor.org/rfc/rfc5322#section-2.2
-        //That means this may break if you do something daft like put vertical tabs in your headers.
-        $signHeader = preg_replace('/\r\n[ \t]+/', ' ', $signHeader);
-        //Break headers out into an array
-        $lines = explode(self::CRLF, $signHeader);
-        foreach ($lines as $key => $line) {
-            //If the header is missing a :, skip it as it's invalid
-            //This is likely to happen because the explode() above will also split
-            //on the trailing LE, leaving an empty line
-            if (strpos($line, ':') === false) {
-                continue;
-            }
-            list($heading, $value) = explode(':', $line, 2);
-            //Lower-case header name
-            $heading = strtolower($heading);
-            //Collapse white space within the value, also convert WSP to space
-            $value = preg_replace('/[ \t]+/', ' ', $value);
-            //RFC6376 is slightly unclear here - it says to delete space at the *end* of each value
-            //But then says to delete space before and after the colon.
-            //Net result is the same as trimming both ends of the value.
-            //By elimination, the same applies to the field name
-            $lines[$key] = trim($heading, " \t") . ':' . trim($value, " \t");
-        }
-
-        return implode(self::CRLF, $lines);
-    }
-
-    /**
-     * Generate a DKIM canonicalization body.
-     * Uses the 'simple' algorithm from RFC6376 section 3.4.3.
-     * Canonicalized bodies should *always* use CRLF, regardless of mailer setting.
-     *
-     * @see https://www.rfc-editor.org/rfc/rfc6376#section-3.4.3
-     *
-     * @param string $body Message Body
-     *
-     * @return string
-     */
-    public function DKIM_BodyC($body)
-    {
-        if (empty($body)) {
-            return self::CRLF;
-        }
-        //Normalize line endings to CRLF
-        $body = static::normalizeBreaks($body, self::CRLF);
-
-        //Reduce multiple trailing line breaks to a single one
-        return static::stripTrailingBreaks($body) . self::CRLF;
-    }
-
-    /**
-     * Create the DKIM header and body in a new message header.
-     *
-     * @param string $headers_line Header lines
-     * @param string $subject      Subject
-     * @param string $body         Body
-     *
-     * @throws Exception
-     *
-     * @return string
-     */
-    public function DKIM_Add($headers_line, $subject, $body)
-    {
-        $DKIMsignatureType = 'rsa-sha256'; //Signature & hash algorithms
-        $DKIMcanonicalization = 'relaxed/simple'; //Canonicalization methods of header & body
-        $DKIMquery = 'dns/txt'; //Query method
-        $DKIMtime = time();
-        //Always sign these headers without being asked
-        //Recommended list from https://www.rfc-editor.org/rfc/rfc6376#section-5.4.1
-        $autoSignHeaders = [
-            'from',
-            'to',
-            'cc',
-            'date',
-            'subject',
-            'reply-to',
-            'message-id',
-            'content-type',
-            'mime-version',
-            'x-mailer',
-        ];
-        if (stripos($headers_line, 'Subject') === false) {
-            $headers_line .= 'Subject: ' . $subject . static::$LE;
-        }
-        $headerLines = explode(static::$LE, $headers_line);
-        $currentHeaderLabel = '';
-        $currentHeaderValue = '';
-        $parsedHeaders = [];
-        $headerLineIndex = 0;
-        $headerLineCount = count($headerLines);
-        foreach ($headerLines as $headerLine) {
-            $matches = [];
-            if (preg_match('/^([^ \t]*?)(?::[ \t]*)(.*)$/', $headerLine, $matches)) {
-                if ($currentHeaderLabel !== '') {
-                    //We were previously in another header; This is the start of a new header, so save the previous one
-                    $parsedHeaders[] = ['label' => $currentHeaderLabel, 'value' => $currentHeaderValue];
-                }
-                $currentHeaderLabel = $matches[1];
-                $currentHeaderValue = $matches[2];
-            } elseif (preg_match('/^[ \t]+(.*)$/', $headerLine, $matches)) {
-                //This is a folded continuation of the current header, so unfold it
-                $currentHeaderValue .= ' ' . $matches[1];
-            }
-            ++$headerLineIndex;
-            if ($headerLineIndex >= $headerLineCount) {
-                //This was the last line, so finish off this header
-                $parsedHeaders[] = ['label' => $currentHeaderLabel, 'value' => $currentHeaderValue];
-            }
-        }
-        $copiedHeaders = [];
-        $headersToSignKeys = [];
-        $headersToSign = [];
-        foreach ($parsedHeaders as $header) {
-            //Is this header one that must be included in the DKIM signature?
-            if (in_array(strtolower($header['label']), $autoSignHeaders, true)) {
-                $headersToSignKeys[] = $header['label'];
-                $headersToSign[] = $header['label'] . ': ' . $header['value'];
-                if ($this->DKIM_copyHeaderFields) {
-                    $copiedHeaders[] = $header['label'] . ':' . //Note no space after this, as per RFC
-                        str_replace('|', '=7C', $this->DKIM_QP($header['value']));
-                }
-                continue;
-            }
-            //Is this an extra custom header we've been asked to sign?
-            if (in_array($header['label'], $this->DKIM_extraHeaders, true)) {
-                //Find its value in custom headers
-                foreach ($this->CustomHeader as $customHeader) {
-                    if ($customHeader[0] === $header['label']) {
-                        $headersToSignKeys[] = $header['label'];
-                        $headersToSign[] = $header['label'] . ': ' . $header['value'];
-                        if ($this->DKIM_copyHeaderFields) {
-                            $copiedHeaders[] = $header['label'] . ':' . //Note no space after this, as per RFC
-                                str_replace('|', '=7C', $this->DKIM_QP($header['value']));
-                        }
-                        //Skip straight to the next header
-                        continue 2;
-                    }
-                }
-            }
-        }
-        $copiedHeaderFields = '';
-        if ($this->DKIM_copyHeaderFields && count($copiedHeaders) > 0) {
-            //Assemble a DKIM 'z' tag
-            $copiedHeaderFields = ' z=';
-            $first = true;
-            foreach ($copiedHeaders as $copiedHeader) {
-                if (!$first) {
-                    $copiedHeaderFields .= static::$LE . ' |';
-                }
-                //Fold long values
-                if (strlen($copiedHeader) > self::STD_LINE_LENGTH - 3) {
-                    $copiedHeaderFields .= substr(
-                        chunk_split($copiedHeader, self::STD_LINE_LENGTH - 3, static::$LE . self::FWS),
-                        0,
-                        -strlen(static::$LE . self::FWS)
-                    );
-                } else {
-                    $copiedHeaderFields .= $copiedHeader;
-                }
-                $first = false;
-            }
-            $copiedHeaderFields .= ';' . static::$LE;
-        }
-        $headerKeys = ' h=' . implode(':', $headersToSignKeys) . ';' . static::$LE;
-        $headerValues = implode(static::$LE, $headersToSign);
-        $body = $this->DKIM_BodyC($body);
-        //Base64 of packed binary SHA-256 hash of body
-        $DKIMb64 = base64_encode(pack('H*', hash('sha256', $body)));
-        $ident = '';
-        if ('' !== $this->DKIM_identity) {
-            $ident = ' i=' . $this->DKIM_identity . ';' . static::$LE;
-        }
-        //The DKIM-Signature header is included in the signature *except for* the value of the `b` tag
-        //which is appended after calculating the signature
-        //https://www.rfc-editor.org/rfc/rfc6376#section-3.5
-        $dkimSignatureHeader = 'DKIM-Signature: v=1;' .
-            ' d=' . $this->DKIM_domain . ';' .
-            ' s=' . $this->DKIM_selector . ';' . static::$LE .
-            ' a=' . $DKIMsignatureType . ';' .
-            ' q=' . $DKIMquery . ';' .
-            ' t=' . $DKIMtime . ';' .
-            ' c=' . $DKIMcanonicalization . ';' . static::$LE .
-            $headerKeys .
-            $ident .
-            $copiedHeaderFields .
-            ' bh=' . $DKIMb64 . ';' . static::$LE .
-            ' b=';
-        //Canonicalize the set of headers
-        $canonicalizedHeaders = $this->DKIM_HeaderC(
-            $headerValues . static::$LE . $dkimSignatureHeader
-        );
-        $signature = $this->DKIM_Sign($canonicalizedHeaders);
-        $signature = trim(chunk_split($signature, self::STD_LINE_LENGTH - 3, static::$LE . self::FWS));
-
-        return static::normalizeBreaks($dkimSignatureHeader . $signature);
-    }
-
-    /**
-     * Detect if a string contains a line longer than the maximum line length
-     * allowed by RFC 2822 section 2.1.1.
-     *
-     * @param string $str
-     *
-     * @return bool
-     */
-    public static function hasLineLongerThanMax($str)
-    {
-        return (bool) preg_match('/^(.{' . (self::MAX_LINE_LENGTH + strlen(static::$LE)) . ',})/m', $str);
-    }
-
-    /**
-     * If a string contains any "special" characters, double-quote the name,
-     * and escape any double quotes with a backslash.
-     *
-     * @param string $str
-     *
-     * @return string
-     *
-     * @see RFC822 3.4.1
-     */
-    public static function quotedString($str)
-    {
-        if (preg_match('/[ ()<>@,;:"\/\[\]?=]/', $str)) {
-            //If the string contains any of these chars, it must be double-quoted
-            //and any double quotes must be escaped with a backslash
-            return '"' . str_replace('"', '\\"', $str) . '"';
-        }
-
-        //Return the string untouched, it doesn't need quoting
-        return $str;
-    }
-
-    /**
-     * Allows for public read access to 'to' property.
-     * Before the send() call, queued addresses (i.e. with IDN) are not yet included.
-     *
-     * @return array
-     */
-    public function getToAddresses()
-    {
-        return $this->to;
-    }
-
-    /**
-     * Allows for public read access to 'cc' property.
-     * Before the send() call, queued addresses (i.e. with IDN) are not yet included.
-     *
-     * @return array
-     */
-    public function getCcAddresses()
-    {
-        return $this->cc;
-    }
-
-    /**
-     * Allows for public read access to 'bcc' property.
-     * Before the send() call, queued addresses (i.e. with IDN) are not yet included.
-     *
-     * @return array
-     */
-    public function getBccAddresses()
-    {
-        return $this->bcc;
-    }
-
-    /**
-     * Allows for public read access to 'ReplyTo' property.
-     * Before the send() call, queued addresses (i.e. with IDN) are not yet included.
-     *
-     * @return array
-     */
-    public function getReplyToAddresses()
-    {
-        return $this->ReplyTo;
-    }
-
-    /**
-     * Allows for public read access to 'all_recipients' property.
-     * Before the send() call, queued addresses (i.e. with IDN) are not yet included.
-     *
-     * @return array
-     */
-    public function getAllRecipientAddresses()
-    {
-        return $this->all_recipients;
-    }
-
-    /**
-     * Perform a callback.
-     *
-     * @param bool   $isSent
-     * @param array  $to
-     * @param array  $cc
-     * @param array  $bcc
-     * @param string $subject
-     * @param string $body
-     * @param string $from
-     * @param array  $extra
-     */
-    protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body, $from, $extra)
-    {
-        if (!empty($this->action_function) && is_callable($this->action_function)) {
-            call_user_func($this->action_function, $isSent, $to, $cc, $bcc, $subject, $body, $from, $extra);
-        }
-    }
-
-    /**
-     * Get the OAuthTokenProvider instance.
-     *
-     * @return OAuthTokenProvider
-     */
-    public function getOAuth()
-    {
-        return $this->oauth;
-    }
-
-    /**
-     * Set an OAuthTokenProvider instance.
-     */
-    public function setOAuth(OAuthTokenProvider $oauth)
-    {
-        $this->oauth = $oauth;
-    }
+					$punycode = idn_to_ascii( $domain, $errorcode );
+				}
+				if ( false !== $punycode ) {
+					return substr( $address, 0, $pos ) . $punycode;
+				}
+			}
+		}
+
+		return $address;
+	}
+
+	/**
+	 * Create a message and send it.
+	 * Uses the sending method specified by $Mailer.
+	 *
+	 * @throws Exception
+	 *
+	 * @return bool false on error - See the ErrorInfo property for details of the error
+	 */
+	public function send() {
+		try {
+			if ( ! $this->preSend() ) {
+				return false;
+			}
+
+			return $this->postSend();
+		} catch ( Exception $exc ) {
+			$this->mailHeader = '';
+			$this->setError( $exc->getMessage() );
+			if ( $this->exceptions ) {
+				throw $exc;
+			}
+
+			return false;
+		}
+	}
+
+	/**
+	 * Prepare a message for sending.
+	 *
+	 * @throws Exception
+	 *
+	 * @return bool
+	 */
+	public function preSend() {
+		if (
+			'smtp' === $this->Mailer
+			|| ( 'mail' === $this->Mailer && ( \PHP_VERSION_ID >= 80000 || stripos( PHP_OS, 'WIN' ) === 0 ) )
+		) {
+			// SMTP mandates RFC-compliant line endings
+			// and it's also used with mail() on Windows
+			static::setLE( self::CRLF );
+		} else {
+			// Maintain backward compatibility with legacy Linux command line mailers
+			static::setLE( PHP_EOL );
+		}
+		// Check for buggy PHP versions that add a header with an incorrect line break
+		if (
+			'mail' === $this->Mailer
+			&& ( ( \PHP_VERSION_ID >= 70000 && \PHP_VERSION_ID < 70017 )
+				|| ( \PHP_VERSION_ID >= 70100 && \PHP_VERSION_ID < 70103 ) )
+			&& ini_get( 'mail.add_x_header' ) === '1'
+			&& stripos( PHP_OS, 'WIN' ) === 0
+		) {
+			trigger_error( $this->lang( 'buggy_php' ), E_USER_WARNING );
+		}
+
+		try {
+			$this->error_count = 0; // Reset errors
+			$this->mailHeader  = '';
+
+			// Dequeue recipient and Reply-To addresses with IDN
+			foreach ( array_merge( $this->RecipientsQueue, $this->ReplyToQueue ) as $params ) {
+				$params[1] = $this->punyencodeAddress( $params[1] );
+				call_user_func_array( array( $this, 'addAnAddress' ), $params );
+			}
+			if ( count( $this->to ) + count( $this->cc ) + count( $this->bcc ) < 1 ) {
+				throw new Exception( $this->lang( 'provide_address' ), self::STOP_CRITICAL );
+			}
+
+			// Validate From, Sender, and ConfirmReadingTo addresses
+			foreach ( array( 'From', 'Sender', 'ConfirmReadingTo' ) as $address_kind ) {
+				if ( $this->{$address_kind} === null ) {
+					$this->{$address_kind} = '';
+					continue;
+				}
+				$this->{$address_kind} = trim( $this->{$address_kind} );
+				if ( empty( $this->{$address_kind} ) ) {
+					continue;
+				}
+				$this->{$address_kind} = $this->punyencodeAddress( $this->{$address_kind} );
+				if ( ! static::validateAddress( $this->{$address_kind} ) ) {
+					$error_message = sprintf(
+						'%s (%s): %s',
+						$this->lang( 'invalid_address' ),
+						$address_kind,
+						$this->{$address_kind}
+					);
+					$this->setError( $error_message );
+					$this->edebug( $error_message );
+					if ( $this->exceptions ) {
+						throw new Exception( $error_message );
+					}
+
+					return false;
+				}
+			}
+
+			// Set whether the message is multipart/alternative
+			if ( $this->alternativeExists() ) {
+				$this->ContentType = static::CONTENT_TYPE_MULTIPART_ALTERNATIVE;
+			}
+
+			$this->setMessageType();
+			// Refuse to send an empty message unless we are specifically allowing it
+			if ( ! $this->AllowEmpty && empty( $this->Body ) ) {
+				throw new Exception( $this->lang( 'empty_message' ), self::STOP_CRITICAL );
+			}
+
+			// Trim subject consistently
+			$this->Subject = trim( $this->Subject );
+			// Create body before headers in case body makes changes to headers (e.g. altering transfer encoding)
+			$this->MIMEHeader = '';
+			$this->MIMEBody   = $this->createBody();
+			// createBody may have added some headers, so retain them
+			$tempheaders       = $this->MIMEHeader;
+			$this->MIMEHeader  = $this->createHeader();
+			$this->MIMEHeader .= $tempheaders;
+
+			// To capture the complete message when using mail(), create
+			// an extra header list which createHeader() doesn't fold in
+			if ( 'mail' === $this->Mailer ) {
+				if ( count( $this->to ) > 0 ) {
+					$this->mailHeader .= $this->addrAppend( 'To', $this->to );
+				} else {
+					$this->mailHeader .= $this->headerLine( 'To', 'undisclosed-recipients:;' );
+				}
+				$this->mailHeader .= $this->headerLine(
+					'Subject',
+					$this->encodeHeader( $this->secureHeader( $this->Subject ) )
+				);
+			}
+
+			// Sign with DKIM if enabled
+			if (
+				! empty( $this->DKIM_domain )
+				&& ! empty( $this->DKIM_selector )
+				&& ( ! empty( $this->DKIM_private_string )
+					|| ( ! empty( $this->DKIM_private )
+						&& static::isPermittedPath( $this->DKIM_private )
+						&& file_exists( $this->DKIM_private )
+					)
+				)
+			) {
+				$header_dkim      = $this->DKIM_Add(
+					$this->MIMEHeader . $this->mailHeader,
+					$this->encodeHeader( $this->secureHeader( $this->Subject ) ),
+					$this->MIMEBody
+				);
+				$this->MIMEHeader = static::stripTrailingWSP( $this->MIMEHeader ) . static::$LE .
+					static::normalizeBreaks( $header_dkim ) . static::$LE;
+			}
+
+			return true;
+		} catch ( Exception $exc ) {
+			$this->setError( $exc->getMessage() );
+			if ( $this->exceptions ) {
+				throw $exc;
+			}
+
+			return false;
+		}
+	}
+
+	/**
+	 * Actually send a message via the selected mechanism.
+	 *
+	 * @throws Exception
+	 *
+	 * @return bool
+	 */
+	public function postSend() {
+		try {
+			// Choose the mailer and send through it
+			switch ( $this->Mailer ) {
+				case 'sendmail':
+				case 'qmail':
+					return $this->sendmailSend( $this->MIMEHeader, $this->MIMEBody );
+				case 'smtp':
+					return $this->smtpSend( $this->MIMEHeader, $this->MIMEBody );
+				case 'mail':
+					return $this->mailSend( $this->MIMEHeader, $this->MIMEBody );
+				default:
+					$sendMethod = $this->Mailer . 'Send';
+					if ( method_exists( $this, $sendMethod ) ) {
+						return $this->{$sendMethod}( $this->MIMEHeader, $this->MIMEBody );
+					}
+
+					return $this->mailSend( $this->MIMEHeader, $this->MIMEBody );
+			}
+		} catch ( Exception $exc ) {
+			$this->setError( $exc->getMessage() );
+			$this->edebug( $exc->getMessage() );
+			if ( $this->Mailer === 'smtp' && $this->SMTPKeepAlive == true && $this->smtp->connected() ) {
+				$this->smtp->reset();
+			}
+			if ( $this->exceptions ) {
+				throw $exc;
+			}
+		}
+
+		return false;
+	}
+
+	/**
+	 * Send mail using the $Sendmail program.
+	 *
+	 * @see PHPMailer::$Sendmail
+	 *
+	 * @param string $header The message headers
+	 * @param string $body   The message body
+	 *
+	 * @throws Exception
+	 *
+	 * @return bool
+	 */
+	protected function sendmailSend( $header, $body ) {
+		if ( $this->Mailer === 'qmail' ) {
+			$this->edebug( 'Sending with qmail' );
+		} else {
+			$this->edebug( 'Sending with sendmail' );
+		}
+		$header = static::stripTrailingWSP( $header ) . static::$LE . static::$LE;
+		// This sets the SMTP envelope sender which gets turned into a return-path header by the receiver
+		// A space after `-f` is optional, but there is a long history of its presence
+		// causing problems, so we don't use one
+		// Exim docs: https://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html
+		// Sendmail docs: https://www.sendmail.org/~ca/email/man/sendmail.html
+		// Example problem: https://www.drupal.org/node/1057954
+
+		// PHP 5.6 workaround
+		$sendmail_from_value = ini_get( 'sendmail_from' );
+		if ( empty( $this->Sender ) && ! empty( $sendmail_from_value ) ) {
+			// PHP config has a sender address we can use
+			$this->Sender = ini_get( 'sendmail_from' );
+		}
+		// CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.
+		if ( ! empty( $this->Sender ) && static::validateAddress( $this->Sender ) && self::isShellSafe( $this->Sender ) ) {
+			if ( $this->Mailer === 'qmail' ) {
+				$sendmailFmt = '%s -f%s';
+			} else {
+				$sendmailFmt = '%s -oi -f%s -t';
+			}
+		} else {
+			// allow sendmail to choose a default envelope sender. It may
+			// seem preferable to force it to use the From header as with
+			// SMTP, but that introduces new problems (see
+			// <https://github.com/PHPMailer/PHPMailer/issues/2298>), and
+			// it has historically worked this way.
+			$sendmailFmt = '%s -oi -t';
+		}
+
+		$sendmail = sprintf( $sendmailFmt, escapeshellcmd( $this->Sendmail ), $this->Sender );
+		$this->edebug( 'Sendmail path: ' . $this->Sendmail );
+		$this->edebug( 'Sendmail command: ' . $sendmail );
+		$this->edebug( 'Envelope sender: ' . $this->Sender );
+		$this->edebug( "Headers: {$header}" );
+
+		if ( $this->SingleTo ) {
+			foreach ( $this->SingleToArray as $toAddr ) {
+				$mail = @popen( $sendmail, 'w' );
+				if ( ! $mail ) {
+					throw new Exception( $this->lang( 'execute' ) . $this->Sendmail, self::STOP_CRITICAL );
+				}
+				$this->edebug( "To: {$toAddr}" );
+				fwrite( $mail, 'To: ' . $toAddr . "\n" );
+				fwrite( $mail, $header );
+				fwrite( $mail, $body );
+				$result   = pclose( $mail );
+				$addrinfo = static::parseAddresses( $toAddr, true, $this->CharSet );
+				$this->doCallback(
+					( $result === 0 ),
+					array( array( $addrinfo['address'], $addrinfo['name'] ) ),
+					$this->cc,
+					$this->bcc,
+					$this->Subject,
+					$body,
+					$this->From,
+					array()
+				);
+				$this->edebug( 'Result: ' . ( $result === 0 ? 'true' : 'false' ) );
+				if ( 0 !== $result ) {
+					throw new Exception( $this->lang( 'execute' ) . $this->Sendmail, self::STOP_CRITICAL );
+				}
+			}
+		} else {
+			$mail = @popen( $sendmail, 'w' );
+			if ( ! $mail ) {
+				throw new Exception( $this->lang( 'execute' ) . $this->Sendmail, self::STOP_CRITICAL );
+			}
+			fwrite( $mail, $header );
+			fwrite( $mail, $body );
+			$result = pclose( $mail );
+			$this->doCallback(
+				( $result === 0 ),
+				$this->to,
+				$this->cc,
+				$this->bcc,
+				$this->Subject,
+				$body,
+				$this->From,
+				array()
+			);
+			$this->edebug( 'Result: ' . ( $result === 0 ? 'true' : 'false' ) );
+			if ( 0 !== $result ) {
+				throw new Exception( $this->lang( 'execute' ) . $this->Sendmail, self::STOP_CRITICAL );
+			}
+		}
+
+		return true;
+	}
+
+	/**
+	 * Fix CVE-2016-10033 and CVE-2016-10045 by disallowing potentially unsafe shell characters.
+	 * Note that escapeshellarg and escapeshellcmd are inadequate for our purposes, especially on Windows.
+	 *
+	 * @see https://github.com/PHPMailer/PHPMailer/issues/924 CVE-2016-10045 bug report
+	 *
+	 * @param string $string The string to be validated
+	 *
+	 * @return bool
+	 */
+	protected static function isShellSafe( $string ) {
+		// It's not possible to use shell commands safely (which includes the mail() function) without escapeshellarg,
+		// but some hosting providers disable it, creating a security problem that we don't want to have to deal with,
+		// so we don't.
+		if ( ! function_exists( 'escapeshellarg' ) || ! function_exists( 'escapeshellcmd' ) ) {
+			return false;
+		}
+
+		if (
+			escapeshellcmd( $string ) !== $string
+			|| ! in_array( escapeshellarg( $string ), array( "'$string'", "\"$string\"" ) )
+		) {
+			return false;
+		}
+
+		$length = strlen( $string );
+
+		for ( $i = 0; $i < $length; ++$i ) {
+			$c = $string[ $i ];
+
+			// All other characters have a special meaning in at least one common shell, including = and +.
+			// Full stop (.) has a special meaning in cmd.exe, but its impact should be negligible here.
+			// Note that this does permit non-Latin alphanumeric characters based on the current locale.
+			if ( ! ctype_alnum( $c ) && strpos( '@_-.', $c ) === false ) {
+				return false;
+			}
+		}
+
+		return true;
+	}
+
+	/**
+	 * Check whether a file path is of a permitted type.
+	 * Used to reject URLs and phar files from functions that access local file paths,
+	 * such as addAttachment.
+	 *
+	 * @param string $path A relative or absolute path to a file
+	 *
+	 * @return bool
+	 */
+	protected static function isPermittedPath( $path ) {
+		// Matches scheme definition from https://www.rfc-editor.org/rfc/rfc3986#section-3.1
+		return ! preg_match( '#^[a-z][a-z\d+.-]*://#i', $path );
+	}
+
+	/**
+	 * Check whether a file path is safe, accessible, and readable.
+	 *
+	 * @param string $path A relative or absolute path to a file
+	 *
+	 * @return bool
+	 */
+	protected static function fileIsAccessible( $path ) {
+		if ( ! static::isPermittedPath( $path ) ) {
+			return false;
+		}
+		$readable = is_file( $path );
+		// If not a UNC path (expected to start with \\), check read permission, see #2069
+		if ( strpos( $path, '\\\\' ) !== 0 ) {
+			$readable = $readable && is_readable( $path );
+		}
+		return $readable;
+	}
+
+	/**
+	 * Send mail using the PHP mail() function.
+	 *
+	 * @see https://www.php.net/manual/en/book.mail.php
+	 *
+	 * @param string $header The message headers
+	 * @param string $body   The message body
+	 *
+	 * @throws Exception
+	 *
+	 * @return bool
+	 */
+	protected function mailSend( $header, $body ) {
+		$header = static::stripTrailingWSP( $header ) . static::$LE . static::$LE;
+
+		$toArr = array();
+		foreach ( $this->to as $toaddr ) {
+			$toArr[] = $this->addrFormat( $toaddr );
+		}
+		$to = trim( implode( ', ', $toArr ) );
+
+		// If there are no To-addresses (e.g. when sending only to BCC-addresses)
+		// the following should be added to get a correct DKIM-signature.
+		// Compare with $this->preSend()
+		if ( $to === '' ) {
+			$to = 'undisclosed-recipients:;';
+		}
+
+		$params = null;
+		// This sets the SMTP envelope sender which gets turned into a return-path header by the receiver
+		// A space after `-f` is optional, but there is a long history of its presence
+		// causing problems, so we don't use one
+		// Exim docs: https://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html
+		// Sendmail docs: https://www.sendmail.org/~ca/email/man/sendmail.html
+		// Example problem: https://www.drupal.org/node/1057954
+		// CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.
+
+		// PHP 5.6 workaround
+		$sendmail_from_value = ini_get( 'sendmail_from' );
+		if ( empty( $this->Sender ) && ! empty( $sendmail_from_value ) ) {
+			// PHP config has a sender address we can use
+			$this->Sender = ini_get( 'sendmail_from' );
+		}
+		if ( ! empty( $this->Sender ) && static::validateAddress( $this->Sender ) ) {
+			if ( self::isShellSafe( $this->Sender ) ) {
+				$params = sprintf( '-f%s', $this->Sender );
+			}
+			$old_from = ini_get( 'sendmail_from' );
+			ini_set( 'sendmail_from', $this->Sender );
+		}
+		$result = false;
+		if ( $this->SingleTo && count( $toArr ) > 1 ) {
+			foreach ( $toArr as $toAddr ) {
+				$result   = $this->mailPassthru( $toAddr, $this->Subject, $body, $header, $params );
+				$addrinfo = static::parseAddresses( $toAddr, true, $this->CharSet );
+				$this->doCallback(
+					$result,
+					array( array( $addrinfo['address'], $addrinfo['name'] ) ),
+					$this->cc,
+					$this->bcc,
+					$this->Subject,
+					$body,
+					$this->From,
+					array()
+				);
+			}
+		} else {
+			$result = $this->mailPassthru( $to, $this->Subject, $body, $header, $params );
+			$this->doCallback( $result, $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From, array() );
+		}
+		if ( isset( $old_from ) ) {
+			ini_set( 'sendmail_from', $old_from );
+		}
+		if ( ! $result ) {
+			throw new Exception( $this->lang( 'instantiate' ), self::STOP_CRITICAL );
+		}
+
+		return true;
+	}
+
+	/**
+	 * Get an instance to use for SMTP operations.
+	 * Override this function to load your own SMTP implementation,
+	 * or set one with setSMTPInstance.
+	 *
+	 * @return SMTP
+	 */
+	public function getSMTPInstance() {
+		if ( ! is_object( $this->smtp ) ) {
+			$this->smtp = new SMTP();
+		}
+
+		return $this->smtp;
+	}
+
+	/**
+	 * Provide an instance to use for SMTP operations.
+	 *
+	 * @return SMTP
+	 */
+	public function setSMTPInstance( SMTP $smtp ) {
+		$this->smtp = $smtp;
+
+		return $this->smtp;
+	}
+
+	/**
+	 * Provide SMTP XCLIENT attributes
+	 *
+	 * @param string  $name  Attribute name
+	 * @param ?string $value Attribute value
+	 *
+	 * @return bool
+	 */
+	public function setSMTPXclientAttribute( $name, $value ) {
+		if ( ! in_array( $name, SMTP::$xclient_allowed_attributes ) ) {
+			return false;
+		}
+		if ( isset( $this->SMTPXClient[ $name ] ) && $value === null ) {
+			unset( $this->SMTPXClient[ $name ] );
+		} elseif ( $value !== null ) {
+			$this->SMTPXClient[ $name ] = $value;
+		}
+
+		return true;
+	}
+
+	/**
+	 * Get SMTP XCLIENT attributes
+	 *
+	 * @return array
+	 */
+	public function getSMTPXclientAttributes() {
+		return $this->SMTPXClient;
+	}
+
+	/**
+	 * Send mail via SMTP.
+	 * Returns false if there is a bad MAIL FROM, RCPT, or DATA input.
+	 *
+	 * @see PHPMailer::setSMTPInstance() to use a different class.
+	 *
+	 * @uses \PHPMailer\PHPMailer\SMTP
+	 *
+	 * @param string $header The message headers
+	 * @param string $body   The message body
+	 *
+	 * @throws Exception
+	 *
+	 * @return bool
+	 */
+	protected function smtpSend( $header, $body ) {
+		$header   = static::stripTrailingWSP( $header ) . static::$LE . static::$LE;
+		$bad_rcpt = array();
+		if ( ! $this->smtpConnect( $this->SMTPOptions ) ) {
+			throw new Exception( $this->lang( 'smtp_connect_failed' ), self::STOP_CRITICAL );
+		}
+		// Sender already validated in preSend()
+		if ( '' === $this->Sender ) {
+			$smtp_from = $this->From;
+		} else {
+			$smtp_from = $this->Sender;
+		}
+		if ( count( $this->SMTPXClient ) ) {
+			$this->smtp->xclient( $this->SMTPXClient );
+		}
+		if ( ! $this->smtp->mail( $smtp_from ) ) {
+			$this->setError( $this->lang( 'from_failed' ) . $smtp_from . ' : ' . implode( ',', $this->smtp->getError() ) );
+			throw new Exception( $this->ErrorInfo, self::STOP_CRITICAL );
+		}
+
+		$callbacks = array();
+		// Attempt to send to all recipients
+		foreach ( array( $this->to, $this->cc, $this->bcc ) as $togroup ) {
+			foreach ( $togroup as $to ) {
+				if ( ! $this->smtp->recipient( $to[0], $this->dsn ) ) {
+					$error      = $this->smtp->getError();
+					$bad_rcpt[] = array(
+						'to'    => $to[0],
+						'error' => $error['detail'],
+					);
+					$isSent     = false;
+				} else {
+					$isSent = true;
+				}
+
+				$callbacks[] = array(
+					'issent' => $isSent,
+					'to'     => $to[0],
+					'name'   => $to[1],
+				);
+			}
+		}
+
+		// Only send the DATA command if we have viable recipients
+		if ( ( count( $this->all_recipients ) > count( $bad_rcpt ) ) && ! $this->smtp->data( $header . $body ) ) {
+			throw new Exception( $this->lang( 'data_not_accepted' ), self::STOP_CRITICAL );
+		}
+
+		$smtp_transaction_id = $this->smtp->getLastTransactionID();
+
+		if ( $this->SMTPKeepAlive ) {
+			$this->smtp->reset();
+		} else {
+			$this->smtp->quit();
+			$this->smtp->close();
+		}
+
+		foreach ( $callbacks as $cb ) {
+			$this->doCallback(
+				$cb['issent'],
+				array( array( $cb['to'], $cb['name'] ) ),
+				array(),
+				array(),
+				$this->Subject,
+				$body,
+				$this->From,
+				array( 'smtp_transaction_id' => $smtp_transaction_id )
+			);
+		}
+
+		// Create error message for any bad addresses
+		if ( count( $bad_rcpt ) > 0 ) {
+			$errstr = '';
+			foreach ( $bad_rcpt as $bad ) {
+				$errstr .= $bad['to'] . ': ' . $bad['error'];
+			}
+			throw new Exception( $this->lang( 'recipients_failed' ) . $errstr, self::STOP_CONTINUE );
+		}
+
+		return true;
+	}
+
+	/**
+	 * Initiate a connection to an SMTP server.
+	 * Returns false if the operation failed.
+	 *
+	 * @param array $options An array of options compatible with stream_context_create()
+	 *
+	 * @throws Exception
+	 *
+	 * @uses \PHPMailer\PHPMailer\SMTP
+	 *
+	 * @return bool
+	 */
+	public function smtpConnect( $options = null ) {
+		if ( null === $this->smtp ) {
+			$this->smtp = $this->getSMTPInstance();
+		}
+
+		// If no options are provided, use whatever is set in the instance
+		if ( null === $options ) {
+			$options = $this->SMTPOptions;
+		}
+
+		// Already connected?
+		if ( $this->smtp->connected() ) {
+			return true;
+		}
+
+		$this->smtp->setTimeout( $this->Timeout );
+		$this->smtp->setDebugLevel( $this->SMTPDebug );
+		$this->smtp->setDebugOutput( $this->Debugoutput );
+		$this->smtp->setVerp( $this->do_verp );
+		if ( $this->Host === null ) {
+			$this->Host = 'localhost';
+		}
+		$hosts         = explode( ';', $this->Host );
+		$lastexception = null;
+
+		foreach ( $hosts as $hostentry ) {
+			$hostinfo = array();
+			if (
+				! preg_match(
+					'/^(?:(ssl|tls):\/\/)?(.+?)(?::(\d+))?$/',
+					trim( $hostentry ),
+					$hostinfo
+				)
+			) {
+				$this->edebug( $this->lang( 'invalid_hostentry' ) . ' ' . trim( $hostentry ) );
+				// Not a valid host entry
+				continue;
+			}
+			// $hostinfo[1]: optional ssl or tls prefix
+			// $hostinfo[2]: the hostname
+			// $hostinfo[3]: optional port number
+			// The host string prefix can temporarily override the current setting for SMTPSecure
+			// If it's not specified, the default value is used
+
+			// Check the host name is a valid name or IP address before trying to use it
+			if ( ! static::isValidHost( $hostinfo[2] ) ) {
+				$this->edebug( $this->lang( 'invalid_host' ) . ' ' . $hostinfo[2] );
+				continue;
+			}
+			$prefix = '';
+			$secure = $this->SMTPSecure;
+			$tls    = ( static::ENCRYPTION_STARTTLS === $this->SMTPSecure );
+			if ( 'ssl' === $hostinfo[1] || ( '' === $hostinfo[1] && static::ENCRYPTION_SMTPS === $this->SMTPSecure ) ) {
+				$prefix = 'ssl://';
+				$tls    = false; // Can't have SSL and TLS at the same time
+				$secure = static::ENCRYPTION_SMTPS;
+			} elseif ( 'tls' === $hostinfo[1] ) {
+				$tls = true;
+				// TLS doesn't use a prefix
+				$secure = static::ENCRYPTION_STARTTLS;
+			}
+			// Do we need the OpenSSL extension?
+			$sslext = defined( 'OPENSSL_ALGO_SHA256' );
+			if ( static::ENCRYPTION_STARTTLS === $secure || static::ENCRYPTION_SMTPS === $secure ) {
+				// Check for an OpenSSL constant rather than using extension_loaded, which is sometimes disabled
+				if ( ! $sslext ) {
+					throw new Exception( $this->lang( 'extension_missing' ) . 'openssl', self::STOP_CRITICAL );
+				}
+			}
+			$host = $hostinfo[2];
+			$port = $this->Port;
+			if (
+				array_key_exists( 3, $hostinfo ) &&
+				is_numeric( $hostinfo[3] ) &&
+				$hostinfo[3] > 0 &&
+				$hostinfo[3] < 65536
+			) {
+				$port = (int) $hostinfo[3];
+			}
+			if ( $this->smtp->connect( $prefix . $host, $port, $this->Timeout, $options ) ) {
+				try {
+					if ( $this->Helo ) {
+						$hello = $this->Helo;
+					} else {
+						$hello = $this->serverHostname();
+					}
+					$this->smtp->hello( $hello );
+					// Automatically enable TLS encryption if:
+					// * it's not disabled
+					// * we are not connecting to localhost
+					// * we have openssl extension
+					// * we are not already using SSL
+					// * the server offers STARTTLS
+					if (
+						$this->SMTPAutoTLS &&
+						$this->Host !== 'localhost' &&
+						$sslext &&
+						$secure !== 'ssl' &&
+						$this->smtp->getServerExt( 'STARTTLS' )
+					) {
+						$tls = true;
+					}
+					if ( $tls ) {
+						if ( ! $this->smtp->startTLS() ) {
+							$message = $this->getSmtpErrorMessage( 'connect_host' );
+							throw new Exception( $message );
+						}
+						// We must resend EHLO after TLS negotiation
+						$this->smtp->hello( $hello );
+					}
+					if (
+						$this->SMTPAuth && ! $this->smtp->authenticate(
+							$this->Username,
+							$this->Password,
+							$this->AuthType,
+							$this->oauth
+						)
+					) {
+						throw new Exception( $this->lang( 'authenticate' ) );
+					}
+
+					return true;
+				} catch ( Exception $exc ) {
+					$lastexception = $exc;
+					$this->edebug( $exc->getMessage() );
+					// We must have connected, but then failed TLS or Auth, so close connection nicely
+					$this->smtp->quit();
+				}
+			}
+		}
+		// If we get here, all connection attempts have failed, so close connection hard
+		$this->smtp->close();
+		// As we've caught all exceptions, just report whatever the last one was
+		if ( $this->exceptions && null !== $lastexception ) {
+			throw $lastexception;
+		}
+		if ( $this->exceptions ) {
+			// no exception was thrown, likely $this->smtp->connect() failed
+			$message = $this->getSmtpErrorMessage( 'connect_host' );
+			throw new Exception( $message );
+		}
+
+		return false;
+	}
+
+	/**
+	 * Close the active SMTP session if one exists.
+	 */
+	public function smtpClose() {
+		if ( ( null !== $this->smtp ) && $this->smtp->connected() ) {
+			$this->smtp->quit();
+			$this->smtp->close();
+		}
+	}
+
+	/**
+	 * Set the language for error messages.
+	 * The default language is English.
+	 *
+	 * @param string $langcode  ISO 639-1 2-character language code (e.g. French is "fr")
+	 *                          Optionally, the language code can be enhanced with a 4-character
+	 *                          script annotation and/or a 2-character country annotation.
+	 * @param string $lang_path Path to the language file directory, with trailing separator (slash)
+	 *                          Do not set this from user input!
+	 *
+	 * @return bool Returns true if the requested language was loaded, false otherwise.
+	 */
+	public function setLanguage( $langcode = 'en', $lang_path = '' ) {
+		// Backwards compatibility for renamed language codes
+		$renamed_langcodes = array(
+			'br' => 'pt_br',
+			'cz' => 'cs',
+			'dk' => 'da',
+			'no' => 'nb',
+			'se' => 'sv',
+			'rs' => 'sr',
+			'tg' => 'tl',
+			'am' => 'hy',
+		);
+
+		if ( array_key_exists( $langcode, $renamed_langcodes ) ) {
+			$langcode = $renamed_langcodes[ $langcode ];
+		}
+
+		// Define full set of translatable strings in English
+		$PHPMAILER_LANG = array(
+			'authenticate'         => 'SMTP Error: Could not authenticate.',
+			'buggy_php'            => 'Your version of PHP is affected by a bug that may result in corrupted messages.' .
+				' To fix it, switch to sending using SMTP, disable the mail.add_x_header option in' .
+				' your php.ini, switch to MacOS or Linux, or upgrade your PHP to version 7.0.17+ or 7.1.3+.',
+			'connect_host'         => 'SMTP Error: Could not connect to SMTP host.',
+			'data_not_accepted'    => 'SMTP Error: data not accepted.',
+			'empty_message'        => 'Message body empty',
+			'encoding'             => 'Unknown encoding: ',
+			'execute'              => 'Could not execute: ',
+			'extension_missing'    => 'Extension missing: ',
+			'file_access'          => 'Could not access file: ',
+			'file_open'            => 'File Error: Could not open file: ',
+			'from_failed'          => 'The following From address failed: ',
+			'instantiate'          => 'Could not instantiate mail function.',
+			'invalid_address'      => 'Invalid address: ',
+			'invalid_header'       => 'Invalid header name or value',
+			'invalid_hostentry'    => 'Invalid hostentry: ',
+			'invalid_host'         => 'Invalid host: ',
+			'mailer_not_supported' => ' mailer is not supported.',
+			'provide_address'      => 'You must provide at least one recipient email address.',
+			'recipients_failed'    => 'SMTP Error: The following recipients failed: ',
+			'signing'              => 'Signing Error: ',
+			'smtp_code'            => 'SMTP code: ',
+			'smtp_code_ex'         => 'Additional SMTP info: ',
+			'smtp_connect_failed'  => 'SMTP connect() failed.',
+			'smtp_detail'          => 'Detail: ',
+			'smtp_error'           => 'SMTP server error: ',
+			'variable_set'         => 'Cannot set or reset variable: ',
+		);
+		if ( empty( $lang_path ) ) {
+			// Calculate an absolute path so it can work if CWD is not here
+			$lang_path = dirname( __DIR__ ) . DIRECTORY_SEPARATOR . 'language' . DIRECTORY_SEPARATOR;
+		}
+
+		// Validate $langcode
+		$foundlang = true;
+		$langcode  = strtolower( $langcode );
+		if (
+			! preg_match( '/^(?P<lang>[a-z]{2})(?P<script>_[a-z]{4})?(?P<country>_[a-z]{2})?$/', $langcode, $matches )
+			&& $langcode !== 'en'
+		) {
+			$foundlang = false;
+			$langcode  = 'en';
+		}
+
+		// There is no English translation file
+		if ( 'en' !== $langcode ) {
+			$langcodes = array();
+			if ( ! empty( $matches['script'] ) && ! empty( $matches['country'] ) ) {
+				$langcodes[] = $matches['lang'] . $matches['script'] . $matches['country'];
+			}
+			if ( ! empty( $matches['country'] ) ) {
+				$langcodes[] = $matches['lang'] . $matches['country'];
+			}
+			if ( ! empty( $matches['script'] ) ) {
+				$langcodes[] = $matches['lang'] . $matches['script'];
+			}
+			$langcodes[] = $matches['lang'];
+
+			// Try and find a readable language file for the requested language.
+			$foundFile = false;
+			foreach ( $langcodes as $code ) {
+				$lang_file = $lang_path . 'phpmailer.lang-' . $code . '.php';
+				if ( static::fileIsAccessible( $lang_file ) ) {
+					$foundFile = true;
+					break;
+				}
+			}
+
+			if ( $foundFile === false ) {
+				$foundlang = false;
+			} else {
+				$lines = file( $lang_file );
+				foreach ( $lines as $line ) {
+					// Translation file lines look like this:
+					// $PHPMAILER_LANG['authenticate'] = 'SMTP-Fehler: Authentifizierung fehlgeschlagen.';
+					// These files are parsed as text and not PHP so as to avoid the possibility of code injection
+					// See https://blog.stevenlevithan.com/archives/match-quoted-string
+					$matches = array();
+					if (
+						preg_match(
+							'/^\$PHPMAILER_LANG\[\'([a-z\d_]+)\'\]\s*=\s*(["\'])(.+)*?\2;/',
+							$line,
+							$matches
+						) &&
+						// Ignore unknown translation keys
+						array_key_exists( $matches[1], $PHPMAILER_LANG )
+					) {
+						// Overwrite language-specific strings so we'll never have missing translation keys.
+						$PHPMAILER_LANG[ $matches[1] ] = (string) $matches[3];
+					}
+				}
+			}
+		}
+		$this->language = $PHPMAILER_LANG;
+
+		return $foundlang; // Returns false if language not found
+	}
+
+	/**
+	 * Get the array of strings for the current language.
+	 *
+	 * @return array
+	 */
+	public function getTranslations() {
+		if ( empty( $this->language ) ) {
+			$this->setLanguage(); // Set the default language.
+		}
+
+		return $this->language;
+	}
+
+	/**
+	 * Create recipient headers.
+	 *
+	 * @param string $type
+	 * @param array  $addr An array of recipients,
+	 *                     where each recipient is a 2-element indexed array with element 0 containing an address
+	 *                     and element 1 containing a name, like:
+	 *                     [['joe@example.com', 'Joe User'], ['zoe@example.com', 'Zoe User']]
+	 *
+	 * @return string
+	 */
+	public function addrAppend( $type, $addr ) {
+		$addresses = array();
+		foreach ( $addr as $address ) {
+			$addresses[] = $this->addrFormat( $address );
+		}
+
+		return $type . ': ' . implode( ', ', $addresses ) . static::$LE;
+	}
+
+	/**
+	 * Format an address for use in a message header.
+	 *
+	 * @param array $addr A 2-element indexed array, element 0 containing an address, element 1 containing a name like
+	 *                    ['joe@example.com', 'Joe User']
+	 *
+	 * @return string
+	 */
+	public function addrFormat( $addr ) {
+		if ( ! isset( $addr[1] ) || ( $addr[1] === '' ) ) { // No name provided
+			return $this->secureHeader( $addr[0] );
+		}
+
+		return $this->encodeHeader( $this->secureHeader( $addr[1] ), 'phrase' ) .
+			' <' . $this->secureHeader( $addr[0] ) . '>';
+	}
+
+	/**
+	 * Word-wrap message.
+	 * For use with mailers that do not automatically perform wrapping
+	 * and for quoted-printable encoded messages.
+	 * Original written by philippe.
+	 *
+	 * @param string $message The message to wrap
+	 * @param int    $length  The line length to wrap to
+	 * @param bool   $qp_mode Whether to run in Quoted-Printable mode
+	 *
+	 * @return string
+	 */
+	public function wrapText( $message, $length, $qp_mode = false ) {
+		if ( $qp_mode ) {
+			$soft_break = sprintf( ' =%s', static::$LE );
+		} else {
+			$soft_break = static::$LE;
+		}
+		// If utf-8 encoding is used, we will need to make sure we don't
+		// split multibyte characters when we wrap
+		$is_utf8 = static::CHARSET_UTF8 === strtolower( $this->CharSet );
+		$lelen   = strlen( static::$LE );
+		$crlflen = strlen( static::$LE );
+
+		$message = static::normalizeBreaks( $message );
+		// Remove a trailing line break
+		if ( substr( $message, -$lelen ) === static::$LE ) {
+			$message = substr( $message, 0, -$lelen );
+		}
+
+		// Split message into lines
+		$lines = explode( static::$LE, $message );
+		// Message will be rebuilt in here
+		$message = '';
+		foreach ( $lines as $line ) {
+			$words     = explode( ' ', $line );
+			$buf       = '';
+			$firstword = true;
+			foreach ( $words as $word ) {
+				if ( $qp_mode && ( strlen( $word ) > $length ) ) {
+					$space_left = $length - strlen( $buf ) - $crlflen;
+					if ( ! $firstword ) {
+						if ( $space_left > 20 ) {
+							$len = $space_left;
+							if ( $is_utf8 ) {
+								$len = $this->utf8CharBoundary( $word, $len );
+							} elseif ( '=' === substr( $word, $len - 1, 1 ) ) {
+								--$len;
+							} elseif ( '=' === substr( $word, $len - 2, 1 ) ) {
+								$len -= 2;
+							}
+							$part     = substr( $word, 0, $len );
+							$word     = substr( $word, $len );
+							$buf     .= ' ' . $part;
+							$message .= $buf . sprintf( '=%s', static::$LE );
+						} else {
+							$message .= $buf . $soft_break;
+						}
+						$buf = '';
+					}
+					while ( $word !== '' ) {
+						if ( $length <= 0 ) {
+							break;
+						}
+						$len = $length;
+						if ( $is_utf8 ) {
+							$len = $this->utf8CharBoundary( $word, $len );
+						} elseif ( '=' === substr( $word, $len - 1, 1 ) ) {
+							--$len;
+						} elseif ( '=' === substr( $word, $len - 2, 1 ) ) {
+							$len -= 2;
+						}
+						$part = substr( $word, 0, $len );
+						$word = (string) substr( $word, $len );
+
+						if ( $word !== '' ) {
+							$message .= $part . sprintf( '=%s', static::$LE );
+						} else {
+							$buf = $part;
+						}
+					}
+				} else {
+					$buf_o = $buf;
+					if ( ! $firstword ) {
+						$buf .= ' ';
+					}
+					$buf .= $word;
+
+					if ( '' !== $buf_o && strlen( $buf ) > $length ) {
+						$message .= $buf_o . $soft_break;
+						$buf      = $word;
+					}
+				}
+				$firstword = false;
+			}
+			$message .= $buf . static::$LE;
+		}
+
+		return $message;
+	}
+
+	/**
+	 * Find the last character boundary prior to $maxLength in a utf-8
+	 * quoted-printable encoded string.
+	 * Original written by Colin Brown.
+	 *
+	 * @param string $encodedText utf-8 QP text
+	 * @param int    $maxLength   Find the last character boundary prior to this length
+	 *
+	 * @return int
+	 */
+	public function utf8CharBoundary( $encodedText, $maxLength ) {
+		$foundSplitPos = false;
+		$lookBack      = 3;
+		while ( ! $foundSplitPos ) {
+			$lastChunk      = substr( $encodedText, $maxLength - $lookBack, $lookBack );
+			$encodedCharPos = strpos( $lastChunk, '=' );
+			if ( false !== $encodedCharPos ) {
+				// Found start of encoded character byte within $lookBack block.
+				// Check the encoded byte value (the 2 chars after the '=')
+				$hex = substr( $encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2 );
+				$dec = hexdec( $hex );
+				if ( $dec < 128 ) {
+					// Single byte character.
+					// If the encoded char was found at pos 0, it will fit
+					// otherwise reduce maxLength to start of the encoded char
+					if ( $encodedCharPos > 0 ) {
+						$maxLength -= $lookBack - $encodedCharPos;
+					}
+					$foundSplitPos = true;
+				} elseif ( $dec >= 192 ) {
+					// First byte of a multi byte character
+					// Reduce maxLength to split at start of character
+					$maxLength    -= $lookBack - $encodedCharPos;
+					$foundSplitPos = true;
+				} elseif ( $dec < 192 ) {
+					// Middle byte of a multi byte character, look further back
+					$lookBack += 3;
+				}
+			} else {
+				// No encoded character found
+				$foundSplitPos = true;
+			}
+		}
+
+		return $maxLength;
+	}
+
+	/**
+	 * Apply word wrapping to the message body.
+	 * Wraps the message body to the number of chars set in the WordWrap property.
+	 * You should only do this to plain-text bodies as wrapping HTML tags may break them.
+	 * This is called automatically by createBody(), so you don't need to call it yourself.
+	 */
+	public function setWordWrap() {
+		if ( $this->WordWrap < 1 ) {
+			return;
+		}
+
+		switch ( $this->message_type ) {
+			case 'alt':
+			case 'alt_inline':
+			case 'alt_attach':
+			case 'alt_inline_attach':
+				$this->AltBody = $this->wrapText( $this->AltBody, $this->WordWrap );
+				break;
+			default:
+				$this->Body = $this->wrapText( $this->Body, $this->WordWrap );
+				break;
+		}
+	}
+
+	/**
+	 * Assemble message headers.
+	 *
+	 * @return string The assembled headers
+	 */
+	public function createHeader() {
+		$result = '';
+
+		$result .= $this->headerLine( 'Date', '' === $this->MessageDate ? self::rfcDate() : $this->MessageDate );
+
+		// The To header is created automatically by mail(), so needs to be omitted here
+		if ( 'mail' !== $this->Mailer ) {
+			if ( $this->SingleTo ) {
+				foreach ( $this->to as $toaddr ) {
+					$this->SingleToArray[] = $this->addrFormat( $toaddr );
+				}
+			} elseif ( count( $this->to ) > 0 ) {
+				$result .= $this->addrAppend( 'To', $this->to );
+			} elseif ( count( $this->cc ) === 0 ) {
+				$result .= $this->headerLine( 'To', 'undisclosed-recipients:;' );
+			}
+		}
+		$result .= $this->addrAppend( 'From', array( array( trim( $this->From ), $this->FromName ) ) );
+
+		// sendmail and mail() extract Cc from the header before sending
+		if ( count( $this->cc ) > 0 ) {
+			$result .= $this->addrAppend( 'Cc', $this->cc );
+		}
+
+		// sendmail and mail() extract Bcc from the header before sending
+		if (
+			(
+				'sendmail' === $this->Mailer || 'qmail' === $this->Mailer || 'mail' === $this->Mailer
+			)
+			&& count( $this->bcc ) > 0
+		) {
+			$result .= $this->addrAppend( 'Bcc', $this->bcc );
+		}
+
+		if ( count( $this->ReplyTo ) > 0 ) {
+			$result .= $this->addrAppend( 'Reply-To', $this->ReplyTo );
+		}
+
+		// mail() sets the subject itself
+		if ( 'mail' !== $this->Mailer ) {
+			$result .= $this->headerLine( 'Subject', $this->encodeHeader( $this->secureHeader( $this->Subject ) ) );
+		}
+
+		// Only allow a custom message ID if it conforms to RFC 5322 section 3.6.4
+		// https://www.rfc-editor.org/rfc/rfc5322#section-3.6.4
+		if (
+			'' !== $this->MessageID &&
+			preg_match(
+				'/^<((([a-z\d!#$%&\'*+\/=?^_`{|}~-]+(\.[a-z\d!#$%&\'*+\/=?^_`{|}~-]+)*)' .
+				'|("(([\x01-\x08\x0B\x0C\x0E-\x1F\x7F]|[\x21\x23-\x5B\x5D-\x7E])' .
+				'|(\\[\x01-\x09\x0B\x0C\x0E-\x7F]))*"))@(([a-z\d!#$%&\'*+\/=?^_`{|}~-]+' .
+				'(\.[a-z\d!#$%&\'*+\/=?^_`{|}~-]+)*)|(\[(([\x01-\x08\x0B\x0C\x0E-\x1F\x7F]' .
+				'|[\x21-\x5A\x5E-\x7E])|(\\[\x01-\x09\x0B\x0C\x0E-\x7F]))*\])))>$/Di',
+				$this->MessageID
+			)
+		) {
+			$this->lastMessageID = $this->MessageID;
+		} else {
+			$this->lastMessageID = sprintf( '<%s@%s>', $this->uniqueid, $this->serverHostname() );
+		}
+		$result .= $this->headerLine( 'Message-ID', $this->lastMessageID );
+		if ( null !== $this->Priority ) {
+			$result .= $this->headerLine( 'X-Priority', $this->Priority );
+		}
+		if ( '' === $this->XMailer ) {
+			// Empty string for default X-Mailer header
+			$result .= $this->headerLine(
+				'X-Mailer',
+				'PHPMailer ' . self::VERSION . ' (https://github.com/PHPMailer/PHPMailer)'
+			);
+		} elseif ( is_string( $this->XMailer ) && trim( $this->XMailer ) !== '' ) {
+			// Some string
+			$result .= $this->headerLine( 'X-Mailer', trim( $this->XMailer ) );
+		} //Other values result in no X-Mailer header
+
+		if ( '' !== $this->ConfirmReadingTo ) {
+			$result .= $this->headerLine( 'Disposition-Notification-To', '<' . $this->ConfirmReadingTo . '>' );
+		}
+
+		// Add custom headers
+		foreach ( $this->CustomHeader as $header ) {
+			$result .= $this->headerLine(
+				trim( $header[0] ),
+				$this->encodeHeader( trim( $header[1] ) )
+			);
+		}
+		if ( ! $this->sign_key_file ) {
+			$result .= $this->headerLine( 'MIME-Version', '1.0' );
+			$result .= $this->getMailMIME();
+		}
+
+		return $result;
+	}
+
+	/**
+	 * Get the message MIME type headers.
+	 *
+	 * @return string
+	 */
+	public function getMailMIME() {
+		$result      = '';
+		$ismultipart = true;
+		switch ( $this->message_type ) {
+			case 'inline':
+				$result .= $this->headerLine( 'Content-Type', static::CONTENT_TYPE_MULTIPART_RELATED . ';' );
+				$result .= $this->textLine( ' boundary="' . $this->boundary[1] . '"' );
+				break;
+			case 'attach':
+			case 'inline_attach':
+			case 'alt_attach':
+			case 'alt_inline_attach':
+				$result .= $this->headerLine( 'Content-Type', static::CONTENT_TYPE_MULTIPART_MIXED . ';' );
+				$result .= $this->textLine( ' boundary="' . $this->boundary[1] . '"' );
+				break;
+			case 'alt':
+			case 'alt_inline':
+				$result .= $this->headerLine( 'Content-Type', static::CONTENT_TYPE_MULTIPART_ALTERNATIVE . ';' );
+				$result .= $this->textLine( ' boundary="' . $this->boundary[1] . '"' );
+				break;
+			default:
+				// Catches case 'plain': and case '':
+				$result     .= $this->textLine( 'Content-Type: ' . $this->ContentType . '; charset=' . $this->CharSet );
+				$ismultipart = false;
+				break;
+		}
+		// RFC1341 part 5 says 7bit is assumed if not specified
+		if ( static::ENCODING_7BIT !== $this->Encoding ) {
+			// RFC 2045 section 6.4 says multipart MIME parts may only use 7bit, 8bit or binary CTE
+			if ( $ismultipart ) {
+				if ( static::ENCODING_8BIT === $this->Encoding ) {
+					$result .= $this->headerLine( 'Content-Transfer-Encoding', static::ENCODING_8BIT );
+				}
+				// The only remaining alternatives are quoted-printable and base64, which are both 7bit compatible
+			} else {
+				$result .= $this->headerLine( 'Content-Transfer-Encoding', $this->Encoding );
+			}
+		}
+
+		return $result;
+	}
+
+	/**
+	 * Returns the whole MIME message.
+	 * Includes complete headers and body.
+	 * Only valid post preSend().
+	 *
+	 * @see PHPMailer::preSend()
+	 *
+	 * @return string
+	 */
+	public function getSentMIMEMessage() {
+		return static::stripTrailingWSP( $this->MIMEHeader . $this->mailHeader ) .
+			static::$LE . static::$LE . $this->MIMEBody;
+	}
+
+	/**
+	 * Create a unique ID to use for boundaries.
+	 *
+	 * @return string
+	 */
+	protected function generateId() {
+		$len   = 32; // 32 bytes = 256 bits
+		$bytes = '';
+		if ( function_exists( 'random_bytes' ) ) {
+			try {
+				$bytes = random_bytes( $len );
+			} catch ( \Exception $e ) {
+				// Do nothing
+			}
+		} elseif ( function_exists( 'openssl_random_pseudo_bytes' ) ) {
+			/** @noinspection CryptographicallySecureRandomnessInspection */
+			$bytes = openssl_random_pseudo_bytes( $len );
+		}
+		if ( $bytes === '' ) {
+			// We failed to produce a proper random string, so make do.
+			// Use a hash to force the length to the same as the other methods
+			$bytes = hash( 'sha256', uniqid( (string) mt_rand(), true ), true );
+		}
+
+		// We don't care about messing up base64 format here, just want a random string
+		return str_replace( array( '=', '+', '/' ), '', base64_encode( hash( 'sha256', $bytes, true ) ) );
+	}
+
+	/**
+	 * Assemble the message body.
+	 * Returns an empty string on failure.
+	 *
+	 * @throws Exception
+	 *
+	 * @return string The assembled message body
+	 */
+	public function createBody() {
+		$body = '';
+		// Create unique IDs and preset boundaries
+		$this->setBoundaries();
+
+		if ( $this->sign_key_file ) {
+			$body .= $this->getMailMIME() . static::$LE;
+		}
+
+		$this->setWordWrap();
+
+		$bodyEncoding = $this->Encoding;
+		$bodyCharSet  = $this->CharSet;
+		// Can we do a 7-bit downgrade?
+		if ( static::ENCODING_8BIT === $bodyEncoding && ! $this->has8bitChars( $this->Body ) ) {
+			$bodyEncoding = static::ENCODING_7BIT;
+			// All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit
+			$bodyCharSet = static::CHARSET_ASCII;
+		}
+		// If lines are too long, and we're not already using an encoding that will shorten them,
+		// change to quoted-printable transfer encoding for the body part only
+		if ( static::ENCODING_BASE64 !== $this->Encoding && static::hasLineLongerThanMax( $this->Body ) ) {
+			$bodyEncoding = static::ENCODING_QUOTED_PRINTABLE;
+		}
+
+		$altBodyEncoding = $this->Encoding;
+		$altBodyCharSet  = $this->CharSet;
+		// Can we do a 7-bit downgrade?
+		if ( static::ENCODING_8BIT === $altBodyEncoding && ! $this->has8bitChars( $this->AltBody ) ) {
+			$altBodyEncoding = static::ENCODING_7BIT;
+			// All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit
+			$altBodyCharSet = static::CHARSET_ASCII;
+		}
+		// If lines are too long, and we're not already using an encoding that will shorten them,
+		// change to quoted-printable transfer encoding for the alt body part only
+		if ( static::ENCODING_BASE64 !== $altBodyEncoding && static::hasLineLongerThanMax( $this->AltBody ) ) {
+			$altBodyEncoding = static::ENCODING_QUOTED_PRINTABLE;
+		}
+		// Use this as a preamble in all multipart message types
+		$mimepre = '';
+		switch ( $this->message_type ) {
+			case 'inline':
+				$body .= $mimepre;
+				$body .= $this->getBoundary( $this->boundary[1], $bodyCharSet, '', $bodyEncoding );
+				$body .= $this->encodeString( $this->Body, $bodyEncoding );
+				$body .= static::$LE;
+				$body .= $this->attachAll( 'inline', $this->boundary[1] );
+				break;
+			case 'attach':
+				$body .= $mimepre;
+				$body .= $this->getBoundary( $this->boundary[1], $bodyCharSet, '', $bodyEncoding );
+				$body .= $this->encodeString( $this->Body, $bodyEncoding );
+				$body .= static::$LE;
+				$body .= $this->attachAll( 'attachment', $this->boundary[1] );
+				break;
+			case 'inline_attach':
+				$body .= $mimepre;
+				$body .= $this->textLine( '--' . $this->boundary[1] );
+				$body .= $this->headerLine( 'Content-Type', static::CONTENT_TYPE_MULTIPART_RELATED . ';' );
+				$body .= $this->textLine( ' boundary="' . $this->boundary[2] . '";' );
+				$body .= $this->textLine( ' type="' . static::CONTENT_TYPE_TEXT_HTML . '"' );
+				$body .= static::$LE;
+				$body .= $this->getBoundary( $this->boundary[2], $bodyCharSet, '', $bodyEncoding );
+				$body .= $this->encodeString( $this->Body, $bodyEncoding );
+				$body .= static::$LE;
+				$body .= $this->attachAll( 'inline', $this->boundary[2] );
+				$body .= static::$LE;
+				$body .= $this->attachAll( 'attachment', $this->boundary[1] );
+				break;
+			case 'alt':
+				$body .= $mimepre;
+				$body .= $this->getBoundary(
+					$this->boundary[1],
+					$altBodyCharSet,
+					static::CONTENT_TYPE_PLAINTEXT,
+					$altBodyEncoding
+				);
+				$body .= $this->encodeString( $this->AltBody, $altBodyEncoding );
+				$body .= static::$LE;
+				$body .= $this->getBoundary(
+					$this->boundary[1],
+					$bodyCharSet,
+					static::CONTENT_TYPE_TEXT_HTML,
+					$bodyEncoding
+				);
+				$body .= $this->encodeString( $this->Body, $bodyEncoding );
+				$body .= static::$LE;
+				if ( ! empty( $this->Ical ) ) {
+					$method = static::ICAL_METHOD_REQUEST;
+					foreach ( static::$IcalMethods as $imethod ) {
+						if ( stripos( $this->Ical, 'METHOD:' . $imethod ) !== false ) {
+							$method = $imethod;
+							break;
+						}
+					}
+					$body .= $this->getBoundary(
+						$this->boundary[1],
+						'',
+						static::CONTENT_TYPE_TEXT_CALENDAR . '; method=' . $method,
+						''
+					);
+					$body .= $this->encodeString( $this->Ical, $this->Encoding );
+					$body .= static::$LE;
+				}
+				$body .= $this->endBoundary( $this->boundary[1] );
+				break;
+			case 'alt_inline':
+				$body .= $mimepre;
+				$body .= $this->getBoundary(
+					$this->boundary[1],
+					$altBodyCharSet,
+					static::CONTENT_TYPE_PLAINTEXT,
+					$altBodyEncoding
+				);
+				$body .= $this->encodeString( $this->AltBody, $altBodyEncoding );
+				$body .= static::$LE;
+				$body .= $this->textLine( '--' . $this->boundary[1] );
+				$body .= $this->headerLine( 'Content-Type', static::CONTENT_TYPE_MULTIPART_RELATED . ';' );
+				$body .= $this->textLine( ' boundary="' . $this->boundary[2] . '";' );
+				$body .= $this->textLine( ' type="' . static::CONTENT_TYPE_TEXT_HTML . '"' );
+				$body .= static::$LE;
+				$body .= $this->getBoundary(
+					$this->boundary[2],
+					$bodyCharSet,
+					static::CONTENT_TYPE_TEXT_HTML,
+					$bodyEncoding
+				);
+				$body .= $this->encodeString( $this->Body, $bodyEncoding );
+				$body .= static::$LE;
+				$body .= $this->attachAll( 'inline', $this->boundary[2] );
+				$body .= static::$LE;
+				$body .= $this->endBoundary( $this->boundary[1] );
+				break;
+			case 'alt_attach':
+				$body .= $mimepre;
+				$body .= $this->textLine( '--' . $this->boundary[1] );
+				$body .= $this->headerLine( 'Content-Type', static::CONTENT_TYPE_MULTIPART_ALTERNATIVE . ';' );
+				$body .= $this->textLine( ' boundary="' . $this->boundary[2] . '"' );
+				$body .= static::$LE;
+				$body .= $this->getBoundary(
+					$this->boundary[2],
+					$altBodyCharSet,
+					static::CONTENT_TYPE_PLAINTEXT,
+					$altBodyEncoding
+				);
+				$body .= $this->encodeString( $this->AltBody, $altBodyEncoding );
+				$body .= static::$LE;
+				$body .= $this->getBoundary(
+					$this->boundary[2],
+					$bodyCharSet,
+					static::CONTENT_TYPE_TEXT_HTML,
+					$bodyEncoding
+				);
+				$body .= $this->encodeString( $this->Body, $bodyEncoding );
+				$body .= static::$LE;
+				if ( ! empty( $this->Ical ) ) {
+					$method = static::ICAL_METHOD_REQUEST;
+					foreach ( static::$IcalMethods as $imethod ) {
+						if ( stripos( $this->Ical, 'METHOD:' . $imethod ) !== false ) {
+							$method = $imethod;
+							break;
+						}
+					}
+					$body .= $this->getBoundary(
+						$this->boundary[2],
+						'',
+						static::CONTENT_TYPE_TEXT_CALENDAR . '; method=' . $method,
+						''
+					);
+					$body .= $this->encodeString( $this->Ical, $this->Encoding );
+				}
+				$body .= $this->endBoundary( $this->boundary[2] );
+				$body .= static::$LE;
+				$body .= $this->attachAll( 'attachment', $this->boundary[1] );
+				break;
+			case 'alt_inline_attach':
+				$body .= $mimepre;
+				$body .= $this->textLine( '--' . $this->boundary[1] );
+				$body .= $this->headerLine( 'Content-Type', static::CONTENT_TYPE_MULTIPART_ALTERNATIVE . ';' );
+				$body .= $this->textLine( ' boundary="' . $this->boundary[2] . '"' );
+				$body .= static::$LE;
+				$body .= $this->getBoundary(
+					$this->boundary[2],
+					$altBodyCharSet,
+					static::CONTENT_TYPE_PLAINTEXT,
+					$altBodyEncoding
+				);
+				$body .= $this->encodeString( $this->AltBody, $altBodyEncoding );
+				$body .= static::$LE;
+				$body .= $this->textLine( '--' . $this->boundary[2] );
+				$body .= $this->headerLine( 'Content-Type', static::CONTENT_TYPE_MULTIPART_RELATED . ';' );
+				$body .= $this->textLine( ' boundary="' . $this->boundary[3] . '";' );
+				$body .= $this->textLine( ' type="' . static::CONTENT_TYPE_TEXT_HTML . '"' );
+				$body .= static::$LE;
+				$body .= $this->getBoundary(
+					$this->boundary[3],
+					$bodyCharSet,
+					static::CONTENT_TYPE_TEXT_HTML,
+					$bodyEncoding
+				);
+				$body .= $this->encodeString( $this->Body, $bodyEncoding );
+				$body .= static::$LE;
+				$body .= $this->attachAll( 'inline', $this->boundary[3] );
+				$body .= static::$LE;
+				$body .= $this->endBoundary( $this->boundary[2] );
+				$body .= static::$LE;
+				$body .= $this->attachAll( 'attachment', $this->boundary[1] );
+				break;
+			default:
+				// Catch case 'plain' and case '', applies to simple `text/plain` and `text/html` body content types
+				// Reset the `Encoding` property in case we changed it for line length reasons
+				$this->Encoding = $bodyEncoding;
+				$body          .= $this->encodeString( $this->Body, $this->Encoding );
+				break;
+		}
+
+		if ( $this->isError() ) {
+			$body = '';
+			if ( $this->exceptions ) {
+				throw new Exception( $this->lang( 'empty_message' ), self::STOP_CRITICAL );
+			}
+		} elseif ( $this->sign_key_file ) {
+			try {
+				if ( ! defined( 'PKCS7_TEXT' ) ) {
+					throw new Exception( $this->lang( 'extension_missing' ) . 'openssl' );
+				}
+
+				$file   = tempnam( sys_get_temp_dir(), 'srcsign' );
+				$signed = tempnam( sys_get_temp_dir(), 'mailsign' );
+				file_put_contents( $file, $body );
+
+				// Workaround for PHP bug https://bugs.php.net/bug.php?id=69197
+				if ( empty( $this->sign_extracerts_file ) ) {
+					$sign = @openssl_pkcs7_sign(
+						$file,
+						$signed,
+						'file://' . realpath( $this->sign_cert_file ),
+						array( 'file://' . realpath( $this->sign_key_file ), $this->sign_key_pass ),
+						array()
+					);
+				} else {
+					$sign = @openssl_pkcs7_sign(
+						$file,
+						$signed,
+						'file://' . realpath( $this->sign_cert_file ),
+						array( 'file://' . realpath( $this->sign_key_file ), $this->sign_key_pass ),
+						array(),
+						PKCS7_DETACHED,
+						$this->sign_extracerts_file
+					);
+				}
+
+				@unlink( $file );
+				if ( $sign ) {
+					$body = file_get_contents( $signed );
+					@unlink( $signed );
+					// The message returned by openssl contains both headers and body, so need to split them up
+					$parts             = explode( "\n\n", $body, 2 );
+					$this->MIMEHeader .= $parts[0] . static::$LE . static::$LE;
+					$body              = $parts[1];
+				} else {
+					@unlink( $signed );
+					throw new Exception( $this->lang( 'signing' ) . openssl_error_string() );
+				}
+			} catch ( Exception $exc ) {
+				$body = '';
+				if ( $this->exceptions ) {
+					throw $exc;
+				}
+			}
+		}
+
+		return $body;
+	}
+
+	/**
+	 * Get the boundaries that this message will use
+	 *
+	 * @return array
+	 */
+	public function getBoundaries() {
+		if ( empty( $this->boundary ) ) {
+			$this->setBoundaries();
+		}
+		return $this->boundary;
+	}
+
+	/**
+	 * Return the start of a message boundary.
+	 *
+	 * @param string $boundary
+	 * @param string $charSet
+	 * @param string $contentType
+	 * @param string $encoding
+	 *
+	 * @return string
+	 */
+	protected function getBoundary( $boundary, $charSet, $contentType, $encoding ) {
+		$result = '';
+		if ( '' === $charSet ) {
+			$charSet = $this->CharSet;
+		}
+		if ( '' === $contentType ) {
+			$contentType = $this->ContentType;
+		}
+		if ( '' === $encoding ) {
+			$encoding = $this->Encoding;
+		}
+		$result .= $this->textLine( '--' . $boundary );
+		$result .= sprintf( 'Content-Type: %s; charset=%s', $contentType, $charSet );
+		$result .= static::$LE;
+		// RFC1341 part 5 says 7bit is assumed if not specified
+		if ( static::ENCODING_7BIT !== $encoding ) {
+			$result .= $this->headerLine( 'Content-Transfer-Encoding', $encoding );
+		}
+		$result .= static::$LE;
+
+		return $result;
+	}
+
+	/**
+	 * Return the end of a message boundary.
+	 *
+	 * @param string $boundary
+	 *
+	 * @return string
+	 */
+	protected function endBoundary( $boundary ) {
+		return static::$LE . '--' . $boundary . '--' . static::$LE;
+	}
+
+	/**
+	 * Set the message type.
+	 * PHPMailer only supports some preset message types, not arbitrary MIME structures.
+	 */
+	protected function setMessageType() {
+		$type = array();
+		if ( $this->alternativeExists() ) {
+			$type[] = 'alt';
+		}
+		if ( $this->inlineImageExists() ) {
+			$type[] = 'inline';
+		}
+		if ( $this->attachmentExists() ) {
+			$type[] = 'attach';
+		}
+		$this->message_type = implode( '_', $type );
+		if ( '' === $this->message_type ) {
+			// The 'plain' message_type refers to the message having a single body element, not that it is plain-text
+			$this->message_type = 'plain';
+		}
+	}
+
+	/**
+	 * Format a header line.
+	 *
+	 * @param string     $name
+	 * @param string|int $value
+	 *
+	 * @return string
+	 */
+	public function headerLine( $name, $value ) {
+		return $name . ': ' . $value . static::$LE;
+	}
+
+	/**
+	 * Return a formatted mail line.
+	 *
+	 * @param string $value
+	 *
+	 * @return string
+	 */
+	public function textLine( $value ) {
+		return $value . static::$LE;
+	}
+
+	/**
+	 * Add an attachment from a path on the filesystem.
+	 * Never use a user-supplied path to a file!
+	 * Returns false if the file could not be found or read.
+	 * Explicitly *does not* support passing URLs; PHPMailer is not an HTTP client.
+	 * If you need to do that, fetch the resource yourself and pass it in via a local file or string.
+	 *
+	 * @param string $path        Path to the attachment
+	 * @param string $name        Overrides the attachment name
+	 * @param string $encoding    File encoding (see $Encoding)
+	 * @param string $type        MIME type, e.g. `image/jpeg`; determined automatically from $path if not specified
+	 * @param string $disposition Disposition to use
+	 *
+	 * @throws Exception
+	 *
+	 * @return bool
+	 */
+	public function addAttachment(
+		$path,
+		$name = '',
+		$encoding = self::ENCODING_BASE64,
+		$type = '',
+		$disposition = 'attachment'
+	) {
+		try {
+			if ( ! static::fileIsAccessible( $path ) ) {
+				throw new Exception( $this->lang( 'file_access' ) . $path, self::STOP_CONTINUE );
+			}
+
+			// If a MIME type is not specified, try to work it out from the file name
+			if ( '' === $type ) {
+				$type = static::filenameToType( $path );
+			}
+
+			$filename = (string) static::mb_pathinfo( $path, PATHINFO_BASENAME );
+			if ( '' === $name ) {
+				$name = $filename;
+			}
+			if ( ! $this->validateEncoding( $encoding ) ) {
+				throw new Exception( $this->lang( 'encoding' ) . $encoding );
+			}
+
+			$this->attachment[] = array(
+				0 => $path,
+				1 => $filename,
+				2 => $name,
+				3 => $encoding,
+				4 => $type,
+				5 => false, // isStringAttachment
+				6 => $disposition,
+				7 => $name,
+			);
+		} catch ( Exception $exc ) {
+			$this->setError( $exc->getMessage() );
+			$this->edebug( $exc->getMessage() );
+			if ( $this->exceptions ) {
+				throw $exc;
+			}
+
+			return false;
+		}
+
+		return true;
+	}
+
+	/**
+	 * Return the array of attachments.
+	 *
+	 * @return array
+	 */
+	public function getAttachments() {
+		return $this->attachment;
+	}
+
+	/**
+	 * Attach all file, string, and binary attachments to the message.
+	 * Returns an empty string on failure.
+	 *
+	 * @param string $disposition_type
+	 * @param string $boundary
+	 *
+	 * @throws Exception
+	 *
+	 * @return string
+	 */
+	protected function attachAll( $disposition_type, $boundary ) {
+		// Return text of body
+		$mime    = array();
+		$cidUniq = array();
+		$incl    = array();
+
+		// Add all attachments
+		foreach ( $this->attachment as $attachment ) {
+			// Check if it is a valid disposition_filter
+			if ( $attachment[6] === $disposition_type ) {
+				// Check for string attachment
+				$string  = '';
+				$path    = '';
+				$bString = $attachment[5];
+				if ( $bString ) {
+					$string = $attachment[0];
+				} else {
+					$path = $attachment[0];
+				}
+
+				$inclhash = hash( 'sha256', serialize( $attachment ) );
+				if ( in_array( $inclhash, $incl, true ) ) {
+					continue;
+				}
+				$incl[]      = $inclhash;
+				$name        = $attachment[2];
+				$encoding    = $attachment[3];
+				$type        = $attachment[4];
+				$disposition = $attachment[6];
+				$cid         = $attachment[7];
+				if ( 'inline' === $disposition && array_key_exists( $cid, $cidUniq ) ) {
+					continue;
+				}
+				$cidUniq[ $cid ] = true;
+
+				$mime[] = sprintf( '--%s%s', $boundary, static::$LE );
+				// Only include a filename property if we have one
+				if ( ! empty( $name ) ) {
+					$mime[] = sprintf(
+						'Content-Type: %s; name=%s%s',
+						$type,
+						static::quotedString( $this->encodeHeader( $this->secureHeader( $name ) ) ),
+						static::$LE
+					);
+				} else {
+					$mime[] = sprintf(
+						'Content-Type: %s%s',
+						$type,
+						static::$LE
+					);
+				}
+				// RFC1341 part 5 says 7bit is assumed if not specified
+				if ( static::ENCODING_7BIT !== $encoding ) {
+					$mime[] = sprintf( 'Content-Transfer-Encoding: %s%s', $encoding, static::$LE );
+				}
+
+				// Only set Content-IDs on inline attachments
+				if ( (string) $cid !== '' && $disposition === 'inline' ) {
+					$mime[] = 'Content-ID: <' . $this->encodeHeader( $this->secureHeader( $cid ) ) . '>' . static::$LE;
+				}
+
+				// Allow for bypassing the Content-Disposition header
+				if ( ! empty( $disposition ) ) {
+					$encoded_name = $this->encodeHeader( $this->secureHeader( $name ) );
+					if ( ! empty( $encoded_name ) ) {
+						$mime[] = sprintf(
+							'Content-Disposition: %s; filename=%s%s',
+							$disposition,
+							static::quotedString( $encoded_name ),
+							static::$LE . static::$LE
+						);
+					} else {
+						$mime[] = sprintf(
+							'Content-Disposition: %s%s',
+							$disposition,
+							static::$LE . static::$LE
+						);
+					}
+				} else {
+					$mime[] = static::$LE;
+				}
+
+				// Encode as string attachment
+				if ( $bString ) {
+					$mime[] = $this->encodeString( $string, $encoding );
+				} else {
+					$mime[] = $this->encodeFile( $path, $encoding );
+				}
+				if ( $this->isError() ) {
+					return '';
+				}
+				$mime[] = static::$LE;
+			}
+		}
+
+		$mime[] = sprintf( '--%s--%s', $boundary, static::$LE );
+
+		return implode( '', $mime );
+	}
+
+	/**
+	 * Encode a file attachment in requested format.
+	 * Returns an empty string on failure.
+	 *
+	 * @param string $path     The full path to the file
+	 * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
+	 *
+	 * @return string
+	 */
+	protected function encodeFile( $path, $encoding = self::ENCODING_BASE64 ) {
+		try {
+			if ( ! static::fileIsAccessible( $path ) ) {
+				throw new Exception( $this->lang( 'file_open' ) . $path, self::STOP_CONTINUE );
+			}
+			$file_buffer = file_get_contents( $path );
+			if ( false === $file_buffer ) {
+				throw new Exception( $this->lang( 'file_open' ) . $path, self::STOP_CONTINUE );
+			}
+			$file_buffer = $this->encodeString( $file_buffer, $encoding );
+
+			return $file_buffer;
+		} catch ( Exception $exc ) {
+			$this->setError( $exc->getMessage() );
+			$this->edebug( $exc->getMessage() );
+			if ( $this->exceptions ) {
+				throw $exc;
+			}
+
+			return '';
+		}
+	}
+
+	/**
+	 * Encode a string in requested format.
+	 * Returns an empty string on failure.
+	 *
+	 * @param string $str      The text to encode
+	 * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
+	 *
+	 * @throws Exception
+	 *
+	 * @return string
+	 */
+	public function encodeString( $str, $encoding = self::ENCODING_BASE64 ) {
+		$encoded = '';
+		switch ( strtolower( $encoding ) ) {
+			case static::ENCODING_BASE64:
+				$encoded = chunk_split(
+					base64_encode( $str ),
+					static::STD_LINE_LENGTH,
+					static::$LE
+				);
+				break;
+			case static::ENCODING_7BIT:
+			case static::ENCODING_8BIT:
+				$encoded = static::normalizeBreaks( $str );
+				// Make sure it ends with a line break
+				if ( substr( $encoded, -( strlen( static::$LE ) ) ) !== static::$LE ) {
+					$encoded .= static::$LE;
+				}
+				break;
+			case static::ENCODING_BINARY:
+				$encoded = $str;
+				break;
+			case static::ENCODING_QUOTED_PRINTABLE:
+				$encoded = $this->encodeQP( $str );
+				break;
+			default:
+				$this->setError( $this->lang( 'encoding' ) . $encoding );
+				if ( $this->exceptions ) {
+					throw new Exception( $this->lang( 'encoding' ) . $encoding );
+				}
+				break;
+		}
+
+		return $encoded;
+	}
+
+	/**
+	 * Encode a header value (not including its label) optimally.
+	 * Picks shortest of Q, B, or none. Result includes folding if needed.
+	 * See RFC822 definitions for phrase, comment and text positions.
+	 *
+	 * @param string $str      The header value to encode
+	 * @param string $position What context the string will be used in
+	 *
+	 * @return string
+	 */
+	public function encodeHeader( $str, $position = 'text' ) {
+		$matchcount = 0;
+		switch ( strtolower( $position ) ) {
+			case 'phrase':
+				if ( ! preg_match( '/[\200-\377]/', $str ) ) {
+					// Can't use addslashes as we don't know the value of magic_quotes_sybase
+					$encoded = addcslashes( $str, "\0..\37\177\\\"" );
+					if ( ( $str === $encoded ) && ! preg_match( '/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str ) ) {
+						return $encoded;
+					}
+
+					return "\"$encoded\"";
+				}
+				$matchcount = preg_match_all( '/[^\040\041\043-\133\135-\176]/', $str, $matches );
+				break;
+			/* @noinspection PhpMissingBreakStatementInspection */
+			case 'comment':
+				$matchcount = preg_match_all( '/[()"]/', $str, $matches );
+				// fallthrough
+			case 'text':
+			default:
+				$matchcount += preg_match_all( '/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches );
+				break;
+		}
+
+		if ( $this->has8bitChars( $str ) ) {
+			$charset = $this->CharSet;
+		} else {
+			$charset = static::CHARSET_ASCII;
+		}
+
+		// Q/B encoding adds 8 chars and the charset ("` =?<charset>?[QB]?<content>?=`").
+		$overhead = 8 + strlen( $charset );
+
+		if ( 'mail' === $this->Mailer ) {
+			$maxlen = static::MAIL_MAX_LINE_LENGTH - $overhead;
+		} else {
+			$maxlen = static::MAX_LINE_LENGTH - $overhead;
+		}
+
+		// Select the encoding that produces the shortest output and/or prevents corruption.
+		if ( $matchcount > strlen( $str ) / 3 ) {
+			// More than 1/3 of the content needs encoding, use B-encode.
+			$encoding = 'B';
+		} elseif ( $matchcount > 0 ) {
+			// Less than 1/3 of the content needs encoding, use Q-encode.
+			$encoding = 'Q';
+		} elseif ( strlen( $str ) > $maxlen ) {
+			// No encoding needed, but value exceeds max line length, use Q-encode to prevent corruption.
+			$encoding = 'Q';
+		} else {
+			// No reformatting needed
+			$encoding = false;
+		}
+
+		switch ( $encoding ) {
+			case 'B':
+				if ( $this->hasMultiBytes( $str ) ) {
+					// Use a custom function which correctly encodes and wraps long
+					// multibyte strings without breaking lines within a character
+					$encoded = $this->base64EncodeWrapMB( $str, "\n" );
+				} else {
+					$encoded = base64_encode( $str );
+					$maxlen -= $maxlen % 4;
+					$encoded = trim( chunk_split( $encoded, $maxlen, "\n" ) );
+				}
+				$encoded = preg_replace( '/^(.*)$/m', ' =?' . $charset . "?$encoding?\\1?=", $encoded );
+				break;
+			case 'Q':
+				$encoded = $this->encodeQ( $str, $position );
+				$encoded = $this->wrapText( $encoded, $maxlen, true );
+				$encoded = str_replace( '=' . static::$LE, "\n", trim( $encoded ) );
+				$encoded = preg_replace( '/^(.*)$/m', ' =?' . $charset . "?$encoding?\\1?=", $encoded );
+				break;
+			default:
+				return $str;
+		}
+
+		return trim( static::normalizeBreaks( $encoded ) );
+	}
+
+	/**
+	 * Check if a string contains multi-byte characters.
+	 *
+	 * @param string $str multi-byte text to wrap encode
+	 *
+	 * @return bool
+	 */
+	public function hasMultiBytes( $str ) {
+		if ( function_exists( 'mb_strlen' ) ) {
+			return strlen( $str ) > mb_strlen( $str, $this->CharSet );
+		}
+
+		// Assume no multibytes (we can't handle without mbstring functions anyway)
+		return false;
+	}
+
+	/**
+	 * Does a string contain any 8-bit chars (in any charset)?
+	 *
+	 * @param string $text
+	 *
+	 * @return bool
+	 */
+	public function has8bitChars( $text ) {
+		return (bool) preg_match( '/[\x80-\xFF]/', $text );
+	}
+
+	/**
+	 * Encode and wrap long multibyte strings for mail headers
+	 * without breaking lines within a character.
+	 * Adapted from a function by paravoid.
+	 *
+	 * @see https://www.php.net/manual/en/function.mb-encode-mimeheader.php#60283
+	 *
+	 * @param string $str       multi-byte text to wrap encode
+	 * @param string $linebreak string to use as linefeed/end-of-line
+	 *
+	 * @return string
+	 */
+	public function base64EncodeWrapMB( $str, $linebreak = null ) {
+		$start   = '=?' . $this->CharSet . '?B?';
+		$end     = '?=';
+		$encoded = '';
+		if ( null === $linebreak ) {
+			$linebreak = static::$LE;
+		}
+
+		$mb_length = mb_strlen( $str, $this->CharSet );
+		// Each line must have length <= 75, including $start and $end
+		$length = 75 - strlen( $start ) - strlen( $end );
+		// Average multi-byte ratio
+		$ratio = $mb_length / strlen( $str );
+		// Base64 has a 4:3 ratio
+		$avgLength = floor( $length * $ratio * .75 );
+
+		$offset = 0;
+		for ( $i = 0; $i < $mb_length; $i += $offset ) {
+			$lookBack = 0;
+			do {
+				$offset = $avgLength - $lookBack;
+				$chunk  = mb_substr( $str, $i, $offset, $this->CharSet );
+				$chunk  = base64_encode( $chunk );
+				++$lookBack;
+			} while ( strlen( $chunk ) > $length );
+			$encoded .= $chunk . $linebreak;
+		}
+
+		// Chomp the last linefeed
+		return substr( $encoded, 0, -strlen( $linebreak ) );
+	}
+
+	/**
+	 * Encode a string in quoted-printable format.
+	 * According to RFC2045 section 6.7.
+	 *
+	 * @param string $string The text to encode
+	 *
+	 * @return string
+	 */
+	public function encodeQP( $string ) {
+		return static::normalizeBreaks( quoted_printable_encode( $string ) );
+	}
+
+	/**
+	 * Encode a string using Q encoding.
+	 *
+	 * @see https://www.rfc-editor.org/rfc/rfc2047#section-4.2
+	 *
+	 * @param string $str      the text to encode
+	 * @param string $position Where the text is going to be used, see the RFC for what that means
+	 *
+	 * @return string
+	 */
+	public function encodeQ( $str, $position = 'text' ) {
+		// There should not be any EOL in the string
+		$pattern = '';
+		$encoded = str_replace( array( "\r", "\n" ), '', $str );
+		switch ( strtolower( $position ) ) {
+			case 'phrase':
+				// RFC 2047 section 5.3
+				$pattern = '^A-Za-z0-9!*+\/ -';
+				break;
+			/*
+			 * RFC 2047 section 5.2.
+			 * Build $pattern without including delimiters and []
+			 */
+			/* @noinspection PhpMissingBreakStatementInspection */
+			case 'comment':
+				$pattern = '\(\)"';
+				/* Intentional fall through */
+			case 'text':
+			default:
+				// RFC 2047 section 5.1
+				// Replace every high ascii, control, =, ? and _ characters
+				$pattern = '\000-\011\013\014\016-\037\075\077\137\177-\377' . $pattern;
+				break;
+		}
+		$matches = array();
+		if ( preg_match_all( "/[{$pattern}]/", $encoded, $matches ) ) {
+			// If the string contains an '=', make sure it's the first thing we replace
+			// so as to avoid double-encoding
+			$eqkey = array_search( '=', $matches[0], true );
+			if ( false !== $eqkey ) {
+				unset( $matches[0][ $eqkey ] );
+				array_unshift( $matches[0], '=' );
+			}
+			foreach ( array_unique( $matches[0] ) as $char ) {
+				$encoded = str_replace( $char, '=' . sprintf( '%02X', ord( $char ) ), $encoded );
+			}
+		}
+		// Replace spaces with _ (more readable than =20)
+		// RFC 2047 section 4.2(2)
+		return str_replace( ' ', '_', $encoded );
+	}
+
+	/**
+	 * Add a string or binary attachment (non-filesystem).
+	 * This method can be used to attach ascii or binary data,
+	 * such as a BLOB record from a database.
+	 *
+	 * @param string $string      String attachment data
+	 * @param string $filename    Name of the attachment
+	 * @param string $encoding    File encoding (see $Encoding)
+	 * @param string $type        File extension (MIME) type
+	 * @param string $disposition Disposition to use
+	 *
+	 * @throws Exception
+	 *
+	 * @return bool True on successfully adding an attachment
+	 */
+	public function addStringAttachment(
+		$string,
+		$filename,
+		$encoding = self::ENCODING_BASE64,
+		$type = '',
+		$disposition = 'attachment'
+	) {
+		try {
+			// If a MIME type is not specified, try to work it out from the file name
+			if ( '' === $type ) {
+				$type = static::filenameToType( $filename );
+			}
+
+			if ( ! $this->validateEncoding( $encoding ) ) {
+				throw new Exception( $this->lang( 'encoding' ) . $encoding );
+			}
+
+			// Append to $attachment array
+			$this->attachment[] = array(
+				0 => $string,
+				1 => $filename,
+				2 => static::mb_pathinfo( $filename, PATHINFO_BASENAME ),
+				3 => $encoding,
+				4 => $type,
+				5 => true, // isStringAttachment
+				6 => $disposition,
+				7 => 0,
+			);
+		} catch ( Exception $exc ) {
+			$this->setError( $exc->getMessage() );
+			$this->edebug( $exc->getMessage() );
+			if ( $this->exceptions ) {
+				throw $exc;
+			}
+
+			return false;
+		}
+
+		return true;
+	}
+
+	/**
+	 * Add an embedded (inline) attachment from a file.
+	 * This can include images, sounds, and just about any other document type.
+	 * These differ from 'regular' attachments in that they are intended to be
+	 * displayed inline with the message, not just attached for download.
+	 * This is used in HTML messages that embed the images
+	 * the HTML refers to using the `$cid` value in `img` tags, for example `<img src="cid:mylogo">`.
+	 * Never use a user-supplied path to a file!
+	 *
+	 * @param string $path        Path to the attachment
+	 * @param string $cid         Content ID of the attachment; Use this to reference
+	 *                            the content when using an embedded image in HTML
+	 * @param string $name        Overrides the attachment filename
+	 * @param string $encoding    File encoding (see $Encoding) defaults to `base64`
+	 * @param string $type        File MIME type (by default mapped from the `$path` filename's extension)
+	 * @param string $disposition Disposition to use: `inline` (default) or `attachment`
+	 *                            (unlikely you want this ΓÇô {@see `addAttachment()`} instead)
+	 *
+	 * @return bool True on successfully adding an attachment
+	 * @throws Exception
+	 */
+	public function addEmbeddedImage(
+		$path,
+		$cid,
+		$name = '',
+		$encoding = self::ENCODING_BASE64,
+		$type = '',
+		$disposition = 'inline'
+	) {
+		try {
+			if ( ! static::fileIsAccessible( $path ) ) {
+				throw new Exception( $this->lang( 'file_access' ) . $path, self::STOP_CONTINUE );
+			}
+
+			// If a MIME type is not specified, try to work it out from the file name
+			if ( '' === $type ) {
+				$type = static::filenameToType( $path );
+			}
+
+			if ( ! $this->validateEncoding( $encoding ) ) {
+				throw new Exception( $this->lang( 'encoding' ) . $encoding );
+			}
+
+			$filename = (string) static::mb_pathinfo( $path, PATHINFO_BASENAME );
+			if ( '' === $name ) {
+				$name = $filename;
+			}
+
+			// Append to $attachment array
+			$this->attachment[] = array(
+				0 => $path,
+				1 => $filename,
+				2 => $name,
+				3 => $encoding,
+				4 => $type,
+				5 => false, // isStringAttachment
+				6 => $disposition,
+				7 => $cid,
+			);
+		} catch ( Exception $exc ) {
+			$this->setError( $exc->getMessage() );
+			$this->edebug( $exc->getMessage() );
+			if ( $this->exceptions ) {
+				throw $exc;
+			}
+
+			return false;
+		}
+
+		return true;
+	}
+
+	/**
+	 * Add an embedded stringified attachment.
+	 * This can include images, sounds, and just about any other document type.
+	 * If your filename doesn't contain an extension, be sure to set the $type to an appropriate MIME type.
+	 *
+	 * @param string $string      The attachment binary data
+	 * @param string $cid         Content ID of the attachment; Use this to reference
+	 *                            the content when using an embedded image in HTML
+	 * @param string $name        A filename for the attachment. If this contains an extension,
+	 *                            PHPMailer will attempt to set a MIME type for the attachment.
+	 *                            For example 'file.jpg' would get an 'image/jpeg' MIME type.
+	 * @param string $encoding    File encoding (see $Encoding), defaults to 'base64'
+	 * @param string $type        MIME type - will be used in preference to any automatically derived type
+	 * @param string $disposition Disposition to use
+	 *
+	 * @throws Exception
+	 *
+	 * @return bool True on successfully adding an attachment
+	 */
+	public function addStringEmbeddedImage(
+		$string,
+		$cid,
+		$name = '',
+		$encoding = self::ENCODING_BASE64,
+		$type = '',
+		$disposition = 'inline'
+	) {
+		try {
+			// If a MIME type is not specified, try to work it out from the name
+			if ( '' === $type && ! empty( $name ) ) {
+				$type = static::filenameToType( $name );
+			}
+
+			if ( ! $this->validateEncoding( $encoding ) ) {
+				throw new Exception( $this->lang( 'encoding' ) . $encoding );
+			}
+
+			// Append to $attachment array
+			$this->attachment[] = array(
+				0 => $string,
+				1 => $name,
+				2 => $name,
+				3 => $encoding,
+				4 => $type,
+				5 => true, // isStringAttachment
+				6 => $disposition,
+				7 => $cid,
+			);
+		} catch ( Exception $exc ) {
+			$this->setError( $exc->getMessage() );
+			$this->edebug( $exc->getMessage() );
+			if ( $this->exceptions ) {
+				throw $exc;
+			}
+
+			return false;
+		}
+
+		return true;
+	}
+
+	/**
+	 * Validate encodings.
+	 *
+	 * @param string $encoding
+	 *
+	 * @return bool
+	 */
+	protected function validateEncoding( $encoding ) {
+		return in_array(
+			$encoding,
+			array(
+				self::ENCODING_7BIT,
+				self::ENCODING_QUOTED_PRINTABLE,
+				self::ENCODING_BASE64,
+				self::ENCODING_8BIT,
+				self::ENCODING_BINARY,
+			),
+			true
+		);
+	}
+
+	/**
+	 * Check if an embedded attachment is present with this cid.
+	 *
+	 * @param string $cid
+	 *
+	 * @return bool
+	 */
+	protected function cidExists( $cid ) {
+		foreach ( $this->attachment as $attachment ) {
+			if ( 'inline' === $attachment[6] && $cid === $attachment[7] ) {
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	/**
+	 * Check if an inline attachment is present.
+	 *
+	 * @return bool
+	 */
+	public function inlineImageExists() {
+		foreach ( $this->attachment as $attachment ) {
+			if ( 'inline' === $attachment[6] ) {
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	/**
+	 * Check if an attachment (non-inline) is present.
+	 *
+	 * @return bool
+	 */
+	public function attachmentExists() {
+		foreach ( $this->attachment as $attachment ) {
+			if ( 'attachment' === $attachment[6] ) {
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	/**
+	 * Check if this message has an alternative body set.
+	 *
+	 * @return bool
+	 */
+	public function alternativeExists() {
+		return ! empty( $this->AltBody );
+	}
+
+	/**
+	 * Clear queued addresses of given kind.
+	 *
+	 * @param string $kind 'to', 'cc', or 'bcc'
+	 */
+	public function clearQueuedAddresses( $kind ) {
+		$this->RecipientsQueue = array_filter(
+			$this->RecipientsQueue,
+			static function ( $params ) use ( $kind ) {
+				return $params[0] !== $kind;
+			}
+		);
+	}
+
+	/**
+	 * Clear all To recipients.
+	 */
+	public function clearAddresses() {
+		foreach ( $this->to as $to ) {
+			unset( $this->all_recipients[ strtolower( $to[0] ) ] );
+		}
+		$this->to = array();
+		$this->clearQueuedAddresses( 'to' );
+	}
+
+	/**
+	 * Clear all CC recipients.
+	 */
+	public function clearCCs() {
+		foreach ( $this->cc as $cc ) {
+			unset( $this->all_recipients[ strtolower( $cc[0] ) ] );
+		}
+		$this->cc = array();
+		$this->clearQueuedAddresses( 'cc' );
+	}
+
+	/**
+	 * Clear all BCC recipients.
+	 */
+	public function clearBCCs() {
+		foreach ( $this->bcc as $bcc ) {
+			unset( $this->all_recipients[ strtolower( $bcc[0] ) ] );
+		}
+		$this->bcc = array();
+		$this->clearQueuedAddresses( 'bcc' );
+	}
+
+	/**
+	 * Clear all ReplyTo recipients.
+	 */
+	public function clearReplyTos() {
+		$this->ReplyTo      = array();
+		$this->ReplyToQueue = array();
+	}
+
+	/**
+	 * Clear all recipient types.
+	 */
+	public function clearAllRecipients() {
+		$this->to              = array();
+		$this->cc              = array();
+		$this->bcc             = array();
+		$this->all_recipients  = array();
+		$this->RecipientsQueue = array();
+	}
+
+	/**
+	 * Clear all filesystem, string, and binary attachments.
+	 */
+	public function clearAttachments() {
+		$this->attachment = array();
+	}
+
+	/**
+	 * Clear all custom headers.
+	 */
+	public function clearCustomHeaders() {
+		$this->CustomHeader = array();
+	}
+
+	/**
+	 * Clear a specific custom header by name or name and value.
+	 * $name value can be overloaded to contain
+	 * both header name and value (name:value).
+	 *
+	 * @param string      $name  Custom header name
+	 * @param string|null $value Header value
+	 *
+	 * @return bool True if a header was replaced successfully
+	 */
+	public function clearCustomHeader( $name, $value = null ) {
+		if ( null === $value && strpos( $name, ':' ) !== false ) {
+			// Value passed in as name:value
+			list($name, $value) = explode( ':', $name, 2 );
+		}
+		$name  = trim( $name );
+		$value = ( null === $value ) ? null : trim( $value );
+
+		foreach ( $this->CustomHeader as $k => $pair ) {
+			if ( $pair[0] == $name ) {
+				// We remove the header if the value is not provided or it matches.
+				if ( null === $value || $pair[1] == $value ) {
+					unset( $this->CustomHeader[ $k ] );
+				}
+			}
+		}
+
+		return true;
+	}
+
+	/**
+	 * Replace a custom header.
+	 * $name value can be overloaded to contain
+	 * both header name and value (name:value).
+	 *
+	 * @param string      $name  Custom header name
+	 * @param string|null $value Header value
+	 *
+	 * @return bool True if a header was replaced successfully
+	 * @throws Exception
+	 */
+	public function replaceCustomHeader( $name, $value = null ) {
+		if ( null === $value && strpos( $name, ':' ) !== false ) {
+			// Value passed in as name:value
+			list($name, $value) = explode( ':', $name, 2 );
+		}
+		$name  = trim( $name );
+		$value = ( null === $value ) ? '' : trim( $value );
+
+		$replaced = false;
+		foreach ( $this->CustomHeader as $k => $pair ) {
+			if ( $pair[0] == $name ) {
+				if ( $replaced ) {
+					unset( $this->CustomHeader[ $k ] );
+					continue;
+				}
+				if ( strpbrk( $name . $value, "\r\n" ) !== false ) {
+					if ( $this->exceptions ) {
+						throw new Exception( $this->lang( 'invalid_header' ) );
+					}
+
+					return false;
+				}
+				$this->CustomHeader[ $k ] = array( $name, $value );
+				$replaced                 = true;
+			}
+		}
+
+		return true;
+	}
+
+	/**
+	 * Add an error message to the error container.
+	 *
+	 * @param string $msg
+	 */
+	protected function setError( $msg ) {
+		++$this->error_count;
+		if ( 'smtp' === $this->Mailer && null !== $this->smtp ) {
+			$lasterror = $this->smtp->getError();
+			if ( ! empty( $lasterror['error'] ) ) {
+				$msg .= $this->lang( 'smtp_error' ) . $lasterror['error'];
+				if ( ! empty( $lasterror['detail'] ) ) {
+					$msg .= ' ' . $this->lang( 'smtp_detail' ) . $lasterror['detail'];
+				}
+				if ( ! empty( $lasterror['smtp_code'] ) ) {
+					$msg .= ' ' . $this->lang( 'smtp_code' ) . $lasterror['smtp_code'];
+				}
+				if ( ! empty( $lasterror['smtp_code_ex'] ) ) {
+					$msg .= ' ' . $this->lang( 'smtp_code_ex' ) . $lasterror['smtp_code_ex'];
+				}
+			}
+		}
+		$this->ErrorInfo = $msg;
+	}
+
+	/**
+	 * Return an RFC 822 formatted date.
+	 *
+	 * @return string
+	 */
+	public static function rfcDate() {
+		// Set the time zone to whatever the default is to avoid 500 errors
+		// Will default to UTC if it's not set properly in php.ini
+		date_default_timezone_set( @date_default_timezone_get() );
+
+		return date( 'D, j M Y H:i:s O' );
+	}
+
+	/**
+	 * Get the server hostname.
+	 * Returns 'localhost.localdomain' if unknown.
+	 *
+	 * @return string
+	 */
+	protected function serverHostname() {
+		$result = '';
+		if ( ! empty( $this->Hostname ) ) {
+			$result = $this->Hostname;
+		} elseif ( isset( $_SERVER ) && array_key_exists( 'SERVER_NAME', $_SERVER ) ) {
+			$result = $_SERVER['SERVER_NAME'];
+		} elseif ( function_exists( 'gethostname' ) && gethostname() !== false ) {
+			$result = gethostname();
+		} elseif ( php_uname( 'n' ) !== '' ) {
+			$result = php_uname( 'n' );
+		}
+		if ( ! static::isValidHost( $result ) ) {
+			return 'localhost.localdomain';
+		}
+
+		return $result;
+	}
+
+	/**
+	 * Validate whether a string contains a valid value to use as a hostname or IP address.
+	 * IPv6 addresses must include [], e.g. `[::1]`, not just `::1`.
+	 *
+	 * @param string $host The host name or IP address to check
+	 *
+	 * @return bool
+	 */
+	public static function isValidHost( $host ) {
+		// Simple syntax limits
+		if (
+			empty( $host )
+			|| ! is_string( $host )
+			|| strlen( $host ) > 256
+			|| ! preg_match( '/^([a-z\d.-]*|\[[a-f\d:]+\])$/i', $host )
+		) {
+			return false;
+		}
+		// Looks like a bracketed IPv6 address
+		if ( strlen( $host ) > 2 && substr( $host, 0, 1 ) === '[' && substr( $host, -1, 1 ) === ']' ) {
+			return filter_var( substr( $host, 1, -1 ), FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) !== false;
+		}
+		// If removing all the dots results in a numeric string, it must be an IPv4 address.
+		// Need to check this first because otherwise things like `999.0.0.0` are considered valid host names
+		if ( is_numeric( str_replace( '.', '', $host ) ) ) {
+			// Is it a valid IPv4 address?
+			return filter_var( $host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) !== false;
+		}
+		// Is it a syntactically valid hostname (when embedded in a URL)?
+		return filter_var( 'https://' . $host, FILTER_VALIDATE_URL ) !== false;
+	}
+
+	/**
+	 * Get an error message in the current language.
+	 *
+	 * @param string $key
+	 *
+	 * @return string
+	 */
+	protected function lang( $key ) {
+		if ( count( $this->language ) < 1 ) {
+			$this->setLanguage(); // Set the default language
+		}
+
+		if ( array_key_exists( $key, $this->language ) ) {
+			if ( 'smtp_connect_failed' === $key ) {
+				// Include a link to troubleshooting docs on SMTP connection failure.
+				// This is by far the biggest cause of support questions
+				// but it's usually not PHPMailer's fault.
+				return $this->language[ $key ] . ' https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting';
+			}
+
+			return $this->language[ $key ];
+		}
+
+		// Return the key as a fallback
+		return $key;
+	}
+
+	/**
+	 * Build an error message starting with a generic one and adding details if possible.
+	 *
+	 * @param string $base_key
+	 * @return string
+	 */
+	private function getSmtpErrorMessage( $base_key ) {
+		$message = $this->lang( $base_key );
+		$error   = $this->smtp->getError();
+		if ( ! empty( $error['error'] ) ) {
+			$message .= ' ' . $error['error'];
+			if ( ! empty( $error['detail'] ) ) {
+				$message .= ' ' . $error['detail'];
+			}
+		}
+
+		return $message;
+	}
+
+	/**
+	 * Check if an error occurred.
+	 *
+	 * @return bool True if an error did occur
+	 */
+	public function isError() {
+		return $this->error_count > 0;
+	}
+
+	/**
+	 * Add a custom header.
+	 * $name value can be overloaded to contain
+	 * both header name and value (name:value).
+	 *
+	 * @param string      $name  Custom header name
+	 * @param string|null $value Header value
+	 *
+	 * @return bool True if a header was set successfully
+	 * @throws Exception
+	 */
+	public function addCustomHeader( $name, $value = null ) {
+		if ( null === $value && strpos( $name, ':' ) !== false ) {
+			// Value passed in as name:value
+			list($name, $value) = explode( ':', $name, 2 );
+		}
+		$name  = trim( $name );
+		$value = ( null === $value ) ? '' : trim( $value );
+		// Ensure name is not empty, and that neither name nor value contain line breaks
+		if ( empty( $name ) || strpbrk( $name . $value, "\r\n" ) !== false ) {
+			if ( $this->exceptions ) {
+				throw new Exception( $this->lang( 'invalid_header' ) );
+			}
+
+			return false;
+		}
+		$this->CustomHeader[] = array( $name, $value );
+
+		return true;
+	}
+
+	/**
+	 * Returns all custom headers.
+	 *
+	 * @return array
+	 */
+	public function getCustomHeaders() {
+		return $this->CustomHeader;
+	}
+
+	/**
+	 * Create a message body from an HTML string.
+	 * Automatically inlines images and creates a plain-text version by converting the HTML,
+	 * overwriting any existing values in Body and AltBody.
+	 * Do not source $message content from user input!
+	 * $basedir is prepended when handling relative URLs, e.g. <img src="/images/a.png"> and must not be empty
+	 * will look for an image file in $basedir/images/a.png and convert it to inline.
+	 * If you don't provide a $basedir, relative paths will be left untouched (and thus probably break in email)
+	 * Converts data-uri images into embedded attachments.
+	 * If you don't want to apply these transformations to your HTML, just set Body and AltBody directly.
+	 *
+	 * @param string        $message  HTML message string
+	 * @param string        $basedir  Absolute path to a base directory to prepend to relative paths to images
+	 * @param bool|callable $advanced Whether to use the internal HTML to text converter
+	 *                                or your own custom converter
+	 * @return string The transformed message body
+	 *
+	 * @throws Exception
+	 *
+	 * @see PHPMailer::html2text()
+	 */
+	public function msgHTML( $message, $basedir = '', $advanced = false ) {
+		preg_match_all( '/(?<!-)(src|background)=["\'](.*)["\']/Ui', $message, $images );
+		if ( array_key_exists( 2, $images ) ) {
+			if ( strlen( $basedir ) > 1 && '/' !== substr( $basedir, -1 ) ) {
+				// Ensure $basedir has a trailing /
+				$basedir .= '/';
+			}
+			foreach ( $images[2] as $imgindex => $url ) {
+				// Convert data URIs into embedded images
+				// e.g. "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
+				$match = array();
+				if ( preg_match( '#^data:(image/(?:jpe?g|gif|png));?(base64)?,(.+)#', $url, $match ) ) {
+					if ( count( $match ) === 4 && static::ENCODING_BASE64 === $match[2] ) {
+						$data = base64_decode( $match[3] );
+					} elseif ( '' === $match[2] ) {
+						$data = rawurldecode( $match[3] );
+					} else {
+						// Not recognised so leave it alone
+						continue;
+					}
+					// Hash the decoded data, not the URL, so that the same data-URI image used in multiple places
+					// will only be embedded once, even if it used a different encoding
+					$cid = substr( hash( 'sha256', $data ), 0, 32 ) . '@phpmailer.0'; // RFC2392 S 2
+
+					if ( ! $this->cidExists( $cid ) ) {
+						$this->addStringEmbeddedImage(
+							$data,
+							$cid,
+							'embed' . $imgindex,
+							static::ENCODING_BASE64,
+							$match[1]
+						);
+					}
+					$message = str_replace(
+						$images[0][ $imgindex ],
+						$images[1][ $imgindex ] . '="cid:' . $cid . '"',
+						$message
+					);
+					continue;
+				}
+				if (
+					// Only process relative URLs if a basedir is provided (i.e. no absolute local paths)
+					! empty( $basedir )
+					// Ignore URLs containing parent dir traversal (..)
+					&& ( strpos( $url, '..' ) === false )
+					// Do not change urls that are already inline images
+					&& 0 !== strpos( $url, 'cid:' )
+					// Do not change absolute URLs, including anonymous protocol
+					&& ! preg_match( '#^[a-z][a-z0-9+.-]*:?//#i', $url )
+				) {
+					$filename  = static::mb_pathinfo( $url, PATHINFO_BASENAME );
+					$directory = dirname( $url );
+					if ( '.' === $directory ) {
+						$directory = '';
+					}
+					// RFC2392 S 2
+					$cid = substr( hash( 'sha256', $url ), 0, 32 ) . '@phpmailer.0';
+					if ( strlen( $basedir ) > 1 && '/' !== substr( $basedir, -1 ) ) {
+						$basedir .= '/';
+					}
+					if ( strlen( $directory ) > 1 && '/' !== substr( $directory, -1 ) ) {
+						$directory .= '/';
+					}
+					if (
+						$this->addEmbeddedImage(
+							$basedir . $directory . $filename,
+							$cid,
+							$filename,
+							static::ENCODING_BASE64,
+							static::_mime_types( (string) static::mb_pathinfo( $filename, PATHINFO_EXTENSION ) )
+						)
+					) {
+						$message = preg_replace(
+							'/' . $images[1][ $imgindex ] . '=["\']' . preg_quote( $url, '/' ) . '["\']/Ui',
+							$images[1][ $imgindex ] . '="cid:' . $cid . '"',
+							$message
+						);
+					}
+				}
+			}
+		}
+		$this->isHTML();
+		// Convert all message body line breaks to LE, makes quoted-printable encoding work much better
+		$this->Body    = static::normalizeBreaks( $message );
+		$this->AltBody = static::normalizeBreaks( $this->html2text( $message, $advanced ) );
+		if ( ! $this->alternativeExists() ) {
+			$this->AltBody = 'This is an HTML-only message. To view it, activate HTML in your email application.'
+				. static::$LE;
+		}
+
+		return $this->Body;
+	}
+
+	/**
+	 * Convert an HTML string into plain text.
+	 * This is used by msgHTML().
+	 * Note - older versions of this function used a bundled advanced converter
+	 * which was removed for license reasons in #232.
+	 * Example usage:
+	 *
+	 * ```php
+	 * //Use default conversion
+	 * $plain = $mail->html2text($html);
+	 * //Use your own custom converter
+	 * $plain = $mail->html2text($html, function($html) {
+	 *     $converter = new MyHtml2text($html);
+	 *     return $converter->get_text();
+	 * });
+	 * ```
+	 *
+	 * @param string        $html     The HTML text to convert
+	 * @param bool|callable $advanced Any boolean value to use the internal converter,
+	 *                                or provide your own callable for custom conversion.
+	 *                                *Never* pass user-supplied data into this parameter
+	 *
+	 * @return string
+	 */
+	public function html2text( $html, $advanced = false ) {
+		if ( is_callable( $advanced ) ) {
+			return call_user_func( $advanced, $html );
+		}
+
+		return html_entity_decode(
+			trim( wp_strip_all_tags( preg_replace( '/<(head|title|style|script)[^>]*>.*?<\/\\1>/si', '', $html ) ) ),
+			ENT_QUOTES,
+			$this->CharSet
+		);
+	}
+
+	/**
+	 * Get the MIME type for a file extension.
+	 *
+	 * @param string $ext File extension
+	 *
+	 * @return string MIME type of file
+	 */
+	public static function _mime_types( $ext = '' ) {
+		$mimes = array(
+			'xl'    => 'application/excel',
+			'js'    => 'application/javascript',
+			'hqx'   => 'application/mac-binhex40',
+			'cpt'   => 'application/mac-compactpro',
+			'bin'   => 'application/macbinary',
+			'doc'   => 'application/msword',
+			'word'  => 'application/msword',
+			'xlsx'  => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+			'xltx'  => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
+			'potx'  => 'application/vnd.openxmlformats-officedocument.presentationml.template',
+			'ppsx'  => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
+			'pptx'  => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
+			'sldx'  => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
+			'docx'  => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+			'dotx'  => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
+			'xlam'  => 'application/vnd.ms-excel.addin.macroEnabled.12',
+			'xlsb'  => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
+			'class' => 'application/octet-stream',
+			'dll'   => 'application/octet-stream',
+			'dms'   => 'application/octet-stream',
+			'exe'   => 'application/octet-stream',
+			'lha'   => 'application/octet-stream',
+			'lzh'   => 'application/octet-stream',
+			'psd'   => 'application/octet-stream',
+			'sea'   => 'application/octet-stream',
+			'so'    => 'application/octet-stream',
+			'oda'   => 'application/oda',
+			'pdf'   => 'application/pdf',
+			'ai'    => 'application/postscript',
+			'eps'   => 'application/postscript',
+			'ps'    => 'application/postscript',
+			'smi'   => 'application/smil',
+			'smil'  => 'application/smil',
+			'mif'   => 'application/vnd.mif',
+			'xls'   => 'application/vnd.ms-excel',
+			'ppt'   => 'application/vnd.ms-powerpoint',
+			'wbxml' => 'application/vnd.wap.wbxml',
+			'wmlc'  => 'application/vnd.wap.wmlc',
+			'dcr'   => 'application/x-director',
+			'dir'   => 'application/x-director',
+			'dxr'   => 'application/x-director',
+			'dvi'   => 'application/x-dvi',
+			'gtar'  => 'application/x-gtar',
+			'php3'  => 'application/x-httpd-php',
+			'php4'  => 'application/x-httpd-php',
+			'php'   => 'application/x-httpd-php',
+			'phtml' => 'application/x-httpd-php',
+			'phps'  => 'application/x-httpd-php-source',
+			'swf'   => 'application/x-shockwave-flash',
+			'sit'   => 'application/x-stuffit',
+			'tar'   => 'application/x-tar',
+			'tgz'   => 'application/x-tar',
+			'xht'   => 'application/xhtml+xml',
+			'xhtml' => 'application/xhtml+xml',
+			'zip'   => 'application/zip',
+			'mid'   => 'audio/midi',
+			'midi'  => 'audio/midi',
+			'mp2'   => 'audio/mpeg',
+			'mp3'   => 'audio/mpeg',
+			'm4a'   => 'audio/mp4',
+			'mpga'  => 'audio/mpeg',
+			'aif'   => 'audio/x-aiff',
+			'aifc'  => 'audio/x-aiff',
+			'aiff'  => 'audio/x-aiff',
+			'ram'   => 'audio/x-pn-realaudio',
+			'rm'    => 'audio/x-pn-realaudio',
+			'rpm'   => 'audio/x-pn-realaudio-plugin',
+			'ra'    => 'audio/x-realaudio',
+			'wav'   => 'audio/x-wav',
+			'mka'   => 'audio/x-matroska',
+			'bmp'   => 'image/bmp',
+			'gif'   => 'image/gif',
+			'jpeg'  => 'image/jpeg',
+			'jpe'   => 'image/jpeg',
+			'jpg'   => 'image/jpeg',
+			'png'   => 'image/png',
+			'tiff'  => 'image/tiff',
+			'tif'   => 'image/tiff',
+			'webp'  => 'image/webp',
+			'avif'  => 'image/avif',
+			'heif'  => 'image/heif',
+			'heifs' => 'image/heif-sequence',
+			'heic'  => 'image/heic',
+			'heics' => 'image/heic-sequence',
+			'eml'   => 'message/rfc822',
+			'css'   => 'text/css',
+			'html'  => 'text/html',
+			'htm'   => 'text/html',
+			'shtml' => 'text/html',
+			'log'   => 'text/plain',
+			'text'  => 'text/plain',
+			'txt'   => 'text/plain',
+			'rtx'   => 'text/richtext',
+			'rtf'   => 'text/rtf',
+			'vcf'   => 'text/vcard',
+			'vcard' => 'text/vcard',
+			'ics'   => 'text/calendar',
+			'xml'   => 'text/xml',
+			'xsl'   => 'text/xml',
+			'csv'   => 'text/csv',
+			'wmv'   => 'video/x-ms-wmv',
+			'mpeg'  => 'video/mpeg',
+			'mpe'   => 'video/mpeg',
+			'mpg'   => 'video/mpeg',
+			'mp4'   => 'video/mp4',
+			'm4v'   => 'video/mp4',
+			'mov'   => 'video/quicktime',
+			'qt'    => 'video/quicktime',
+			'rv'    => 'video/vnd.rn-realvideo',
+			'avi'   => 'video/x-msvideo',
+			'movie' => 'video/x-sgi-movie',
+			'webm'  => 'video/webm',
+			'mkv'   => 'video/x-matroska',
+		);
+		$ext   = strtolower( $ext );
+		if ( array_key_exists( $ext, $mimes ) ) {
+			return $mimes[ $ext ];
+		}
+
+		return 'application/octet-stream';
+	}
+
+	/**
+	 * Map a file name to a MIME type.
+	 * Defaults to 'application/octet-stream', i.e.. arbitrary binary data.
+	 *
+	 * @param string $filename A file name or full path, does not need to exist as a file
+	 *
+	 * @return string
+	 */
+	public static function filenameToType( $filename ) {
+		// In case the path is a URL, strip any query string before getting extension
+		$qpos = strpos( $filename, '?' );
+		if ( false !== $qpos ) {
+			$filename = substr( $filename, 0, $qpos );
+		}
+		$ext = static::mb_pathinfo( $filename, PATHINFO_EXTENSION );
+
+		return static::_mime_types( $ext );
+	}
+
+	/**
+	 * Multi-byte-safe pathinfo replacement.
+	 * Drop-in replacement for pathinfo(), but multibyte- and cross-platform-safe.
+	 *
+	 * @see https://www.php.net/manual/en/function.pathinfo.php#107461
+	 *
+	 * @param string     $path    A filename or path, does not need to exist as a file
+	 * @param int|string $options Either a PATHINFO_* constant,
+	 *                            or a string name to return only the specified piece
+	 *
+	 * @return string|array
+	 */
+	public static function mb_pathinfo( $path, $options = null ) {
+		$ret      = array(
+			'dirname'   => '',
+			'basename'  => '',
+			'extension' => '',
+			'filename'  => '',
+		);
+		$pathinfo = array();
+		if ( preg_match( '#^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^.\\\\/]+?)|))[\\\\/.]*$#m', $path, $pathinfo ) ) {
+			if ( array_key_exists( 1, $pathinfo ) ) {
+				$ret['dirname'] = $pathinfo[1];
+			}
+			if ( array_key_exists( 2, $pathinfo ) ) {
+				$ret['basename'] = $pathinfo[2];
+			}
+			if ( array_key_exists( 5, $pathinfo ) ) {
+				$ret['extension'] = $pathinfo[5];
+			}
+			if ( array_key_exists( 3, $pathinfo ) ) {
+				$ret['filename'] = $pathinfo[3];
+			}
+		}
+		switch ( $options ) {
+			case PATHINFO_DIRNAME:
+			case 'dirname':
+				return $ret['dirname'];
+			case PATHINFO_BASENAME:
+			case 'basename':
+				return $ret['basename'];
+			case PATHINFO_EXTENSION:
+			case 'extension':
+				return $ret['extension'];
+			case PATHINFO_FILENAME:
+			case 'filename':
+				return $ret['filename'];
+			default:
+				return $ret;
+		}
+	}
+
+	/**
+	 * Set or reset instance properties.
+	 * You should avoid this function - it's more verbose, less efficient, more error-prone and
+	 * harder to debug than setting properties directly.
+	 * Usage Example:
+	 * `$mail->set('SMTPSecure', static::ENCRYPTION_STARTTLS);`
+	 *   is the same as:
+	 * `$mail->SMTPSecure = static::ENCRYPTION_STARTTLS;`.
+	 *
+	 * @param string $name  The property name to set
+	 * @param mixed  $value The value to set the property to
+	 *
+	 * @return bool
+	 */
+	public function set( $name, $value = '' ) {
+		if ( property_exists( $this, $name ) ) {
+			$this->{$name} = $value;
+
+			return true;
+		}
+		$this->setError( $this->lang( 'variable_set' ) . $name );
+
+		return false;
+	}
+
+	/**
+	 * Strip newlines to prevent header injection.
+	 *
+	 * @param string $str
+	 *
+	 * @return string
+	 */
+	public function secureHeader( $str ) {
+		return trim( str_replace( array( "\r", "\n" ), '', $str ) );
+	}
+
+	/**
+	 * Normalize line breaks in a string.
+	 * Converts UNIX LF, Mac CR and Windows CRLF line breaks into a single line break format.
+	 * Defaults to CRLF (for message bodies) and preserves consecutive breaks.
+	 *
+	 * @param string $text
+	 * @param string $breaktype What kind of line break to use; defaults to static::$LE
+	 *
+	 * @return string
+	 */
+	public static function normalizeBreaks( $text, $breaktype = null ) {
+		if ( null === $breaktype ) {
+			$breaktype = static::$LE;
+		}
+		// Normalise to \n
+		$text = str_replace( array( self::CRLF, "\r" ), "\n", $text );
+		// Now convert LE as needed
+		if ( "\n" !== $breaktype ) {
+			$text = str_replace( "\n", $breaktype, $text );
+		}
+
+		return $text;
+	}
+
+	/**
+	 * Remove trailing whitespace from a string.
+	 *
+	 * @param string $text
+	 *
+	 * @return string The text to remove whitespace from
+	 */
+	public static function stripTrailingWSP( $text ) {
+		return rtrim( $text, " \r\n\t" );
+	}
+
+	/**
+	 * Strip trailing line breaks from a string.
+	 *
+	 * @param string $text
+	 *
+	 * @return string The text to remove breaks from
+	 */
+	public static function stripTrailingBreaks( $text ) {
+		return rtrim( $text, "\r\n" );
+	}
+
+	/**
+	 * Return the current line break format string.
+	 *
+	 * @return string
+	 */
+	public static function getLE() {
+		return static::$LE;
+	}
+
+	/**
+	 * Set the line break format string, e.g. "\r\n".
+	 *
+	 * @param string $le
+	 */
+	protected static function setLE( $le ) {
+		static::$LE = $le;
+	}
+
+	/**
+	 * Set the public and private key files and password for S/MIME signing.
+	 *
+	 * @param string $cert_filename
+	 * @param string $key_filename
+	 * @param string $key_pass            Password for private key
+	 * @param string $extracerts_filename Optional path to chain certificate
+	 */
+	public function sign( $cert_filename, $key_filename, $key_pass, $extracerts_filename = '' ) {
+		$this->sign_cert_file       = $cert_filename;
+		$this->sign_key_file        = $key_filename;
+		$this->sign_key_pass        = $key_pass;
+		$this->sign_extracerts_file = $extracerts_filename;
+	}
+
+	/**
+	 * Quoted-Printable-encode a DKIM header.
+	 *
+	 * @param string $txt
+	 *
+	 * @return string
+	 */
+	public function DKIM_QP( $txt ) {
+		$line = '';
+		$len  = strlen( $txt );
+		for ( $i = 0; $i < $len; ++$i ) {
+			$ord = ord( $txt[ $i ] );
+			if ( ( ( 0x21 <= $ord ) && ( $ord <= 0x3A ) ) || $ord === 0x3C || ( ( 0x3E <= $ord ) && ( $ord <= 0x7E ) ) ) {
+				$line .= $txt[ $i ];
+			} else {
+				$line .= '=' . sprintf( '%02X', $ord );
+			}
+		}
+
+		return $line;
+	}
+
+	/**
+	 * Generate a DKIM signature.
+	 *
+	 * @param string $signHeader
+	 *
+	 * @throws Exception
+	 *
+	 * @return string The DKIM signature value
+	 */
+	public function DKIM_Sign( $signHeader ) {
+		if ( ! defined( 'PKCS7_TEXT' ) ) {
+			if ( $this->exceptions ) {
+				throw new Exception( $this->lang( 'extension_missing' ) . 'openssl' );
+			}
+
+			return '';
+		}
+		$privKeyStr = ! empty( $this->DKIM_private_string ) ?
+			$this->DKIM_private_string :
+			file_get_contents( $this->DKIM_private );
+		if ( '' !== $this->DKIM_passphrase ) {
+			$privKey = openssl_pkey_get_private( $privKeyStr, $this->DKIM_passphrase );
+		} else {
+			$privKey = openssl_pkey_get_private( $privKeyStr );
+		}
+		if ( openssl_sign( $signHeader, $signature, $privKey, 'sha256WithRSAEncryption' ) ) {
+			if ( \PHP_MAJOR_VERSION < 8 ) {
+				openssl_pkey_free( $privKey );
+			}
+
+			return base64_encode( $signature );
+		}
+		if ( \PHP_MAJOR_VERSION < 8 ) {
+			openssl_pkey_free( $privKey );
+		}
+
+		return '';
+	}
+
+	/**
+	 * Generate a DKIM canonicalization header.
+	 * Uses the 'relaxed' algorithm from RFC6376 section 3.4.2.
+	 * Canonicalized headers should *always* use CRLF, regardless of mailer setting.
+	 *
+	 * @see https://www.rfc-editor.org/rfc/rfc6376#section-3.4.2
+	 *
+	 * @param string $signHeader Header
+	 *
+	 * @return string
+	 */
+	public function DKIM_HeaderC( $signHeader ) {
+		// Normalize breaks to CRLF (regardless of the mailer)
+		$signHeader = static::normalizeBreaks( $signHeader, self::CRLF );
+		// Unfold header lines
+		// Note PCRE \s is too broad a definition of whitespace; RFC5322 defines it as `[ \t]`
+		// @see https://www.rfc-editor.org/rfc/rfc5322#section-2.2
+		// That means this may break if you do something daft like put vertical tabs in your headers.
+		$signHeader = preg_replace( '/\r\n[ \t]+/', ' ', $signHeader );
+		// Break headers out into an array
+		$lines = explode( self::CRLF, $signHeader );
+		foreach ( $lines as $key => $line ) {
+			// If the header is missing a :, skip it as it's invalid
+			// This is likely to happen because the explode() above will also split
+			// on the trailing LE, leaving an empty line
+			if ( strpos( $line, ':' ) === false ) {
+				continue;
+			}
+			list($heading, $value) = explode( ':', $line, 2 );
+			// Lower-case header name
+			$heading = strtolower( $heading );
+			// Collapse white space within the value, also convert WSP to space
+			$value = preg_replace( '/[ \t]+/', ' ', $value );
+			// RFC6376 is slightly unclear here - it says to delete space at the *end* of each value
+			// But then says to delete space before and after the colon.
+			// Net result is the same as trimming both ends of the value.
+			// By elimination, the same applies to the field name
+			$lines[ $key ] = trim( $heading, " \t" ) . ':' . trim( $value, " \t" );
+		}
+
+		return implode( self::CRLF, $lines );
+	}
+
+	/**
+	 * Generate a DKIM canonicalization body.
+	 * Uses the 'simple' algorithm from RFC6376 section 3.4.3.
+	 * Canonicalized bodies should *always* use CRLF, regardless of mailer setting.
+	 *
+	 * @see https://www.rfc-editor.org/rfc/rfc6376#section-3.4.3
+	 *
+	 * @param string $body Message Body
+	 *
+	 * @return string
+	 */
+	public function DKIM_BodyC( $body ) {
+		if ( empty( $body ) ) {
+			return self::CRLF;
+		}
+		// Normalize line endings to CRLF
+		$body = static::normalizeBreaks( $body, self::CRLF );
+
+		// Reduce multiple trailing line breaks to a single one
+		return static::stripTrailingBreaks( $body ) . self::CRLF;
+	}
+
+	/**
+	 * Create the DKIM header and body in a new message header.
+	 *
+	 * @param string $headers_line Header lines
+	 * @param string $subject      Subject
+	 * @param string $body         Body
+	 *
+	 * @throws Exception
+	 *
+	 * @return string
+	 */
+	public function DKIM_Add( $headers_line, $subject, $body ) {
+		$DKIMsignatureType    = 'rsa-sha256'; // Signature & hash algorithms
+		$DKIMcanonicalization = 'relaxed/simple'; // Canonicalization methods of header & body
+		$DKIMquery            = 'dns/txt'; // Query method
+		$DKIMtime             = time();
+		// Always sign these headers without being asked
+		// Recommended list from https://www.rfc-editor.org/rfc/rfc6376#section-5.4.1
+		$autoSignHeaders = array(
+			'from',
+			'to',
+			'cc',
+			'date',
+			'subject',
+			'reply-to',
+			'message-id',
+			'content-type',
+			'mime-version',
+			'x-mailer',
+		);
+		if ( stripos( $headers_line, 'Subject' ) === false ) {
+			$headers_line .= 'Subject: ' . $subject . static::$LE;
+		}
+		$headerLines        = explode( static::$LE, $headers_line );
+		$currentHeaderLabel = '';
+		$currentHeaderValue = '';
+		$parsedHeaders      = array();
+		$headerLineIndex    = 0;
+		$headerLineCount    = count( $headerLines );
+		foreach ( $headerLines as $headerLine ) {
+			$matches = array();
+			if ( preg_match( '/^([^ \t]*?)(?::[ \t]*)(.*)$/', $headerLine, $matches ) ) {
+				if ( $currentHeaderLabel !== '' ) {
+					// We were previously in another header; This is the start of a new header, so save the previous one
+					$parsedHeaders[] = array(
+						'label' => $currentHeaderLabel,
+						'value' => $currentHeaderValue,
+					);
+				}
+				$currentHeaderLabel = $matches[1];
+				$currentHeaderValue = $matches[2];
+			} elseif ( preg_match( '/^[ \t]+(.*)$/', $headerLine, $matches ) ) {
+				// This is a folded continuation of the current header, so unfold it
+				$currentHeaderValue .= ' ' . $matches[1];
+			}
+			++$headerLineIndex;
+			if ( $headerLineIndex >= $headerLineCount ) {
+				// This was the last line, so finish off this header
+				$parsedHeaders[] = array(
+					'label' => $currentHeaderLabel,
+					'value' => $currentHeaderValue,
+				);
+			}
+		}
+		$copiedHeaders     = array();
+		$headersToSignKeys = array();
+		$headersToSign     = array();
+		foreach ( $parsedHeaders as $header ) {
+			// Is this header one that must be included in the DKIM signature?
+			if ( in_array( strtolower( $header['label'] ), $autoSignHeaders, true ) ) {
+				$headersToSignKeys[] = $header['label'];
+				$headersToSign[]     = $header['label'] . ': ' . $header['value'];
+				if ( $this->DKIM_copyHeaderFields ) {
+					$copiedHeaders[] = $header['label'] . ':' . // Note no space after this, as per RFC
+						str_replace( '|', '=7C', $this->DKIM_QP( $header['value'] ) );
+				}
+				continue;
+			}
+			// Is this an extra custom header we've been asked to sign?
+			if ( in_array( $header['label'], $this->DKIM_extraHeaders, true ) ) {
+				// Find its value in custom headers
+				foreach ( $this->CustomHeader as $customHeader ) {
+					if ( $customHeader[0] === $header['label'] ) {
+						$headersToSignKeys[] = $header['label'];
+						$headersToSign[]     = $header['label'] . ': ' . $header['value'];
+						if ( $this->DKIM_copyHeaderFields ) {
+							$copiedHeaders[] = $header['label'] . ':' . // Note no space after this, as per RFC
+								str_replace( '|', '=7C', $this->DKIM_QP( $header['value'] ) );
+						}
+						// Skip straight to the next header
+						continue 2;
+					}
+				}
+			}
+		}
+		$copiedHeaderFields = '';
+		if ( $this->DKIM_copyHeaderFields && count( $copiedHeaders ) > 0 ) {
+			// Assemble a DKIM 'z' tag
+			$copiedHeaderFields = ' z=';
+			$first              = true;
+			foreach ( $copiedHeaders as $copiedHeader ) {
+				if ( ! $first ) {
+					$copiedHeaderFields .= static::$LE . ' |';
+				}
+				// Fold long values
+				if ( strlen( $copiedHeader ) > self::STD_LINE_LENGTH - 3 ) {
+					$copiedHeaderFields .= substr(
+						chunk_split( $copiedHeader, self::STD_LINE_LENGTH - 3, static::$LE . self::FWS ),
+						0,
+						-strlen( static::$LE . self::FWS )
+					);
+				} else {
+					$copiedHeaderFields .= $copiedHeader;
+				}
+				$first = false;
+			}
+			$copiedHeaderFields .= ';' . static::$LE;
+		}
+		$headerKeys   = ' h=' . implode( ':', $headersToSignKeys ) . ';' . static::$LE;
+		$headerValues = implode( static::$LE, $headersToSign );
+		$body         = $this->DKIM_BodyC( $body );
+		// Base64 of packed binary SHA-256 hash of body
+		$DKIMb64 = base64_encode( pack( 'H*', hash( 'sha256', $body ) ) );
+		$ident   = '';
+		if ( '' !== $this->DKIM_identity ) {
+			$ident = ' i=' . $this->DKIM_identity . ';' . static::$LE;
+		}
+		// The DKIM-Signature header is included in the signature *except for* the value of the `b` tag
+		// which is appended after calculating the signature
+		// https://www.rfc-editor.org/rfc/rfc6376#section-3.5
+		$dkimSignatureHeader = 'DKIM-Signature: v=1;' .
+			' d=' . $this->DKIM_domain . ';' .
+			' s=' . $this->DKIM_selector . ';' . static::$LE .
+			' a=' . $DKIMsignatureType . ';' .
+			' q=' . $DKIMquery . ';' .
+			' t=' . $DKIMtime . ';' .
+			' c=' . $DKIMcanonicalization . ';' . static::$LE .
+			$headerKeys .
+			$ident .
+			$copiedHeaderFields .
+			' bh=' . $DKIMb64 . ';' . static::$LE .
+			' b=';
+		// Canonicalize the set of headers
+		$canonicalizedHeaders = $this->DKIM_HeaderC(
+			$headerValues . static::$LE . $dkimSignatureHeader
+		);
+		$signature            = $this->DKIM_Sign( $canonicalizedHeaders );
+		$signature            = trim( chunk_split( $signature, self::STD_LINE_LENGTH - 3, static::$LE . self::FWS ) );
+
+		return static::normalizeBreaks( $dkimSignatureHeader . $signature );
+	}
+
+	/**
+	 * Detect if a string contains a line longer than the maximum line length
+	 * allowed by RFC 2822 section 2.1.1.
+	 *
+	 * @param string $str
+	 *
+	 * @return bool
+	 */
+	public static function hasLineLongerThanMax( $str ) {
+		return (bool) preg_match( '/^(.{' . ( self::MAX_LINE_LENGTH + strlen( static::$LE ) ) . ',})/m', $str );
+	}
+
+	/**
+	 * If a string contains any "special" characters, double-quote the name,
+	 * and escape any double quotes with a backslash.
+	 *
+	 * @param string $str
+	 *
+	 * @return string
+	 *
+	 * @see RFC822 3.4.1
+	 */
+	public static function quotedString( $str ) {
+		if ( preg_match( '/[ ()<>@,;:"\/\[\]?=]/', $str ) ) {
+			// If the string contains any of these chars, it must be double-quoted
+			// and any double quotes must be escaped with a backslash
+			return '"' . str_replace( '"', '\\"', $str ) . '"';
+		}
+
+		// Return the string untouched, it doesn't need quoting
+		return $str;
+	}
+
+	/**
+	 * Allows for public read access to 'to' property.
+	 * Before the send() call, queued addresses (i.e. with IDN) are not yet included.
+	 *
+	 * @return array
+	 */
+	public function getToAddresses() {
+		return $this->to;
+	}
+
+	/**
+	 * Allows for public read access to 'cc' property.
+	 * Before the send() call, queued addresses (i.e. with IDN) are not yet included.
+	 *
+	 * @return array
+	 */
+	public function getCcAddresses() {
+		return $this->cc;
+	}
+
+	/**
+	 * Allows for public read access to 'bcc' property.
+	 * Before the send() call, queued addresses (i.e. with IDN) are not yet included.
+	 *
+	 * @return array
+	 */
+	public function getBccAddresses() {
+		return $this->bcc;
+	}
+
+	/**
+	 * Allows for public read access to 'ReplyTo' property.
+	 * Before the send() call, queued addresses (i.e. with IDN) are not yet included.
+	 *
+	 * @return array
+	 */
+	public function getReplyToAddresses() {
+		return $this->ReplyTo;
+	}
+
+	/**
+	 * Allows for public read access to 'all_recipients' property.
+	 * Before the send() call, queued addresses (i.e. with IDN) are not yet included.
+	 *
+	 * @return array
+	 */
+	public function getAllRecipientAddresses() {
+		return $this->all_recipients;
+	}
+
+	/**
+	 * Perform a callback.
+	 *
+	 * @param bool   $isSent
+	 * @param array  $to
+	 * @param array  $cc
+	 * @param array  $bcc
+	 * @param string $subject
+	 * @param string $body
+	 * @param string $from
+	 * @param array  $extra
+	 */
+	protected function doCallback( $isSent, $to, $cc, $bcc, $subject, $body, $from, $extra ) {
+		if ( ! empty( $this->action_function ) && is_callable( $this->action_function ) ) {
+			call_user_func( $this->action_function, $isSent, $to, $cc, $bcc, $subject, $body, $from, $extra );
+		}
+	}
+
+	/**
+	 * Get the OAuthTokenProvider instance.
+	 *
+	 * @return OAuthTokenProvider
+	 */
+	public function getOAuth() {
+		return $this->oauth;
+	}
+
+	/**
+	 * Set an OAuthTokenProvider instance.
+	 */
+	public function setOAuth( OAuthTokenProvider $oauth ) {
+		$this->oauth = $oauth;
+	}
 }
diff --git a/src/wp-includes/SimplePie/src/Parser.php b/src/wp-includes/SimplePie/src/Parser.php
index baf70d2bdb..d7e4301402 100644
--- a/src/wp-includes/SimplePie/src/Parser.php
+++ b/src/wp-includes/SimplePie/src/Parser.php
@@ -12,16 +12,16 @@
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
  *
- * 	* Redistributions of source code must retain the above copyright notice, this list of
- * 	  conditions and the following disclaimer.
+ *  * Redistributions of source code must retain the above copyright notice, this list of
+ *    conditions and the following disclaimer.
  *
- * 	* Redistributions in binary form must reproduce the above copyright notice, this list
- * 	  of conditions and the following disclaimer in the documentation and/or other materials
- * 	  provided with the distribution.
+ *  * Redistributions in binary form must reproduce the above copyright notice, this list
+ *    of conditions and the following disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
  *
- * 	* Neither the name of the SimplePie Team nor the names of its contributors may be used
- * 	  to endorse or promote products derived from this software without specific prior
- * 	  written permission.
+ *  * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without specific prior
+ *    written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
@@ -49,582 +49,596 @@ use SimplePie\XML\Declaration\Parser as DeclarationParser;
 /**
  * Parses XML into something sane
  *
- *
  * This class can be overloaded with {@see \SimplePie\SimplePie::set_parser_class()}
  *
  * @package SimplePie
  * @subpackage Parsing
  */
-class Parser implements RegistryAware
-{
-    public $error_code;
-    public $error_string;
-    public $current_line;
-    public $current_column;
-    public $current_byte;
-    public $separator = ' ';
-    public $namespace = [''];
-    public $element = [''];
-    public $xml_base = [''];
-    public $xml_base_explicit = [false];
-    public $xml_lang = [''];
-    public $data = [];
-    public $datas = [[]];
-    public $current_xhtml_construct = -1;
-    public $encoding;
-    protected $registry;
-
-    public function set_registry(\SimplePie\Registry $registry)/* : void */
-    {
-        $this->registry = $registry;
-    }
-
-    public function parse(&$data, $encoding, $url = '')
-    {
-        if (class_exists('DOMXpath') && function_exists('Mf2\parse')) {
-            $doc = new \DOMDocument();
-            @$doc->loadHTML($data);
-            $xpath = new \DOMXpath($doc);
-            // Check for both h-feed and h-entry, as both a feed with no entries
-            // and a list of entries without an h-feed wrapper are both valid.
-            $query = '//*[contains(concat(" ", @class, " "), " h-feed ") or '.
-                'contains(concat(" ", @class, " "), " h-entry ")]';
-            $result = $xpath->query($query);
-            if ($result->length !== 0) {
-                return $this->parse_microformats($data, $url);
-            }
-        }
-
-        // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
-        if (strtoupper($encoding) === 'US-ASCII') {
-            $this->encoding = 'UTF-8';
-        } else {
-            $this->encoding = $encoding;
-        }
-
-        // Strip BOM:
-        // UTF-32 Big Endian BOM
-        if (substr($data, 0, 4) === "\x00\x00\xFE\xFF") {
-            $data = substr($data, 4);
-        }
-        // UTF-32 Little Endian BOM
-        elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00") {
-            $data = substr($data, 4);
-        }
-        // UTF-16 Big Endian BOM
-        elseif (substr($data, 0, 2) === "\xFE\xFF") {
-            $data = substr($data, 2);
-        }
-        // UTF-16 Little Endian BOM
-        elseif (substr($data, 0, 2) === "\xFF\xFE") {
-            $data = substr($data, 2);
-        }
-        // UTF-8 BOM
-        elseif (substr($data, 0, 3) === "\xEF\xBB\xBF") {
-            $data = substr($data, 3);
-        }
-
-        if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false) {
-            $declaration = $this->registry->create(DeclarationParser::class, [substr($data, 5, $pos - 5)]);
-            if ($declaration->parse()) {
-                $data = substr($data, $pos + 2);
-                $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' ."\n". $this->declare_html_entities() . $data;
-            } else {
-                $this->error_string = 'SimplePie bug! Please report this!';
-                return false;
-            }
-        }
-
-        $return = true;
-
-        static $xml_is_sane = null;
-        if ($xml_is_sane === null) {
-            $parser_check = xml_parser_create();
-            xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
-            xml_parser_free($parser_check);
-            $xml_is_sane = isset($values[0]['value']);
-        }
-
-        // Create the parser
-        if ($xml_is_sane) {
-            $xml = xml_parser_create_ns($this->encoding, $this->separator);
-            xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
-            xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
-            xml_set_character_data_handler($xml, [$this, 'cdata']);
-            xml_set_element_handler($xml, [$this, 'tag_open'], [$this, 'tag_close']);
-
-            // Parse!
-            $wrapper = @is_writable(sys_get_temp_dir()) ? 'php://temp' : 'php://memory';
-            if (($stream = fopen($wrapper, 'r+')) &&
-                fwrite($stream, $data) &&
-                rewind($stream)) {
-                //Parse by chunks not to use too much memory
-                do {
-                    $stream_data = fread($stream, 1048576);
-                    if (!xml_parse($xml, $stream_data === false ? '' : $stream_data, feof($stream))) {
-                        $this->error_code = xml_get_error_code($xml);
-                        $this->error_string = xml_error_string($this->error_code);
-                        $return = false;
-                        break;
-                    }
-                } while (!feof($stream));
-                fclose($stream);
-            } else {
-                $return = false;
-            }
-
-            $this->current_line = xml_get_current_line_number($xml);
-            $this->current_column = xml_get_current_column_number($xml);
-            $this->current_byte = xml_get_current_byte_index($xml);
-            xml_parser_free($xml);
-            return $return;
-        }
-
-        libxml_clear_errors();
-        $xml = new \XMLReader();
-        $xml->xml($data);
-        while (@$xml->read()) {
-            switch ($xml->nodeType) {
-                case constant('XMLReader::END_ELEMENT'):
-                    if ($xml->namespaceURI !== '') {
-                        $tagName = $xml->namespaceURI . $this->separator . $xml->localName;
-                    } else {
-                        $tagName = $xml->localName;
-                    }
-                    $this->tag_close(null, $tagName);
-                    break;
-                case constant('XMLReader::ELEMENT'):
-                    $empty = $xml->isEmptyElement;
-                    if ($xml->namespaceURI !== '') {
-                        $tagName = $xml->namespaceURI . $this->separator . $xml->localName;
-                    } else {
-                        $tagName = $xml->localName;
-                    }
-                    $attributes = [];
-                    while ($xml->moveToNextAttribute()) {
-                        if ($xml->namespaceURI !== '') {
-                            $attrName = $xml->namespaceURI . $this->separator . $xml->localName;
-                        } else {
-                            $attrName = $xml->localName;
-                        }
-                        $attributes[$attrName] = $xml->value;
-                    }
-                    $this->tag_open(null, $tagName, $attributes);
-                    if ($empty) {
-                        $this->tag_close(null, $tagName);
-                    }
-                    break;
-                case constant('XMLReader::TEXT'):
-
-                case constant('XMLReader::CDATA'):
-                    $this->cdata(null, $xml->value);
-                    break;
-            }
-        }
-        if ($error = libxml_get_last_error()) {
-            $this->error_code = $error->code;
-            $this->error_string = $error->message;
-            $this->current_line = $error->line;
-            $this->current_column = $error->column;
-            return false;
-        }
-
-        return true;
-    }
-
-    public function get_error_code()
-    {
-        return $this->error_code;
-    }
-
-    public function get_error_string()
-    {
-        return $this->error_string;
-    }
-
-    public function get_current_line()
-    {
-        return $this->current_line;
-    }
-
-    public function get_current_column()
-    {
-        return $this->current_column;
-    }
-
-    public function get_current_byte()
-    {
-        return $this->current_byte;
-    }
-
-    public function get_data()
-    {
-        return $this->data;
-    }
-
-    public function tag_open($parser, $tag, $attributes)
-    {
-        [$this->namespace[], $this->element[]] = $this->split_ns($tag);
-
-        $attribs = [];
-        foreach ($attributes as $name => $value) {
-            [$attrib_namespace, $attribute] = $this->split_ns($name);
-            $attribs[$attrib_namespace][$attribute] = $value;
-        }
-
-        if (isset($attribs[\SimplePie\SimplePie::NAMESPACE_XML]['base'])) {
-            $base = $this->registry->call(Misc::class, 'absolutize_url', [$attribs[\SimplePie\SimplePie::NAMESPACE_XML]['base'], end($this->xml_base)]);
-            if ($base !== false) {
-                $this->xml_base[] = $base;
-                $this->xml_base_explicit[] = true;
-            }
-        } else {
-            $this->xml_base[] = end($this->xml_base);
-            $this->xml_base_explicit[] = end($this->xml_base_explicit);
-        }
-
-        if (isset($attribs[\SimplePie\SimplePie::NAMESPACE_XML]['lang'])) {
-            $this->xml_lang[] = $attribs[\SimplePie\SimplePie::NAMESPACE_XML]['lang'];
-        } else {
-            $this->xml_lang[] = end($this->xml_lang);
-        }
-
-        if ($this->current_xhtml_construct >= 0) {
-            $this->current_xhtml_construct++;
-            if (end($this->namespace) === \SimplePie\SimplePie::NAMESPACE_XHTML) {
-                $this->data['data'] .= '<' . end($this->element);
-                if (isset($attribs[''])) {
-                    foreach ($attribs[''] as $name => $value) {
-                        $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
-                    }
-                }
-                $this->data['data'] .= '>';
-            }
-        } else {
-            $this->datas[] = &$this->data;
-            $this->data = &$this->data['child'][end($this->namespace)][end($this->element)][];
-            $this->data = ['data' => '', 'attribs' => $attribs, 'xml_base' => end($this->xml_base), 'xml_base_explicit' => end($this->xml_base_explicit), 'xml_lang' => end($this->xml_lang)];
-            if ((end($this->namespace) === \SimplePie\SimplePie::NAMESPACE_ATOM_03 && in_array(end($this->element), ['title', 'tagline', 'copyright', 'info', 'summary', 'content']) && isset($attribs['']['mode']) && $attribs['']['mode'] === 'xml')
-            || (end($this->namespace) === \SimplePie\SimplePie::NAMESPACE_ATOM_10 && in_array(end($this->element), ['rights', 'subtitle', 'summary', 'info', 'title', 'content']) && isset($attribs['']['type']) && $attribs['']['type'] === 'xhtml')
-            || (end($this->namespace) === \SimplePie\SimplePie::NAMESPACE_RSS_20 && in_array(end($this->element), ['title']))
-            || (end($this->namespace) === \SimplePie\SimplePie::NAMESPACE_RSS_090 && in_array(end($this->element), ['title']))
-            || (end($this->namespace) === \SimplePie\SimplePie::NAMESPACE_RSS_10 && in_array(end($this->element), ['title']))) {
-                $this->current_xhtml_construct = 0;
-            }
-        }
-    }
-
-    public function cdata($parser, $cdata)
-    {
-        if ($this->current_xhtml_construct >= 0) {
-            $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
-        } else {
-            $this->data['data'] .= $cdata;
-        }
-    }
-
-    public function tag_close($parser, $tag)
-    {
-        if ($this->current_xhtml_construct >= 0) {
-            $this->current_xhtml_construct--;
-            if (end($this->namespace) === \SimplePie\SimplePie::NAMESPACE_XHTML && !in_array(end($this->element), ['area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param'])) {
-                $this->data['data'] .= '</' . end($this->element) . '>';
-            }
-        }
-        if ($this->current_xhtml_construct === -1) {
-            $this->data = &$this->datas[count($this->datas) - 1];
-            array_pop($this->datas);
-        }
-
-        array_pop($this->element);
-        array_pop($this->namespace);
-        array_pop($this->xml_base);
-        array_pop($this->xml_base_explicit);
-        array_pop($this->xml_lang);
-    }
-
-    public function split_ns($string)
-    {
-        static $cache = [];
-        if (!isset($cache[$string])) {
-            if ($pos = strpos($string, $this->separator)) {
-                static $separator_length;
-                if (!$separator_length) {
-                    $separator_length = strlen($this->separator);
-                }
-                $namespace = substr($string, 0, $pos);
-                $local_name = substr($string, $pos + $separator_length);
-                if (strtolower($namespace) === \SimplePie\SimplePie::NAMESPACE_ITUNES) {
-                    $namespace = \SimplePie\SimplePie::NAMESPACE_ITUNES;
-                }
-
-                // Normalize the Media RSS namespaces
-                if ($namespace === \SimplePie\SimplePie::NAMESPACE_MEDIARSS_WRONG ||
-                    $namespace === \SimplePie\SimplePie::NAMESPACE_MEDIARSS_WRONG2 ||
-                    $namespace === \SimplePie\SimplePie::NAMESPACE_MEDIARSS_WRONG3 ||
-                    $namespace === \SimplePie\SimplePie::NAMESPACE_MEDIARSS_WRONG4 ||
-                    $namespace === \SimplePie\SimplePie::NAMESPACE_MEDIARSS_WRONG5) {
-                    $namespace = \SimplePie\SimplePie::NAMESPACE_MEDIARSS;
-                }
-                $cache[$string] = [$namespace, $local_name];
-            } else {
-                $cache[$string] = ['', $string];
-            }
-        }
-        return $cache[$string];
-    }
-
-    private function parse_hcard($data, $category = false)
-    {
-        $name = '';
-        $link = '';
-        // Check if h-card is set and pass that information on in the link.
-        if (isset($data['type']) && in_array('h-card', $data['type'])) {
-            if (isset($data['properties']['name'][0])) {
-                $name = $data['properties']['name'][0];
-            }
-            if (isset($data['properties']['url'][0])) {
-                $link = $data['properties']['url'][0];
-                if ($name === '') {
-                    $name = $link;
-                } else {
-                    // can't have commas in categories.
-                    $name = str_replace(',', '', $name);
-                }
-                $person_tag = $category ? '<span class="person-tag"></span>' : '';
-                return '<a class="h-card" href="'.$link.'">'.$person_tag.$name.'</a>';
-            }
-        }
-        return $data['value'] ?? '';
-    }
-
-    private function parse_microformats(&$data, $url)
-    {
-        $feed_title = '';
-        $feed_author = null;
-        $author_cache = [];
-        $items = [];
-        $entries = [];
-        $mf = \Mf2\parse($data, $url);
-        // First look for an h-feed.
-        $h_feed = [];
-        foreach ($mf['items'] as $mf_item) {
-            if (in_array('h-feed', $mf_item['type'])) {
-                $h_feed = $mf_item;
-                break;
-            }
-            // Also look for h-feed or h-entry in the children of each top level item.
-            if (!isset($mf_item['children'][0]['type'])) {
-                continue;
-            }
-            if (in_array('h-feed', $mf_item['children'][0]['type'])) {
-                $h_feed = $mf_item['children'][0];
-                // In this case the parent of the h-feed may be an h-card, so use it as
-                // the feed_author.
-                if (in_array('h-card', $mf_item['type'])) {
-                    $feed_author = $mf_item;
-                }
-                break;
-            } elseif (in_array('h-entry', $mf_item['children'][0]['type'])) {
-                $entries = $mf_item['children'];
-                // In this case the parent of the h-entry list may be an h-card, so use
-                // it as the feed_author.
-                if (in_array('h-card', $mf_item['type'])) {
-                    $feed_author = $mf_item;
-                }
-                break;
-            }
-        }
-        if (isset($h_feed['children'])) {
-            $entries = $h_feed['children'];
-            // Also set the feed title and store author from the h-feed if available.
-            if (isset($mf['items'][0]['properties']['name'][0])) {
-                $feed_title = $mf['items'][0]['properties']['name'][0];
-            }
-            if (isset($mf['items'][0]['properties']['author'][0])) {
-                $feed_author = $mf['items'][0]['properties']['author'][0];
-            }
-        } elseif (count($entries) === 0) {
-            $entries = $mf['items'];
-        }
-        for ($i = 0; $i < count($entries); $i++) {
-            $entry = $entries[$i];
-            if (in_array('h-entry', $entry['type'])) {
-                $item = [];
-                $title = '';
-                $description = '';
-                if (isset($entry['properties']['url'][0])) {
-                    $link = $entry['properties']['url'][0];
-                    if (isset($link['value'])) {
-                        $link = $link['value'];
-                    }
-                    $item['link'] = [['data' => $link]];
-                }
-                if (isset($entry['properties']['uid'][0])) {
-                    $guid = $entry['properties']['uid'][0];
-                    if (isset($guid['value'])) {
-                        $guid = $guid['value'];
-                    }
-                    $item['guid'] = [['data' => $guid]];
-                }
-                if (isset($entry['properties']['name'][0])) {
-                    $title = $entry['properties']['name'][0];
-                    if (isset($title['value'])) {
-                        $title = $title['value'];
-                    }
-                    $item['title'] = [['data' => $title]];
-                }
-                if (isset($entry['properties']['author'][0]) || isset($feed_author)) {
-                    // author is a special case, it can be plain text or an h-card array.
-                    // If it's plain text it can also be a url that should be followed to
-                    // get the actual h-card.
-                    $author = $entry['properties']['author'][0] ?? $feed_author;
-                    if (!is_string($author)) {
-                        $author = $this->parse_hcard($author);
-                    } elseif (strpos($author, 'http') === 0) {
-                        if (isset($author_cache[$author])) {
-                            $author = $author_cache[$author];
-                        } else {
-                            $mf = \Mf2\fetch($author);
-                            foreach ($mf['items'] as $hcard) {
-                                // Only interested in an h-card by itself in this case.
-                                if (!in_array('h-card', $hcard['type'])) {
-                                    continue;
-                                }
-                                // It must have a url property matching what we fetched.
-                                if (!isset($hcard['properties']['url']) ||
-                                        !(in_array($author, $hcard['properties']['url']))) {
-                                    continue;
-                                }
-                                // Save parse_hcard the trouble of finding the correct url.
-                                $hcard['properties']['url'][0] = $author;
-                                // Cache this h-card for the next h-entry to check.
-                                $author_cache[$author] = $this->parse_hcard($hcard);
-                                $author = $author_cache[$author];
-                                break;
-                            }
-                        }
-                    }
-                    $item['author'] = [['data' => $author]];
-                }
-                if (isset($entry['properties']['photo'][0])) {
-                    // If a photo is also in content, don't need to add it again here.
-                    $content = '';
-                    if (isset($entry['properties']['content'][0]['html'])) {
-                        $content = $entry['properties']['content'][0]['html'];
-                    }
-                    $photo_list = [];
-                    for ($j = 0; $j < count($entry['properties']['photo']); $j++) {
-                        $photo = $entry['properties']['photo'][$j];
-                        if (!empty($photo) && strpos($content, $photo) === false) {
-                            $photo_list[] = $photo;
-                        }
-                    }
-                    // When there's more than one photo show the first and use a lightbox.
-                    // Need a permanent, unique name for the image set, but don't have
-                    // anything unique except for the content itself, so use that.
-                    $count = count($photo_list);
-                    if ($count > 1) {
-                        $image_set_id = preg_replace('/[[:^alnum:]]/', '', $photo_list[0]);
-                        $description = '<p>';
-                        for ($j = 0; $j < $count; $j++) {
-                            $hidden = $j === 0 ? '' : 'class="hidden" ';
-                            $description .= '<a href="'.$photo_list[$j].'" '.$hidden.
-                                'data-lightbox="image-set-'.$image_set_id.'">'.
-                                '<img src="'.$photo_list[$j].'"></a>';
-                        }
-                        $description .= '<br><b>'.$count.' photos</b></p>';
-                    } elseif ($count == 1) {
-                        $description = '<p><img src="'.$photo_list[0].'"></p>';
-                    }
-                }
-                if (isset($entry['properties']['content'][0]['html'])) {
-                    // e-content['value'] is the same as p-name when they are on the same
-                    // element. Use this to replace title with a strip_tags version so
-                    // that alt text from images is not included in the title.
-                    if ($entry['properties']['content'][0]['value'] === $title) {
-                        $title = strip_tags($entry['properties']['content'][0]['html']);
-                        $item['title'] = [['data' => $title]];
-                    }
-                    $description .= $entry['properties']['content'][0]['html'];
-                    if (isset($entry['properties']['in-reply-to'][0])) {
-                        $in_reply_to = '';
-                        if (is_string($entry['properties']['in-reply-to'][0])) {
-                            $in_reply_to = $entry['properties']['in-reply-to'][0];
-                        } elseif (isset($entry['properties']['in-reply-to'][0]['value'])) {
-                            $in_reply_to = $entry['properties']['in-reply-to'][0]['value'];
-                        }
-                        if ($in_reply_to !== '') {
-                            $description .= '<p><span class="in-reply-to"></span> '.
-                                '<a href="'.$in_reply_to.'">'.$in_reply_to.'</a><p>';
-                        }
-                    }
-                    $item['description'] = [['data' => $description]];
-                }
-                if (isset($entry['properties']['category'])) {
-                    $category_csv = '';
-                    // Categories can also contain h-cards.
-                    foreach ($entry['properties']['category'] as $category) {
-                        if ($category_csv !== '') {
-                            $category_csv .= ', ';
-                        }
-                        if (is_string($category)) {
-                            // Can't have commas in categories.
-                            $category_csv .= str_replace(',', '', $category);
-                        } else {
-                            $category_csv .= $this->parse_hcard($category, true);
-                        }
-                    }
-                    $item['category'] = [['data' => $category_csv]];
-                }
-                if (isset($entry['properties']['published'][0])) {
-                    $timestamp = strtotime($entry['properties']['published'][0]);
-                    $pub_date = date('F j Y g:ia', $timestamp).' GMT';
-                    $item['pubDate'] = [['data' => $pub_date]];
-                }
-                // The title and description are set to the empty string to represent
-                // a deleted item (which also makes it an invalid rss item).
-                if (isset($entry['properties']['deleted'][0])) {
-                    $item['title'] = [['data' => '']];
-                    $item['description'] = [['data' => '']];
-                }
-                $items[] = ['child' => ['' => $item]];
-            }
-        }
-        // Mimic RSS data format when storing microformats.
-        $link = [['data' => $url]];
-        $image = '';
-        if (!is_string($feed_author) &&
-                isset($feed_author['properties']['photo'][0])) {
-            $image = [['child' => ['' => ['url' =>
-                [['data' => $feed_author['properties']['photo'][0]]]]]]];
-        }
-        // Use the name given for the h-feed, or get the title from the html.
-        if ($feed_title !== '') {
-            $feed_title = [['data' => htmlspecialchars($feed_title)]];
-        } elseif ($position = strpos($data, '<title>')) {
-            $start = $position < 200 ? 0 : $position - 200;
-            $check = substr($data, $start, 400);
-            $matches = [];
-            if (preg_match('/<title>(.+)<\/title>/', $check, $matches)) {
-                $feed_title = [['data' => htmlspecialchars($matches[1])]];
-            }
-        }
-        $channel = ['channel' => [['child' => ['' =>
-            ['link' => $link, 'image' => $image, 'title' => $feed_title,
-                  'item' => $items]]]]];
-        $rss = [['attribs' => ['' => ['version' => '2.0']],
-                           'child' => ['' => $channel]]];
-        $this->data = ['child' => ['' => ['rss' => $rss]]];
-        return true;
-    }
-
-    private function declare_html_entities()
-    {
-        // This is required because the RSS specification says that entity-encoded
-        // html is allowed, but the xml specification says they must be declared.
-        return '<!DOCTYPE html [ <!ENTITY nbsp "&#x00A0;"> <!ENTITY iexcl "&#x00A1;"> <!ENTITY cent "&#x00A2;"> <!ENTITY pound "&#x00A3;"> <!ENTITY curren "&#x00A4;"> <!ENTITY yen "&#x00A5;"> <!ENTITY brvbar "&#x00A6;"> <!ENTITY sect "&#x00A7;"> <!ENTITY uml "&#x00A8;"> <!ENTITY copy "&#x00A9;"> <!ENTITY ordf "&#x00AA;"> <!ENTITY laquo "&#x00AB;"> <!ENTITY not "&#x00AC;"> <!ENTITY shy "&#x00AD;"> <!ENTITY reg "&#x00AE;"> <!ENTITY macr "&#x00AF;"> <!ENTITY deg "&#x00B0;"> <!ENTITY plusmn "&#x00B1;"> <!ENTITY sup2 "&#x00B2;"> <!ENTITY sup3 "&#x00B3;"> <!ENTITY acute "&#x00B4;"> <!ENTITY micro "&#x00B5;"> <!ENTITY para "&#x00B6;"> <!ENTITY middot "&#x00B7;"> <!ENTITY cedil "&#x00B8;"> <!ENTITY sup1 "&#x00B9;"> <!ENTITY ordm "&#x00BA;"> <!ENTITY raquo "&#x00BB;"> <!ENTITY frac14 "&#x00BC;"> <!ENTITY frac12 "&#x00BD;"> <!ENTITY frac34 "&#x00BE;"> <!ENTITY iquest "&#x00BF;"> <!ENTITY Agrave "&#x00C0;"> <!ENTITY Aacute "&#x00C1;"> <!ENTITY Acirc "&#x00C2;"> <!ENTITY Atilde "&#x00C3;"> <!ENTITY Auml "&#x00C4;"> <!ENTITY Aring "&#x00C5;"> <!ENTITY AElig "&#x00C6;"> <!ENTITY Ccedil "&#x00C7;"> <!ENTITY Egrave "&#x00C8;"> <!ENTITY Eacute "&#x00C9;"> <!ENTITY Ecirc "&#x00CA;"> <!ENTITY Euml "&#x00CB;"> <!ENTITY Igrave "&#x00CC;"> <!ENTITY Iacute "&#x00CD;"> <!ENTITY Icirc "&#x00CE;"> <!ENTITY Iuml "&#x00CF;"> <!ENTITY ETH "&#x00D0;"> <!ENTITY Ntilde "&#x00D1;"> <!ENTITY Ograve "&#x00D2;"> <!ENTITY Oacute "&#x00D3;"> <!ENTITY Ocirc "&#x00D4;"> <!ENTITY Otilde "&#x00D5;"> <!ENTITY Ouml "&#x00D6;"> <!ENTITY times "&#x00D7;"> <!ENTITY Oslash "&#x00D8;"> <!ENTITY Ugrave "&#x00D9;"> <!ENTITY Uacute "&#x00DA;"> <!ENTITY Ucirc "&#x00DB;"> <!ENTITY Uuml "&#x00DC;"> <!ENTITY Yacute "&#x00DD;"> <!ENTITY THORN "&#x00DE;"> <!ENTITY szlig "&#x00DF;"> <!ENTITY agrave "&#x00E0;"> <!ENTITY aacute "&#x00E1;"> <!ENTITY acirc "&#x00E2;"> <!ENTITY atilde "&#x00E3;"> <!ENTITY auml "&#x00E4;"> <!ENTITY aring "&#x00E5;"> <!ENTITY aelig "&#x00E6;"> <!ENTITY ccedil "&#x00E7;"> <!ENTITY egrave "&#x00E8;"> <!ENTITY eacute "&#x00E9;"> <!ENTITY ecirc "&#x00EA;"> <!ENTITY euml "&#x00EB;"> <!ENTITY igrave "&#x00EC;"> <!ENTITY iacute "&#x00ED;"> <!ENTITY icirc "&#x00EE;"> <!ENTITY iuml "&#x00EF;"> <!ENTITY eth "&#x00F0;"> <!ENTITY ntilde "&#x00F1;"> <!ENTITY ograve "&#x00F2;"> <!ENTITY oacute "&#x00F3;"> <!ENTITY ocirc "&#x00F4;"> <!ENTITY otilde "&#x00F5;"> <!ENTITY ouml "&#x00F6;"> <!ENTITY divide "&#x00F7;"> <!ENTITY oslash "&#x00F8;"> <!ENTITY ugrave "&#x00F9;"> <!ENTITY uacute "&#x00FA;"> <!ENTITY ucirc "&#x00FB;"> <!ENTITY uuml "&#x00FC;"> <!ENTITY yacute "&#x00FD;"> <!ENTITY thorn "&#x00FE;"> <!ENTITY yuml "&#x00FF;"> <!ENTITY OElig "&#x0152;"> <!ENTITY oelig "&#x0153;"> <!ENTITY Scaron "&#x0160;"> <!ENTITY scaron "&#x0161;"> <!ENTITY Yuml "&#x0178;"> <!ENTITY fnof "&#x0192;"> <!ENTITY circ "&#x02C6;"> <!ENTITY tilde "&#x02DC;"> <!ENTITY Alpha "&#x0391;"> <!ENTITY Beta "&#x0392;"> <!ENTITY Gamma "&#x0393;"> <!ENTITY Epsilon "&#x0395;"> <!ENTITY Zeta "&#x0396;"> <!ENTITY Eta "&#x0397;"> <!ENTITY Theta "&#x0398;"> <!ENTITY Iota "&#x0399;"> <!ENTITY Kappa "&#x039A;"> <!ENTITY Lambda "&#x039B;"> <!ENTITY Mu "&#x039C;"> <!ENTITY Nu "&#x039D;"> <!ENTITY Xi "&#x039E;"> <!ENTITY Omicron "&#x039F;"> <!ENTITY Pi "&#x03A0;"> <!ENTITY Rho "&#x03A1;"> <!ENTITY Sigma "&#x03A3;"> <!ENTITY Tau "&#x03A4;"> <!ENTITY Upsilon "&#x03A5;"> <!ENTITY Phi "&#x03A6;"> <!ENTITY Chi "&#x03A7;"> <!ENTITY Psi "&#x03A8;"> <!ENTITY Omega "&#x03A9;"> <!ENTITY alpha "&#x03B1;"> <!ENTITY beta "&#x03B2;"> <!ENTITY gamma "&#x03B3;"> <!ENTITY delta "&#x03B4;"> <!ENTITY epsilon "&#x03B5;"> <!ENTITY zeta "&#x03B6;"> <!ENTITY eta "&#x03B7;"> <!ENTITY theta "&#x03B8;"> <!ENTITY iota "&#x03B9;"> <!ENTITY kappa "&#x03BA;"> <!ENTITY lambda "&#x03BB;"> <!ENTITY mu "&#x03BC;"> <!ENTITY nu "&#x03BD;"> <!ENTITY xi "&#x03BE;"> <!ENTITY omicron "&#x03BF;"> <!ENTITY pi "&#x03C0;"> <!ENTITY rho "&#x03C1;"> <!ENTITY sigmaf "&#x03C2;"> <!ENTITY sigma "&#x03C3;"> <!ENTITY tau "&#x03C4;"> <!ENTITY upsilon "&#x03C5;"> <!ENTITY phi "&#x03C6;"> <!ENTITY chi "&#x03C7;"> <!ENTITY psi "&#x03C8;"> <!ENTITY omega "&#x03C9;"> <!ENTITY thetasym "&#x03D1;"> <!ENTITY upsih "&#x03D2;"> <!ENTITY piv "&#x03D6;"> <!ENTITY ensp "&#x2002;"> <!ENTITY emsp "&#x2003;"> <!ENTITY thinsp "&#x2009;"> <!ENTITY zwnj "&#x200C;"> <!ENTITY zwj "&#x200D;"> <!ENTITY lrm "&#x200E;"> <!ENTITY rlm "&#x200F;"> <!ENTITY ndash "&#x2013;"> <!ENTITY mdash "&#x2014;"> <!ENTITY lsquo "&#x2018;"> <!ENTITY rsquo "&#x2019;"> <!ENTITY sbquo "&#x201A;"> <!ENTITY ldquo "&#x201C;"> <!ENTITY rdquo "&#x201D;"> <!ENTITY bdquo "&#x201E;"> <!ENTITY dagger "&#x2020;"> <!ENTITY Dagger "&#x2021;"> <!ENTITY bull "&#x2022;"> <!ENTITY hellip "&#x2026;"> <!ENTITY permil "&#x2030;"> <!ENTITY prime "&#x2032;"> <!ENTITY Prime "&#x2033;"> <!ENTITY lsaquo "&#x2039;"> <!ENTITY rsaquo "&#x203A;"> <!ENTITY oline "&#x203E;"> <!ENTITY frasl "&#x2044;"> <!ENTITY euro "&#x20AC;"> <!ENTITY image "&#x2111;"> <!ENTITY weierp "&#x2118;"> <!ENTITY real "&#x211C;"> <!ENTITY trade "&#x2122;"> <!ENTITY alefsym "&#x2135;"> <!ENTITY larr "&#x2190;"> <!ENTITY uarr "&#x2191;"> <!ENTITY rarr "&#x2192;"> <!ENTITY darr "&#x2193;"> <!ENTITY harr "&#x2194;"> <!ENTITY crarr "&#x21B5;"> <!ENTITY lArr "&#x21D0;"> <!ENTITY uArr "&#x21D1;"> <!ENTITY rArr "&#x21D2;"> <!ENTITY dArr "&#x21D3;"> <!ENTITY hArr "&#x21D4;"> <!ENTITY forall "&#x2200;"> <!ENTITY part "&#x2202;"> <!ENTITY exist "&#x2203;"> <!ENTITY empty "&#x2205;"> <!ENTITY nabla "&#x2207;"> <!ENTITY isin "&#x2208;"> <!ENTITY notin "&#x2209;"> <!ENTITY ni "&#x220B;"> <!ENTITY prod "&#x220F;"> <!ENTITY sum "&#x2211;"> <!ENTITY minus "&#x2212;"> <!ENTITY lowast "&#x2217;"> <!ENTITY radic "&#x221A;"> <!ENTITY prop "&#x221D;"> <!ENTITY infin "&#x221E;"> <!ENTITY ang "&#x2220;"> <!ENTITY and "&#x2227;"> <!ENTITY or "&#x2228;"> <!ENTITY cap "&#x2229;"> <!ENTITY cup "&#x222A;"> <!ENTITY int "&#x222B;"> <!ENTITY there4 "&#x2234;"> <!ENTITY sim "&#x223C;"> <!ENTITY cong "&#x2245;"> <!ENTITY asymp "&#x2248;"> <!ENTITY ne "&#x2260;"> <!ENTITY equiv "&#x2261;"> <!ENTITY le "&#x2264;"> <!ENTITY ge "&#x2265;"> <!ENTITY sub "&#x2282;"> <!ENTITY sup "&#x2283;"> <!ENTITY nsub "&#x2284;"> <!ENTITY sube "&#x2286;"> <!ENTITY supe "&#x2287;"> <!ENTITY oplus "&#x2295;"> <!ENTITY otimes "&#x2297;"> <!ENTITY perp "&#x22A5;"> <!ENTITY sdot "&#x22C5;"> <!ENTITY lceil "&#x2308;"> <!ENTITY rceil "&#x2309;"> <!ENTITY lfloor "&#x230A;"> <!ENTITY rfloor "&#x230B;"> <!ENTITY lang "&#x2329;"> <!ENTITY rang "&#x232A;"> <!ENTITY loz "&#x25CA;"> <!ENTITY spades "&#x2660;"> <!ENTITY clubs "&#x2663;"> <!ENTITY hearts "&#x2665;"> <!ENTITY diams "&#x2666;"> ]>';
-    }
+class Parser implements RegistryAware {
+
+	public $error_code;
+	public $error_string;
+	public $current_line;
+	public $current_column;
+	public $current_byte;
+	public $separator               = ' ';
+	public $namespace               = array( '' );
+	public $element                 = array( '' );
+	public $xml_base                = array( '' );
+	public $xml_base_explicit       = array( false );
+	public $xml_lang                = array( '' );
+	public $data                    = array();
+	public $datas                   = array( array() );
+	public $current_xhtml_construct = -1;
+	public $encoding;
+	protected $registry;
+
+	public function set_registry( \SimplePie\Registry $registry ) {
+		/* : void */
+		$this->registry = $registry;
+	}
+
+	public function parse( &$data, $encoding, $url = '' ) {
+		if ( class_exists( 'DOMXpath' ) && function_exists( 'Mf2\parse' ) ) {
+			$doc = new \DOMDocument();
+			@$doc->loadHTML( $data );
+			$xpath = new \DOMXpath( $doc );
+			// Check for both h-feed and h-entry, as both a feed with no entries
+			// and a list of entries without an h-feed wrapper are both valid.
+			$query  = '//*[contains(concat(" ", @class, " "), " h-feed ") or ' .
+				'contains(concat(" ", @class, " "), " h-entry ")]';
+			$result = $xpath->query( $query );
+			if ( $result->length !== 0 ) {
+				return $this->parse_microformats( $data, $url );
+			}
+		}
+
+		// Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
+		if ( strtoupper( $encoding ) === 'US-ASCII' ) {
+			$this->encoding = 'UTF-8';
+		} else {
+			$this->encoding = $encoding;
+		}
+
+		// Strip BOM:
+		// UTF-32 Big Endian BOM
+		if ( substr( $data, 0, 4 ) === "\x00\x00\xFE\xFF" ) {
+			$data = substr( $data, 4 );
+		}
+		// UTF-32 Little Endian BOM
+		elseif ( substr( $data, 0, 4 ) === "\xFF\xFE\x00\x00" ) {
+			$data = substr( $data, 4 );
+		}
+		// UTF-16 Big Endian BOM
+		elseif ( substr( $data, 0, 2 ) === "\xFE\xFF" ) {
+			$data = substr( $data, 2 );
+		}
+		// UTF-16 Little Endian BOM
+		elseif ( substr( $data, 0, 2 ) === "\xFF\xFE" ) {
+			$data = substr( $data, 2 );
+		}
+		// UTF-8 BOM
+		elseif ( substr( $data, 0, 3 ) === "\xEF\xBB\xBF" ) {
+			$data = substr( $data, 3 );
+		}
+
+		if ( substr( $data, 0, 5 ) === '<?xml' && strspn( substr( $data, 5, 1 ), "\x09\x0A\x0D\x20" ) && ( $pos = strpos( $data, '?>' ) ) !== false ) {
+			$declaration = $this->registry->create( DeclarationParser::class, array( substr( $data, 5, $pos - 5 ) ) );
+			if ( $declaration->parse() ) {
+				$data = substr( $data, $pos + 2 );
+				$data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . ( ( $declaration->standalone ) ? 'yes' : 'no' ) . '"?>' . "\n" . $this->declare_html_entities() . $data;
+			} else {
+				$this->error_string = 'SimplePie bug! Please report this!';
+				return false;
+			}
+		}
+
+		$return = true;
+
+		static $xml_is_sane = null;
+		if ( $xml_is_sane === null ) {
+			$parser_check = xml_parser_create();
+			xml_parse_into_struct( $parser_check, '<foo>&amp;</foo>', $values );
+			xml_parser_free( $parser_check );
+			$xml_is_sane = isset( $values[0]['value'] );
+		}
+
+		// Create the parser
+		if ( $xml_is_sane ) {
+			$xml = xml_parser_create_ns( $this->encoding, $this->separator );
+			xml_parser_set_option( $xml, XML_OPTION_SKIP_WHITE, 1 );
+			xml_parser_set_option( $xml, XML_OPTION_CASE_FOLDING, 0 );
+			xml_set_character_data_handler( $xml, array( $this, 'cdata' ) );
+			xml_set_element_handler( $xml, array( $this, 'tag_open' ), array( $this, 'tag_close' ) );
+
+			// Parse!
+			$wrapper = @is_writable( sys_get_temp_dir() ) ? 'php://temp' : 'php://memory';
+			if ( ( $stream = fopen( $wrapper, 'r+' ) ) &&
+				fwrite( $stream, $data ) &&
+				rewind( $stream ) ) {
+				// Parse by chunks not to use too much memory
+				do {
+					$stream_data = fread( $stream, 1048576 );
+					if ( ! xml_parse( $xml, $stream_data === false ? '' : $stream_data, feof( $stream ) ) ) {
+						$this->error_code   = xml_get_error_code( $xml );
+						$this->error_string = xml_error_string( $this->error_code );
+						$return             = false;
+						break;
+					}
+				} while ( ! feof( $stream ) );
+				fclose( $stream );
+			} else {
+				$return = false;
+			}
+
+			$this->current_line   = xml_get_current_line_number( $xml );
+			$this->current_column = xml_get_current_column_number( $xml );
+			$this->current_byte   = xml_get_current_byte_index( $xml );
+			xml_parser_free( $xml );
+			return $return;
+		}
+
+		libxml_clear_errors();
+		$xml = new \XMLReader();
+		$xml->xml( $data );
+		while ( @$xml->read() ) {
+			switch ( $xml->nodeType ) {
+				case constant( 'XMLReader::END_ELEMENT' ):
+					if ( $xml->namespaceURI !== '' ) {
+						$tagName = $xml->namespaceURI . $this->separator . $xml->localName;
+					} else {
+						$tagName = $xml->localName;
+					}
+					$this->tag_close( null, $tagName );
+					break;
+				case constant( 'XMLReader::ELEMENT' ):
+					$empty = $xml->isEmptyElement;
+					if ( $xml->namespaceURI !== '' ) {
+						$tagName = $xml->namespaceURI . $this->separator . $xml->localName;
+					} else {
+						$tagName = $xml->localName;
+					}
+					$attributes = array();
+					while ( $xml->moveToNextAttribute() ) {
+						if ( $xml->namespaceURI !== '' ) {
+							$attrName = $xml->namespaceURI . $this->separator . $xml->localName;
+						} else {
+							$attrName = $xml->localName;
+						}
+						$attributes[ $attrName ] = $xml->value;
+					}
+					$this->tag_open( null, $tagName, $attributes );
+					if ( $empty ) {
+						$this->tag_close( null, $tagName );
+					}
+					break;
+				case constant( 'XMLReader::TEXT' ):
+				case constant( 'XMLReader::CDATA' ):
+					$this->cdata( null, $xml->value );
+					break;
+			}
+		}
+		if ( $error = libxml_get_last_error() ) {
+			$this->error_code     = $error->code;
+			$this->error_string   = $error->message;
+			$this->current_line   = $error->line;
+			$this->current_column = $error->column;
+			return false;
+		}
+
+		return true;
+	}
+
+	public function get_error_code() {
+		return $this->error_code;
+	}
+
+	public function get_error_string() {
+		return $this->error_string;
+	}
+
+	public function get_current_line() {
+		return $this->current_line;
+	}
+
+	public function get_current_column() {
+		return $this->current_column;
+	}
+
+	public function get_current_byte() {
+		return $this->current_byte;
+	}
+
+	public function get_data() {
+		return $this->data;
+	}
+
+	public function tag_open( $parser, $tag, $attributes ) {
+		[$this->namespace[], $this->element[]] = $this->split_ns( $tag );
+
+		$attribs = array();
+		foreach ( $attributes as $name => $value ) {
+			[$attrib_namespace, $attribute]             = $this->split_ns( $name );
+			$attribs[ $attrib_namespace ][ $attribute ] = $value;
+		}
+
+		if ( isset( $attribs[ \SimplePie\SimplePie::NAMESPACE_XML ]['base'] ) ) {
+			$base = $this->registry->call( Misc::class, 'absolutize_url', array( $attribs[ \SimplePie\SimplePie::NAMESPACE_XML ]['base'], end( $this->xml_base ) ) );
+			if ( $base !== false ) {
+				$this->xml_base[]          = $base;
+				$this->xml_base_explicit[] = true;
+			}
+		} else {
+			$this->xml_base[]          = end( $this->xml_base );
+			$this->xml_base_explicit[] = end( $this->xml_base_explicit );
+		}
+
+		if ( isset( $attribs[ \SimplePie\SimplePie::NAMESPACE_XML ]['lang'] ) ) {
+			$this->xml_lang[] = $attribs[ \SimplePie\SimplePie::NAMESPACE_XML ]['lang'];
+		} else {
+			$this->xml_lang[] = end( $this->xml_lang );
+		}
+
+		if ( $this->current_xhtml_construct >= 0 ) {
+			++$this->current_xhtml_construct;
+			if ( end( $this->namespace ) === \SimplePie\SimplePie::NAMESPACE_XHTML ) {
+				$this->data['data'] .= '<' . end( $this->element );
+				if ( isset( $attribs[''] ) ) {
+					foreach ( $attribs[''] as $name => $value ) {
+						$this->data['data'] .= ' ' . $name . '="' . htmlspecialchars( $value, ENT_COMPAT, $this->encoding ) . '"';
+					}
+				}
+				$this->data['data'] .= '>';
+			}
+		} else {
+			$this->datas[] = &$this->data;
+			$this->data    = &$this->data['child'][ end( $this->namespace ) ][ end( $this->element ) ][];
+			$this->data    = array(
+				'data'              => '',
+				'attribs'           => $attribs,
+				'xml_base'          => end( $this->xml_base ),
+				'xml_base_explicit' => end( $this->xml_base_explicit ),
+				'xml_lang'          => end( $this->xml_lang ),
+			);
+			if ( ( end( $this->namespace ) === \SimplePie\SimplePie::NAMESPACE_ATOM_03 && in_array( end( $this->element ), array( 'title', 'tagline', 'copyright', 'info', 'summary', 'content' ) ) && isset( $attribs['']['mode'] ) && $attribs['']['mode'] === 'xml' )
+			|| ( end( $this->namespace ) === \SimplePie\SimplePie::NAMESPACE_ATOM_10 && in_array( end( $this->element ), array( 'rights', 'subtitle', 'summary', 'info', 'title', 'content' ) ) && isset( $attribs['']['type'] ) && $attribs['']['type'] === 'xhtml' )
+			|| ( end( $this->namespace ) === \SimplePie\SimplePie::NAMESPACE_RSS_20 && in_array( end( $this->element ), array( 'title' ) ) )
+			|| ( end( $this->namespace ) === \SimplePie\SimplePie::NAMESPACE_RSS_090 && in_array( end( $this->element ), array( 'title' ) ) )
+			|| ( end( $this->namespace ) === \SimplePie\SimplePie::NAMESPACE_RSS_10 && in_array( end( $this->element ), array( 'title' ) ) ) ) {
+				$this->current_xhtml_construct = 0;
+			}
+		}
+	}
+
+	public function cdata( $parser, $cdata ) {
+		if ( $this->current_xhtml_construct >= 0 ) {
+			$this->data['data'] .= htmlspecialchars( $cdata, ENT_QUOTES, $this->encoding );
+		} else {
+			$this->data['data'] .= $cdata;
+		}
+	}
+
+	public function tag_close( $parser, $tag ) {
+		if ( $this->current_xhtml_construct >= 0 ) {
+			--$this->current_xhtml_construct;
+			if ( end( $this->namespace ) === \SimplePie\SimplePie::NAMESPACE_XHTML && ! in_array( end( $this->element ), array( 'area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param' ) ) ) {
+				$this->data['data'] .= '</' . end( $this->element ) . '>';
+			}
+		}
+		if ( $this->current_xhtml_construct === -1 ) {
+			$this->data = &$this->datas[ count( $this->datas ) - 1 ];
+			array_pop( $this->datas );
+		}
+
+		array_pop( $this->element );
+		array_pop( $this->namespace );
+		array_pop( $this->xml_base );
+		array_pop( $this->xml_base_explicit );
+		array_pop( $this->xml_lang );
+	}
+
+	public function split_ns( $string ) {
+		static $cache = array();
+		if ( ! isset( $cache[ $string ] ) ) {
+			if ( $pos = strpos( $string, $this->separator ) ) {
+				static $separator_length;
+				if ( ! $separator_length ) {
+					$separator_length = strlen( $this->separator );
+				}
+				$namespace  = substr( $string, 0, $pos );
+				$local_name = substr( $string, $pos + $separator_length );
+				if ( strtolower( $namespace ) === \SimplePie\SimplePie::NAMESPACE_ITUNES ) {
+					$namespace = \SimplePie\SimplePie::NAMESPACE_ITUNES;
+				}
+
+				// Normalize the Media RSS namespaces
+				if ( $namespace === \SimplePie\SimplePie::NAMESPACE_MEDIARSS_WRONG ||
+					$namespace === \SimplePie\SimplePie::NAMESPACE_MEDIARSS_WRONG2 ||
+					$namespace === \SimplePie\SimplePie::NAMESPACE_MEDIARSS_WRONG3 ||
+					$namespace === \SimplePie\SimplePie::NAMESPACE_MEDIARSS_WRONG4 ||
+					$namespace === \SimplePie\SimplePie::NAMESPACE_MEDIARSS_WRONG5 ) {
+					$namespace = \SimplePie\SimplePie::NAMESPACE_MEDIARSS;
+				}
+				$cache[ $string ] = array( $namespace, $local_name );
+			} else {
+				$cache[ $string ] = array( '', $string );
+			}
+		}
+		return $cache[ $string ];
+	}
+
+	private function parse_hcard( $data, $category = false ) {
+		$name = '';
+		$link = '';
+		// Check if h-card is set and pass that information on in the link.
+		if ( isset( $data['type'] ) && in_array( 'h-card', $data['type'] ) ) {
+			if ( isset( $data['properties']['name'][0] ) ) {
+				$name = $data['properties']['name'][0];
+			}
+			if ( isset( $data['properties']['url'][0] ) ) {
+				$link = $data['properties']['url'][0];
+				if ( $name === '' ) {
+					$name = $link;
+				} else {
+					// can't have commas in categories.
+					$name = str_replace( ',', '', $name );
+				}
+				$person_tag = $category ? '<span class="person-tag"></span>' : '';
+				return '<a class="h-card" href="' . $link . '">' . $person_tag . $name . '</a>';
+			}
+		}
+		return $data['value'] ?? '';
+	}
+
+	private function parse_microformats( &$data, $url ) {
+		$feed_title   = '';
+		$feed_author  = null;
+		$author_cache = array();
+		$items        = array();
+		$entries      = array();
+		$mf           = \Mf2\parse( $data, $url );
+		// First look for an h-feed.
+		$h_feed = array();
+		foreach ( $mf['items'] as $mf_item ) {
+			if ( in_array( 'h-feed', $mf_item['type'] ) ) {
+				$h_feed = $mf_item;
+				break;
+			}
+			// Also look for h-feed or h-entry in the children of each top level item.
+			if ( ! isset( $mf_item['children'][0]['type'] ) ) {
+				continue;
+			}
+			if ( in_array( 'h-feed', $mf_item['children'][0]['type'] ) ) {
+				$h_feed = $mf_item['children'][0];
+				// In this case the parent of the h-feed may be an h-card, so use it as
+				// the feed_author.
+				if ( in_array( 'h-card', $mf_item['type'] ) ) {
+					$feed_author = $mf_item;
+				}
+				break;
+			} elseif ( in_array( 'h-entry', $mf_item['children'][0]['type'] ) ) {
+				$entries = $mf_item['children'];
+				// In this case the parent of the h-entry list may be an h-card, so use
+				// it as the feed_author.
+				if ( in_array( 'h-card', $mf_item['type'] ) ) {
+					$feed_author = $mf_item;
+				}
+				break;
+			}
+		}
+		if ( isset( $h_feed['children'] ) ) {
+			$entries = $h_feed['children'];
+			// Also set the feed title and store author from the h-feed if available.
+			if ( isset( $mf['items'][0]['properties']['name'][0] ) ) {
+				$feed_title = $mf['items'][0]['properties']['name'][0];
+			}
+			if ( isset( $mf['items'][0]['properties']['author'][0] ) ) {
+				$feed_author = $mf['items'][0]['properties']['author'][0];
+			}
+		} elseif ( count( $entries ) === 0 ) {
+			$entries = $mf['items'];
+		}
+		for ( $i = 0; $i < count( $entries ); $i++ ) {
+			$entry = $entries[ $i ];
+			if ( in_array( 'h-entry', $entry['type'] ) ) {
+				$item        = array();
+				$title       = '';
+				$description = '';
+				if ( isset( $entry['properties']['url'][0] ) ) {
+					$link = $entry['properties']['url'][0];
+					if ( isset( $link['value'] ) ) {
+						$link = $link['value'];
+					}
+					$item['link'] = array( array( 'data' => $link ) );
+				}
+				if ( isset( $entry['properties']['uid'][0] ) ) {
+					$guid = $entry['properties']['uid'][0];
+					if ( isset( $guid['value'] ) ) {
+						$guid = $guid['value'];
+					}
+					$item['guid'] = array( array( 'data' => $guid ) );
+				}
+				if ( isset( $entry['properties']['name'][0] ) ) {
+					$title = $entry['properties']['name'][0];
+					if ( isset( $title['value'] ) ) {
+						$title = $title['value'];
+					}
+					$item['title'] = array( array( 'data' => $title ) );
+				}
+				if ( isset( $entry['properties']['author'][0] ) || isset( $feed_author ) ) {
+					// author is a special case, it can be plain text or an h-card array.
+					// If it's plain text it can also be a url that should be followed to
+					// get the actual h-card.
+					$author = $entry['properties']['author'][0] ?? $feed_author;
+					if ( ! is_string( $author ) ) {
+						$author = $this->parse_hcard( $author );
+					} elseif ( strpos( $author, 'http' ) === 0 ) {
+						if ( isset( $author_cache[ $author ] ) ) {
+							$author = $author_cache[ $author ];
+						} else {
+							$mf = \Mf2\fetch( $author );
+							foreach ( $mf['items'] as $hcard ) {
+								// Only interested in an h-card by itself in this case.
+								if ( ! in_array( 'h-card', $hcard['type'] ) ) {
+									continue;
+								}
+								// It must have a url property matching what we fetched.
+								if ( ! isset( $hcard['properties']['url'] ) ||
+										! ( in_array( $author, $hcard['properties']['url'] ) ) ) {
+									continue;
+								}
+								// Save parse_hcard the trouble of finding the correct url.
+								$hcard['properties']['url'][0] = $author;
+								// Cache this h-card for the next h-entry to check.
+								$author_cache[ $author ] = $this->parse_hcard( $hcard );
+								$author                  = $author_cache[ $author ];
+								break;
+							}
+						}
+					}
+					$item['author'] = array( array( 'data' => $author ) );
+				}
+				if ( isset( $entry['properties']['photo'][0] ) ) {
+					// If a photo is also in content, don't need to add it again here.
+					$content = '';
+					if ( isset( $entry['properties']['content'][0]['html'] ) ) {
+						$content = $entry['properties']['content'][0]['html'];
+					}
+					$photo_list = array();
+					for ( $j = 0; $j < count( $entry['properties']['photo'] ); $j++ ) {
+						$photo = $entry['properties']['photo'][ $j ];
+						if ( ! empty( $photo ) && strpos( $content, $photo ) === false ) {
+							$photo_list[] = $photo;
+						}
+					}
+					// When there's more than one photo show the first and use a lightbox.
+					// Need a permanent, unique name for the image set, but don't have
+					// anything unique except for the content itself, so use that.
+					$count = count( $photo_list );
+					if ( $count > 1 ) {
+						$image_set_id = preg_replace( '/[[:^alnum:]]/', '', $photo_list[0] );
+						$description  = '<p>';
+						for ( $j = 0; $j < $count; $j++ ) {
+							$hidden       = $j === 0 ? '' : 'class="hidden" ';
+							$description .= '<a href="' . $photo_list[ $j ] . '" ' . $hidden .
+								'data-lightbox="image-set-' . $image_set_id . '">' .
+								'<img src="' . $photo_list[ $j ] . '"></a>';
+						}
+						$description .= '<br><b>' . $count . ' photos</b></p>';
+					} elseif ( $count == 1 ) {
+						$description = '<p><img src="' . $photo_list[0] . '"></p>';
+					}
+				}
+				if ( isset( $entry['properties']['content'][0]['html'] ) ) {
+					// e-content['value'] is the same as p-name when they are on the same
+					// element. Use this to replace title with a wp_strip_all_tags version so
+					// that alt text from images is not included in the title.
+					if ( $entry['properties']['content'][0]['value'] === $title ) {
+						$title         = wp_strip_all_tags( $entry['properties']['content'][0]['html'] );
+						$item['title'] = array( array( 'data' => $title ) );
+					}
+					$description .= $entry['properties']['content'][0]['html'];
+					if ( isset( $entry['properties']['in-reply-to'][0] ) ) {
+						$in_reply_to = '';
+						if ( is_string( $entry['properties']['in-reply-to'][0] ) ) {
+							$in_reply_to = $entry['properties']['in-reply-to'][0];
+						} elseif ( isset( $entry['properties']['in-reply-to'][0]['value'] ) ) {
+							$in_reply_to = $entry['properties']['in-reply-to'][0]['value'];
+						}
+						if ( $in_reply_to !== '' ) {
+							$description .= '<p><span class="in-reply-to"></span> ' .
+								'<a href="' . $in_reply_to . '">' . $in_reply_to . '</a><p>';
+						}
+					}
+					$item['description'] = array( array( 'data' => $description ) );
+				}
+				if ( isset( $entry['properties']['category'] ) ) {
+					$category_csv = '';
+					// Categories can also contain h-cards.
+					foreach ( $entry['properties']['category'] as $category ) {
+						if ( $category_csv !== '' ) {
+							$category_csv .= ', ';
+						}
+						if ( is_string( $category ) ) {
+							// Can't have commas in categories.
+							$category_csv .= str_replace( ',', '', $category );
+						} else {
+							$category_csv .= $this->parse_hcard( $category, true );
+						}
+					}
+					$item['category'] = array( array( 'data' => $category_csv ) );
+				}
+				if ( isset( $entry['properties']['published'][0] ) ) {
+					$timestamp       = strtotime( $entry['properties']['published'][0] );
+					$pub_date        = date( 'F j Y g:ia', $timestamp ) . ' GMT';
+					$item['pubDate'] = array( array( 'data' => $pub_date ) );
+				}
+				// The title and description are set to the empty string to represent
+				// a deleted item (which also makes it an invalid rss item).
+				if ( isset( $entry['properties']['deleted'][0] ) ) {
+					$item['title']       = array( array( 'data' => '' ) );
+					$item['description'] = array( array( 'data' => '' ) );
+				}
+				$items[] = array( 'child' => array( '' => $item ) );
+			}
+		}
+		// Mimic RSS data format when storing microformats.
+		$link  = array( array( 'data' => $url ) );
+		$image = '';
+		if ( ! is_string( $feed_author ) &&
+				isset( $feed_author['properties']['photo'][0] ) ) {
+			$image = array(
+				array(
+					'child' => array(
+						'' => array(
+							'url' =>
+									array( array( 'data' => $feed_author['properties']['photo'][0] ) ),
+						),
+					),
+				),
+			);
+		}
+		// Use the name given for the h-feed, or get the title from the html.
+		if ( $feed_title !== '' ) {
+			$feed_title = array( array( 'data' => htmlspecialchars( $feed_title ) ) );
+		} elseif ( $position = strpos( $data, '<title>' ) ) {
+			$start   = $position < 200 ? 0 : $position - 200;
+			$check   = substr( $data, $start, 400 );
+			$matches = array();
+			if ( preg_match( '/<title>(.+)<\/title>/', $check, $matches ) ) {
+				$feed_title = array( array( 'data' => htmlspecialchars( $matches[1] ) ) );
+			}
+		}
+		$channel    = array(
+			'channel' => array(
+				array(
+					'child' => array(
+						'' =>
+						array(
+							'link'  => $link,
+							'image' => $image,
+							'title' => $feed_title,
+							'item'  => $items,
+						),
+					),
+				),
+			),
+		);
+		$rss        = array(
+			array(
+				'attribs' => array( '' => array( 'version' => '2.0' ) ),
+				'child'   => array( '' => $channel ),
+			),
+		);
+		$this->data = array( 'child' => array( '' => array( 'rss' => $rss ) ) );
+		return true;
+	}
+
+	private function declare_html_entities() {
+		// This is required because the RSS specification says that entity-encoded
+		// html is allowed, but the xml specification says they must be declared.
+		return '<!DOCTYPE html [ <!ENTITY nbsp "&#x00A0;"> <!ENTITY iexcl "&#x00A1;"> <!ENTITY cent "&#x00A2;"> <!ENTITY pound "&#x00A3;"> <!ENTITY curren "&#x00A4;"> <!ENTITY yen "&#x00A5;"> <!ENTITY brvbar "&#x00A6;"> <!ENTITY sect "&#x00A7;"> <!ENTITY uml "&#x00A8;"> <!ENTITY copy "&#x00A9;"> <!ENTITY ordf "&#x00AA;"> <!ENTITY laquo "&#x00AB;"> <!ENTITY not "&#x00AC;"> <!ENTITY shy "&#x00AD;"> <!ENTITY reg "&#x00AE;"> <!ENTITY macr "&#x00AF;"> <!ENTITY deg "&#x00B0;"> <!ENTITY plusmn "&#x00B1;"> <!ENTITY sup2 "&#x00B2;"> <!ENTITY sup3 "&#x00B3;"> <!ENTITY acute "&#x00B4;"> <!ENTITY micro "&#x00B5;"> <!ENTITY para "&#x00B6;"> <!ENTITY middot "&#x00B7;"> <!ENTITY cedil "&#x00B8;"> <!ENTITY sup1 "&#x00B9;"> <!ENTITY ordm "&#x00BA;"> <!ENTITY raquo "&#x00BB;"> <!ENTITY frac14 "&#x00BC;"> <!ENTITY frac12 "&#x00BD;"> <!ENTITY frac34 "&#x00BE;"> <!ENTITY iquest "&#x00BF;"> <!ENTITY Agrave "&#x00C0;"> <!ENTITY Aacute "&#x00C1;"> <!ENTITY Acirc "&#x00C2;"> <!ENTITY Atilde "&#x00C3;"> <!ENTITY Auml "&#x00C4;"> <!ENTITY Aring "&#x00C5;"> <!ENTITY AElig "&#x00C6;"> <!ENTITY Ccedil "&#x00C7;"> <!ENTITY Egrave "&#x00C8;"> <!ENTITY Eacute "&#x00C9;"> <!ENTITY Ecirc "&#x00CA;"> <!ENTITY Euml "&#x00CB;"> <!ENTITY Igrave "&#x00CC;"> <!ENTITY Iacute "&#x00CD;"> <!ENTITY Icirc "&#x00CE;"> <!ENTITY Iuml "&#x00CF;"> <!ENTITY ETH "&#x00D0;"> <!ENTITY Ntilde "&#x00D1;"> <!ENTITY Ograve "&#x00D2;"> <!ENTITY Oacute "&#x00D3;"> <!ENTITY Ocirc "&#x00D4;"> <!ENTITY Otilde "&#x00D5;"> <!ENTITY Ouml "&#x00D6;"> <!ENTITY times "&#x00D7;"> <!ENTITY Oslash "&#x00D8;"> <!ENTITY Ugrave "&#x00D9;"> <!ENTITY Uacute "&#x00DA;"> <!ENTITY Ucirc "&#x00DB;"> <!ENTITY Uuml "&#x00DC;"> <!ENTITY Yacute "&#x00DD;"> <!ENTITY THORN "&#x00DE;"> <!ENTITY szlig "&#x00DF;"> <!ENTITY agrave "&#x00E0;"> <!ENTITY aacute "&#x00E1;"> <!ENTITY acirc "&#x00E2;"> <!ENTITY atilde "&#x00E3;"> <!ENTITY auml "&#x00E4;"> <!ENTITY aring "&#x00E5;"> <!ENTITY aelig "&#x00E6;"> <!ENTITY ccedil "&#x00E7;"> <!ENTITY egrave "&#x00E8;"> <!ENTITY eacute "&#x00E9;"> <!ENTITY ecirc "&#x00EA;"> <!ENTITY euml "&#x00EB;"> <!ENTITY igrave "&#x00EC;"> <!ENTITY iacute "&#x00ED;"> <!ENTITY icirc "&#x00EE;"> <!ENTITY iuml "&#x00EF;"> <!ENTITY eth "&#x00F0;"> <!ENTITY ntilde "&#x00F1;"> <!ENTITY ograve "&#x00F2;"> <!ENTITY oacute "&#x00F3;"> <!ENTITY ocirc "&#x00F4;"> <!ENTITY otilde "&#x00F5;"> <!ENTITY ouml "&#x00F6;"> <!ENTITY divide "&#x00F7;"> <!ENTITY oslash "&#x00F8;"> <!ENTITY ugrave "&#x00F9;"> <!ENTITY uacute "&#x00FA;"> <!ENTITY ucirc "&#x00FB;"> <!ENTITY uuml "&#x00FC;"> <!ENTITY yacute "&#x00FD;"> <!ENTITY thorn "&#x00FE;"> <!ENTITY yuml "&#x00FF;"> <!ENTITY OElig "&#x0152;"> <!ENTITY oelig "&#x0153;"> <!ENTITY Scaron "&#x0160;"> <!ENTITY scaron "&#x0161;"> <!ENTITY Yuml "&#x0178;"> <!ENTITY fnof "&#x0192;"> <!ENTITY circ "&#x02C6;"> <!ENTITY tilde "&#x02DC;"> <!ENTITY Alpha "&#x0391;"> <!ENTITY Beta "&#x0392;"> <!ENTITY Gamma "&#x0393;"> <!ENTITY Epsilon "&#x0395;"> <!ENTITY Zeta "&#x0396;"> <!ENTITY Eta "&#x0397;"> <!ENTITY Theta "&#x0398;"> <!ENTITY Iota "&#x0399;"> <!ENTITY Kappa "&#x039A;"> <!ENTITY Lambda "&#x039B;"> <!ENTITY Mu "&#x039C;"> <!ENTITY Nu "&#x039D;"> <!ENTITY Xi "&#x039E;"> <!ENTITY Omicron "&#x039F;"> <!ENTITY Pi "&#x03A0;"> <!ENTITY Rho "&#x03A1;"> <!ENTITY Sigma "&#x03A3;"> <!ENTITY Tau "&#x03A4;"> <!ENTITY Upsilon "&#x03A5;"> <!ENTITY Phi "&#x03A6;"> <!ENTITY Chi "&#x03A7;"> <!ENTITY Psi "&#x03A8;"> <!ENTITY Omega "&#x03A9;"> <!ENTITY alpha "&#x03B1;"> <!ENTITY beta "&#x03B2;"> <!ENTITY gamma "&#x03B3;"> <!ENTITY delta "&#x03B4;"> <!ENTITY epsilon "&#x03B5;"> <!ENTITY zeta "&#x03B6;"> <!ENTITY eta "&#x03B7;"> <!ENTITY theta "&#x03B8;"> <!ENTITY iota "&#x03B9;"> <!ENTITY kappa "&#x03BA;"> <!ENTITY lambda "&#x03BB;"> <!ENTITY mu "&#x03BC;"> <!ENTITY nu "&#x03BD;"> <!ENTITY xi "&#x03BE;"> <!ENTITY omicron "&#x03BF;"> <!ENTITY pi "&#x03C0;"> <!ENTITY rho "&#x03C1;"> <!ENTITY sigmaf "&#x03C2;"> <!ENTITY sigma "&#x03C3;"> <!ENTITY tau "&#x03C4;"> <!ENTITY upsilon "&#x03C5;"> <!ENTITY phi "&#x03C6;"> <!ENTITY chi "&#x03C7;"> <!ENTITY psi "&#x03C8;"> <!ENTITY omega "&#x03C9;"> <!ENTITY thetasym "&#x03D1;"> <!ENTITY upsih "&#x03D2;"> <!ENTITY piv "&#x03D6;"> <!ENTITY ensp "&#x2002;"> <!ENTITY emsp "&#x2003;"> <!ENTITY thinsp "&#x2009;"> <!ENTITY zwnj "&#x200C;"> <!ENTITY zwj "&#x200D;"> <!ENTITY lrm "&#x200E;"> <!ENTITY rlm "&#x200F;"> <!ENTITY ndash "&#x2013;"> <!ENTITY mdash "&#x2014;"> <!ENTITY lsquo "&#x2018;"> <!ENTITY rsquo "&#x2019;"> <!ENTITY sbquo "&#x201A;"> <!ENTITY ldquo "&#x201C;"> <!ENTITY rdquo "&#x201D;"> <!ENTITY bdquo "&#x201E;"> <!ENTITY dagger "&#x2020;"> <!ENTITY Dagger "&#x2021;"> <!ENTITY bull "&#x2022;"> <!ENTITY hellip "&#x2026;"> <!ENTITY permil "&#x2030;"> <!ENTITY prime "&#x2032;"> <!ENTITY Prime "&#x2033;"> <!ENTITY lsaquo "&#x2039;"> <!ENTITY rsaquo "&#x203A;"> <!ENTITY oline "&#x203E;"> <!ENTITY frasl "&#x2044;"> <!ENTITY euro "&#x20AC;"> <!ENTITY image "&#x2111;"> <!ENTITY weierp "&#x2118;"> <!ENTITY real "&#x211C;"> <!ENTITY trade "&#x2122;"> <!ENTITY alefsym "&#x2135;"> <!ENTITY larr "&#x2190;"> <!ENTITY uarr "&#x2191;"> <!ENTITY rarr "&#x2192;"> <!ENTITY darr "&#x2193;"> <!ENTITY harr "&#x2194;"> <!ENTITY crarr "&#x21B5;"> <!ENTITY lArr "&#x21D0;"> <!ENTITY uArr "&#x21D1;"> <!ENTITY rArr "&#x21D2;"> <!ENTITY dArr "&#x21D3;"> <!ENTITY hArr "&#x21D4;"> <!ENTITY forall "&#x2200;"> <!ENTITY part "&#x2202;"> <!ENTITY exist "&#x2203;"> <!ENTITY empty "&#x2205;"> <!ENTITY nabla "&#x2207;"> <!ENTITY isin "&#x2208;"> <!ENTITY notin "&#x2209;"> <!ENTITY ni "&#x220B;"> <!ENTITY prod "&#x220F;"> <!ENTITY sum "&#x2211;"> <!ENTITY minus "&#x2212;"> <!ENTITY lowast "&#x2217;"> <!ENTITY radic "&#x221A;"> <!ENTITY prop "&#x221D;"> <!ENTITY infin "&#x221E;"> <!ENTITY ang "&#x2220;"> <!ENTITY and "&#x2227;"> <!ENTITY or "&#x2228;"> <!ENTITY cap "&#x2229;"> <!ENTITY cup "&#x222A;"> <!ENTITY int "&#x222B;"> <!ENTITY there4 "&#x2234;"> <!ENTITY sim "&#x223C;"> <!ENTITY cong "&#x2245;"> <!ENTITY asymp "&#x2248;"> <!ENTITY ne "&#x2260;"> <!ENTITY equiv "&#x2261;"> <!ENTITY le "&#x2264;"> <!ENTITY ge "&#x2265;"> <!ENTITY sub "&#x2282;"> <!ENTITY sup "&#x2283;"> <!ENTITY nsub "&#x2284;"> <!ENTITY sube "&#x2286;"> <!ENTITY supe "&#x2287;"> <!ENTITY oplus "&#x2295;"> <!ENTITY otimes "&#x2297;"> <!ENTITY perp "&#x22A5;"> <!ENTITY sdot "&#x22C5;"> <!ENTITY lceil "&#x2308;"> <!ENTITY rceil "&#x2309;"> <!ENTITY lfloor "&#x230A;"> <!ENTITY rfloor "&#x230B;"> <!ENTITY lang "&#x2329;"> <!ENTITY rang "&#x232A;"> <!ENTITY loz "&#x25CA;"> <!ENTITY spades "&#x2660;"> <!ENTITY clubs "&#x2663;"> <!ENTITY hearts "&#x2665;"> <!ENTITY diams "&#x2666;"> ]>';
+	}
 }
 
-class_alias('SimplePie\Parser', 'SimplePie_Parser');
+class_alias( 'SimplePie\Parser', 'SimplePie_Parser' );
diff --git a/src/wp-includes/blocks/cover.php b/src/wp-includes/blocks/cover.php
index 1ffe7ab3f4..66d6c6709e 100644
--- a/src/wp-includes/blocks/cover.php
+++ b/src/wp-includes/blocks/cover.php
@@ -50,7 +50,7 @@ function render_block_core_cover( $attributes, $content ) {
 		$processor = new WP_HTML_Tag_Processor( '<div></div>' );
 		$processor->next_tag();
 
-		$current_alt = trim( strip_tags( get_post_meta( $current_thumbnail_id, '_wp_attachment_image_alt', true ) ) );
+		$current_alt = trim( wp_strip_all_tags( get_post_meta( $current_thumbnail_id, '_wp_attachment_image_alt', true ) ) );
 		if ( $current_alt ) {
 			$processor->set_attribute( 'role', 'img' );
 			$processor->set_attribute( 'aria-label', $current_alt );
diff --git a/src/wp-includes/blocks/media-text.php b/src/wp-includes/blocks/media-text.php
index b65137b150..ffb8c36a08 100644
--- a/src/wp-includes/blocks/media-text.php
+++ b/src/wp-includes/blocks/media-text.php
@@ -66,11 +66,9 @@ function render_block_core_media_text( $attributes, $content ) {
 			// Insert a unique ID to identify the figure tag.
 			$media_tag_processor->set_attribute( 'id', $unique_id );
 		}
-	} else {
-		if ( $media_tag_processor->next_tag( $wrapping_figure_query ) ) {
+	} elseif ( $media_tag_processor->next_tag( $wrapping_figure_query ) ) {
 			// Insert a unique ID to identify the figure tag.
 			$media_tag_processor->set_attribute( 'id', $unique_id );
-		}
 	}
 
 	$content = $media_tag_processor->get_updated_html();
@@ -103,7 +101,7 @@ function render_block_core_media_text( $attributes, $content ) {
 		) ) {
 			$image_tag_processor->set_attribute( 'src', esc_url( $current_featured_image ) );
 			$image_tag_processor->set_attribute( 'class', 'wp-image-' . get_post_thumbnail_id() . ' size-' . $media_size_slug );
-			$image_tag_processor->set_attribute( 'alt', trim( strip_tags( get_post_meta( get_post_thumbnail_id(), '_wp_attachment_image_alt', true ) ) ) );
+			$image_tag_processor->set_attribute( 'alt', trim( wp_strip_all_tags( get_post_meta( get_post_thumbnail_id(), '_wp_attachment_image_alt', true ) ) ) );
 			if ( $image_fill ) {
 				$image_tag_processor->set_attribute( 'style', 'object-position:' . $focal_point . ';' );
 			}
diff --git a/src/wp-includes/blocks/post-featured-image.php b/src/wp-includes/blocks/post-featured-image.php
index 815da4ee63..561cc960f5 100644
--- a/src/wp-includes/blocks/post-featured-image.php
+++ b/src/wp-includes/blocks/post-featured-image.php
@@ -28,7 +28,7 @@ function render_block_core_post_featured_image( $attributes, $content, $block )
 
 	if ( $is_link ) {
 		if ( get_the_title( $post_ID ) ) {
-			$attr['alt'] = trim( strip_tags( get_the_title( $post_ID ) ) );
+			$attr['alt'] = trim( wp_strip_all_tags( get_the_title( $post_ID ) ) );
 		} else {
 			$attr['alt'] = sprintf(
 				// translators: %d is the post ID.
diff --git a/src/wp-includes/blocks/rss.php b/src/wp-includes/blocks/rss.php
index 3288586340..44612208de 100644
--- a/src/wp-includes/blocks/rss.php
+++ b/src/wp-includes/blocks/rss.php
@@ -32,7 +32,7 @@ function render_block_core_rss( $attributes ) {
 	$rss_items  = $rss->get_items( 0, $attributes['itemsToShow'] );
 	$list_items = '';
 	foreach ( $rss_items as $item ) {
-		$title = esc_html( trim( strip_tags( $item->get_title() ) ) );
+		$title = esc_html( trim( wp_strip_all_tags( $item->get_title() ) ) );
 		if ( empty( $title ) ) {
 			$title = __( '(no title)' );
 		}
@@ -64,7 +64,7 @@ function render_block_core_rss( $attributes ) {
 				$author = '<span class="wp-block-rss__item-author">' . sprintf(
 					/* translators: byline. %s: author. */
 					__( 'by %s' ),
-					esc_html( strip_tags( $author ) )
+					esc_html( wp_strip_all_tags( $author ) )
 				) . '</span>';
 			}
 		}
diff --git a/src/wp-includes/class-walker-category.php b/src/wp-includes/class-walker-category.php
index 24ae740030..7613f93a41 100644
--- a/src/wp-includes/class-walker-category.php
+++ b/src/wp-includes/class-walker-category.php
@@ -122,7 +122,7 @@ class Walker_Category extends Walker {
 			 * @param string  $description Category description.
 			 * @param WP_Term $category    Category object.
 			 */
-			$atts['title'] = strip_tags( apply_filters( 'category_description', $category->description, $category ) );
+			$atts['title'] = wp_strip_all_tags( apply_filters( 'category_description', $category->description, $category ) );
 		}
 
 		/**
diff --git a/src/wp-includes/class-wp-editor.php b/src/wp-includes/class-wp-editor.php
index 9bda3f039b..6866f66c1e 100644
--- a/src/wp-includes/class-wp-editor.php
+++ b/src/wp-includes/class-wp-editor.php
@@ -1827,7 +1827,7 @@ final class _WP_Editors {
 
 			$results[] = array(
 				'ID'        => $post->ID,
-				'title'     => trim( esc_html( strip_tags( get_the_title( $post ) ) ) ),
+				'title'     => trim( esc_html( wp_strip_all_tags( get_the_title( $post ) ) ) ),
 				'permalink' => get_permalink( $post->ID ),
 				'info'      => $info,
 			);
diff --git a/src/wp-includes/class-wp-text-diff-renderer-table.php b/src/wp-includes/class-wp-text-diff-renderer-table.php
index 4fa3d414d2..09810b8419 100644
--- a/src/wp-includes/class-wp-text-diff-renderer-table.php
+++ b/src/wp-includes/class-wp-text-diff-renderer-table.php
@@ -307,12 +307,12 @@ class WP_Text_Diff_Renderer_Table extends Text_Diff_Renderer {
 				// If they're too different, don't include any <ins> or <del>'s.
 				if ( preg_match_all( '!(<ins>.*?</ins>|<del>.*?</del>)!', $diff, $diff_matches ) ) {
 					// Length of all text between <ins> or <del>.
-					$stripped_matches = strlen( strip_tags( implode( ' ', $diff_matches[0] ) ) );
+					$stripped_matches = strlen( wp_strip_all_tags( implode( ' ', $diff_matches[0] ) ) );
 					/*
 					 * Since we count length of text between <ins> or <del> (instead of picking just one),
 					 * we double the length of chars not in those tags.
 					 */
-					$stripped_diff = strlen( strip_tags( $diff ) ) * 2 - $stripped_matches;
+					$stripped_diff = strlen( wp_strip_all_tags( $diff ) ) * 2 - $stripped_matches;
 					$diff_ratio    = $stripped_matches / $stripped_diff;
 					if ( $diff_ratio > $this->_diff_threshold ) {
 						continue; // Too different. Don't save diffs.
@@ -352,12 +352,10 @@ class WP_Text_Diff_Renderer_Table extends Text_Diff_Renderer {
 				$r .= $this->_added( array( $final_line ), false );
 			} elseif ( $final_rows[ $row ] < 0 ) { // Final is blank. This is really a deleted row.
 				$r .= $this->_deleted( array( $orig_line ), false );
-			} else { // A true changed row.
-				if ( $this->_show_split_view ) {
+			} elseif ( $this->_show_split_view ) { // A true changed row.
 					$r .= '<tr>' . $this->deletedLine( $orig_line ) . $this->addedLine( $final_line ) . "</tr>\n";
-				} else {
-					$r .= '<tr>' . $this->deletedLine( $orig_line ) . '</tr><tr>' . $this->addedLine( $final_line ) . "</tr>\n";
-				}
+			} else {
+				$r .= '<tr>' . $this->deletedLine( $orig_line ) . '</tr><tr>' . $this->addedLine( $final_line ) . "</tr>\n";
 			}
 		}
 
diff --git a/src/wp-includes/class-wp-theme.php b/src/wp-includes/class-wp-theme.php
index cac1f6a410..c2ba9d9742 100644
--- a/src/wp-includes/class-wp-theme.php
+++ b/src/wp-includes/class-wp-theme.php
@@ -982,13 +982,13 @@ final class WP_Theme implements ArrayAccess {
 				$value = sanitize_url( $value );
 				break;
 			case 'Tags':
-				$value = array_filter( array_map( 'trim', explode( ',', strip_tags( $value ) ) ) );
+				$value = array_filter( array_map( 'trim', explode( ',', wp_strip_all_tags( $value ) ) ) );
 				break;
 			case 'Version':
 			case 'RequiresWP':
 			case 'RequiresPHP':
 			case 'UpdateURI':
-				$value = strip_tags( $value );
+				$value = wp_strip_all_tags( $value );
 				break;
 		}
 
@@ -2115,7 +2115,7 @@ final class WP_Theme implements ArrayAccess {
 	 * Callback function for usort() to naturally sort themes by name.
 	 *
 	 * Accesses the Name header directly from the class for maximum speed.
-	 * Would choke on HTML but we don't care enough to slow it down with strip_tags().
+	 * Would choke on HTML but we don't care enough to slow it down with wp_strip_all_tags().
 	 *
 	 * @since 3.4.0
 	 *
diff --git a/src/wp-includes/class-wp-xmlrpc-server.php b/src/wp-includes/class-wp-xmlrpc-server.php
index 2141f21e59..b9e4a22415 100644
--- a/src/wp-includes/class-wp-xmlrpc-server.php
+++ b/src/wp-includes/class-wp-xmlrpc-server.php
@@ -1455,10 +1455,8 @@ class wp_xmlrpc_server extends IXR_Server {
 			if ( get_post_type( $post_data['ID'] ) !== $post_data['post_type'] ) {
 				return new IXR_Error( 401, __( 'The post type may not be changed.' ) );
 			}
-		} else {
-			if ( ! current_user_can( $post_type->cap->create_posts ) || ! current_user_can( $post_type->cap->edit_posts ) ) {
+		} elseif ( ! current_user_can( $post_type->cap->create_posts ) || ! current_user_can( $post_type->cap->edit_posts ) ) {
 				return new IXR_Error( 401, __( 'Sorry, you are not allowed to post on this site.' ) );
-			}
 		}
 
 		switch ( $post_data['post_status'] ) {
@@ -6009,10 +6007,8 @@ class wp_xmlrpc_server extends IXR_Server {
 			// Empty value deletes, non-empty value adds/updates.
 			if ( empty( $content_struct['wp_post_thumbnail'] ) ) {
 				delete_post_thumbnail( $post_id );
-			} else {
-				if ( set_post_thumbnail( $post_id, $content_struct['wp_post_thumbnail'] ) === false ) {
+			} elseif ( set_post_thumbnail( $post_id, $content_struct['wp_post_thumbnail'] ) === false ) {
 					return new IXR_Error( 404, __( 'Invalid attachment ID.' ) );
-				}
 			}
 			unset( $content_struct['wp_post_thumbnail'] );
 		}
@@ -6988,7 +6984,7 @@ class wp_xmlrpc_server extends IXR_Server {
 		 */
 		$remote_source = apply_filters( 'pre_remote_source', $remote_source, $pagelinkedto );
 
-		// Work around bug in strip_tags():
+		// Work around bug in wp_strip_all_tags():
 		$remote_source = str_replace( '<!DOC', '<DOC', $remote_source );
 		$remote_source = preg_replace( '/[\r\n\t ]+/', ' ', $remote_source ); // normalize spaces
 		$remote_source = preg_replace( '/<\/*(h1|h2|h3|h4|h5|h6|p|th|td|li|dt|dd|pre|caption|input|textarea|button|body)[^>]*>/', "\n\n", $remote_source );
@@ -7002,7 +6998,7 @@ class wp_xmlrpc_server extends IXR_Server {
 		// Remove all script and style tags including their content.
 		$remote_source = preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $remote_source );
 		// Just keep the tag we need.
-		$remote_source = strip_tags( $remote_source, '<a>' );
+		$remote_source = wp_strip_all_tags( $remote_source, '<a>' );
 
 		$p = explode( "\n\n", $remote_source );
 
@@ -7030,11 +7026,11 @@ class wp_xmlrpc_server extends IXR_Server {
 
 				$marker      = '<wpcontext>' . $context[1] . '</wpcontext>';  // Set up our marker.
 				$excerpt     = str_replace( $context[0], $marker, $excerpt ); // Swap out the link for our marker.
-				$excerpt     = strip_tags( $excerpt, '<wpcontext>' );         // Strip all tags but our context marker.
+				$excerpt     = wp_strip_all_tags( $excerpt, '<wpcontext>' );         // Strip all tags but our context marker.
 				$excerpt     = trim( $excerpt );
 				$preg_marker = preg_quote( $marker, '|' );
 				$excerpt     = preg_replace( "|.*?\s(.{0,100}$preg_marker.{0,100})\s.*|s", '$1', $excerpt );
-				$excerpt     = strip_tags( $excerpt ); // YES, again, to remove the marker wrapper.
+				$excerpt     = wp_strip_all_tags( $excerpt ); // YES, again, to remove the marker wrapper.
 				break;
 			}
 		}
diff --git a/src/wp-includes/comment-template.php b/src/wp-includes/comment-template.php
index bcca00bc23..52b9442caf 100644
--- a/src/wp-includes/comment-template.php
+++ b/src/wp-includes/comment-template.php
@@ -659,7 +659,7 @@ function get_comment_excerpt( $comment_id = 0 ) {
 	$comment = get_comment( $comment_id );
 
 	if ( ! post_password_required( $comment->comment_post_ID ) ) {
-		$comment_text = strip_tags( str_replace( array( "\n", "\r" ), ' ', $comment->comment_content ) );
+		$comment_text = wp_strip_all_tags( str_replace( array( "\n", "\r" ), ' ', $comment->comment_content ) );
 	} else {
 		$comment_text = __( 'Password protected' );
 	}
@@ -979,7 +979,7 @@ function get_comments_number_text( $zero = false, $one = false, $more = false, $
 			if ( 'on' === _x( 'off', 'Comment number declension: on or off' ) ) {
 				$text = preg_replace( '#<span class="screen-reader-text">.+?</span>#', '', $more );
 				$text = preg_replace( '/&.+?;/', '', $text ); // Remove HTML entities.
-				$text = trim( strip_tags( $text ), '% ' );
+				$text = trim( wp_strip_all_tags( $text ), '% ' );
 
 				// Replace '% Comments' with a proper plural form.
 				if ( $text && ! preg_match( '/[0-9]+/', $text ) && str_contains( $more, '%' ) ) {
@@ -1295,7 +1295,7 @@ function trackback_rdf( $deprecated = '' ) {
 	echo '    dc:identifier="';
 	the_permalink();
 	echo '"' . "\n";
-	echo '    dc:title="' . str_replace( '--', '&#x2d;&#x2d;', wptexturize( strip_tags( get_the_title() ) ) ) . '"' . "\n";
+	echo '    dc:title="' . str_replace( '--', '&#x2d;&#x2d;', wptexturize( wp_strip_all_tags( get_the_title() ) ) ) . '"' . "\n";
 	echo '    trackback:ping="' . get_trackback_url() . '"' . " />\n";
 	echo '</rdf:RDF>';
 }
diff --git a/src/wp-includes/comment.php b/src/wp-includes/comment.php
index 4360f14d09..0618a20e3c 100644
--- a/src/wp-includes/comment.php
+++ b/src/wp-includes/comment.php
@@ -1249,7 +1249,7 @@ function wp_check_comment_data_max_lengths( $comment_data ) {
  *
  * @param array $comment_data Array of arguments for inserting a comment.
  * @return int|string|WP_Error The approval status on success (0|1|'spam'|'trash'),
-  *                            WP_Error otherwise.
+ *                            WP_Error otherwise.
  */
 function wp_check_comment_data( $comment_data ) {
 	global $wpdb;
@@ -3019,7 +3019,7 @@ function do_trackbacks( $post ) {
 
 	/** This filter is documented in wp-includes/post-template.php */
 	$post_title = apply_filters( 'the_title', $post->post_title, $post->ID );
-	$post_title = strip_tags( $post_title );
+	$post_title = wp_strip_all_tags( $post_title );
 
 	if ( $to_ping ) {
 		foreach ( (array) $to_ping as $tb_ping ) {
@@ -3499,7 +3499,7 @@ function wp_handle_comment_submission( $comment_data ) {
 		$comment_post_id = (int) $comment_data['comment_post_ID'];
 	}
 	if ( isset( $comment_data['author'] ) && is_string( $comment_data['author'] ) ) {
-		$comment_author = trim( strip_tags( $comment_data['author'] ) );
+		$comment_author = trim( wp_strip_all_tags( $comment_data['author'] ) );
 	}
 	if ( isset( $comment_data['email'] ) && is_string( $comment_data['email'] ) ) {
 		$comment_author_email = trim( $comment_data['email'] );
@@ -3649,10 +3649,8 @@ function wp_handle_comment_submission( $comment_data ) {
 				add_filter( 'pre_comment_content', 'wp_filter_kses' );
 			}
 		}
-	} else {
-		if ( get_option( 'comment_registration' ) ) {
+	} elseif ( get_option( 'comment_registration' ) ) {
 			return new WP_Error( 'not_logged_in', __( 'Sorry, you must be logged in to comment.' ), 403 );
-		}
 	}
 
 	$comment_type = 'comment';
diff --git a/src/wp-includes/default-filters.php b/src/wp-includes/default-filters.php
index ae654605e8..d84e22c6ad 100644
--- a/src/wp-includes/default-filters.php
+++ b/src/wp-includes/default-filters.php
@@ -169,7 +169,7 @@ add_filter( 'comment_text', 'capital_P_dangit', 31 );
 // Format titles.
 foreach ( array( 'single_post_title', 'single_cat_title', 'single_tag_title', 'single_month_title', 'nav_menu_attr_title', 'nav_menu_description' ) as $filter ) {
 	add_filter( $filter, 'wptexturize' );
-	add_filter( $filter, 'strip_tags' );
+	add_filter( $filter, 'wp_strip_all_tags' );
 }
 
 // Format text area for display.
@@ -247,7 +247,7 @@ add_filter( 'block_type_metadata', 'wp_migrate_old_typography_shape' );
 add_filter( 'wp_get_custom_css', 'wp_replace_insecure_home_url' );
 
 // RSS filters.
-add_filter( 'the_title_rss', 'strip_tags' );
+add_filter( 'the_title_rss', 'wp_strip_all_tags' );
 add_filter( 'the_title_rss', 'ent2ncr', 8 );
 add_filter( 'the_title_rss', 'esc_html' );
 add_filter( 'the_content_rss', 'ent2ncr', 8 );
diff --git a/src/wp-includes/deprecated.php b/src/wp-includes/deprecated.php
index 09d7867156..4bc8808bbb 100644
--- a/src/wp-includes/deprecated.php
+++ b/src/wp-includes/deprecated.php
@@ -22,27 +22,27 @@
  * @param int $postid Post ID.
  * @return array Post data.
  */
-function get_postdata($postid) {
+function get_postdata( $postid ) {
 	_deprecated_function( __FUNCTION__, '1.5.1', 'get_post()' );
 
-	$post = get_post($postid);
-
-	$postdata = array (
-		'ID' => $post->ID,
-		'Author_ID' => $post->post_author,
-		'Date' => $post->post_date,
-		'Content' => $post->post_content,
-		'Excerpt' => $post->post_excerpt,
-		'Title' => $post->post_title,
-		'Category' => $post->post_category,
-		'post_status' => $post->post_status,
+	$post = get_post( $postid );
+
+	$postdata = array(
+		'ID'             => $post->ID,
+		'Author_ID'      => $post->post_author,
+		'Date'           => $post->post_date,
+		'Content'        => $post->post_content,
+		'Excerpt'        => $post->post_excerpt,
+		'Title'          => $post->post_title,
+		'Category'       => $post->post_category,
+		'post_status'    => $post->post_status,
 		'comment_status' => $post->comment_status,
-		'ping_status' => $post->ping_status,
-		'post_password' => $post->post_password,
-		'to_ping' => $post->to_ping,
-		'pinged' => $post->pinged,
-		'post_type' => $post->post_type,
-		'post_name' => $post->post_name
+		'ping_status'    => $post->ping_status,
+		'post_password'  => $post->post_password,
+		'to_ping'        => $post->to_ping,
+		'pinged'         => $post->pinged,
+		'post_type'      => $post->post_type,
+		'post_name'      => $post->post_name,
 	);
 
 	return $postdata;
@@ -63,7 +63,7 @@ function get_postdata($postid) {
 function start_wp() {
 	global $wp_query;
 
-	_deprecated_function( __FUNCTION__, '1.5.0', __('new WordPress Loop') );
+	_deprecated_function( __FUNCTION__, '1.5.0', __( 'new WordPress Loop' ) );
 
 	// Since the old style loop is being used, advance the query iterator here.
 	$wp_query->next_post();
@@ -81,15 +81,16 @@ function start_wp() {
  * @param bool $display Optional. Whether to display the output. Default true.
  * @return int Category ID.
  */
-function the_category_ID($display = true) {
+function the_category_ID( $display = true ) {
 	_deprecated_function( __FUNCTION__, '0.71', 'get_the_category()' );
 
 	// Grab the first cat in the list.
 	$categories = get_the_category();
-	$cat = $categories[0]->term_id;
+	$cat        = $categories[0]->term_id;
 
-	if ( $display )
+	if ( $display ) {
 		echo $cat;
+	}
 
 	return $cat;
 }
@@ -114,7 +115,7 @@ function the_category_head( $before = '', $after = '' ) {
 	$currentcat = $categories[0]->category_id;
 	if ( $currentcat != $previouscat ) {
 		echo $before;
-		echo get_the_category_by_ID($currentcat);
+		echo get_the_category_by_ID( $currentcat );
 		echo $after;
 		$previouscat = $currentcat;
 	}
@@ -134,25 +135,28 @@ function the_category_head( $before = '', $after = '' ) {
  * @param int    $limitprev
  * @param string $excluded_categories
  */
-function previous_post($format='%', $previous='previous post: ', $title='yes', $in_same_cat='no', $limitprev=1, $excluded_categories='') {
+function previous_post( $format = '%', $previous = 'previous post: ', $title = 'yes', $in_same_cat = 'no', $limitprev = 1, $excluded_categories = '' ) {
 
 	_deprecated_function( __FUNCTION__, '2.0.0', 'previous_post_link()' );
 
-	if ( empty($in_same_cat) || 'no' == $in_same_cat )
+	if ( empty( $in_same_cat ) || 'no' == $in_same_cat ) {
 		$in_same_cat = false;
-	else
+	} else {
 		$in_same_cat = true;
+	}
 
-	$post = get_previous_post($in_same_cat, $excluded_categories);
+	$post = get_previous_post( $in_same_cat, $excluded_categories );
 
-	if ( !$post )
+	if ( ! $post ) {
 		return;
+	}
 
-	$string = '<a href="'.get_permalink($post->ID).'">'.$previous;
-	if ( 'yes' == $title )
-		$string .= apply_filters('the_title', $post->post_title, $post->ID);
+	$string = '<a href="' . get_permalink( $post->ID ) . '">' . $previous;
+	if ( 'yes' == $title ) {
+		$string .= apply_filters( 'the_title', $post->post_title, $post->ID );
+	}
 	$string .= '</a>';
-	$format = str_replace('%', $string, $format);
+	$format  = str_replace( '%', $string, $format );
 	echo $format;
 }
 
@@ -167,27 +171,30 @@ function previous_post($format='%', $previous='previous post: ', $title='yes', $
  * @param string $next
  * @param string $title
  * @param string $in_same_cat
- * @param int $limitnext
+ * @param int    $limitnext
  * @param string $excluded_categories
  */
-function next_post($format='%', $next='next post: ', $title='yes', $in_same_cat='no', $limitnext=1, $excluded_categories='') {
+function next_post( $format = '%', $next = 'next post: ', $title = 'yes', $in_same_cat = 'no', $limitnext = 1, $excluded_categories = '' ) {
 	_deprecated_function( __FUNCTION__, '2.0.0', 'next_post_link()' );
 
-	if ( empty($in_same_cat) || 'no' == $in_same_cat )
+	if ( empty( $in_same_cat ) || 'no' == $in_same_cat ) {
 		$in_same_cat = false;
-	else
+	} else {
 		$in_same_cat = true;
+	}
 
-	$post = get_next_post($in_same_cat, $excluded_categories);
+	$post = get_next_post( $in_same_cat, $excluded_categories );
 
-	if ( !$post	)
+	if ( ! $post ) {
 		return;
+	}
 
-	$string = '<a href="'.get_permalink($post->ID).'">'.$next;
-	if ( 'yes' == $title )
-		$string .= apply_filters('the_title', $post->post_title, $post->ID);
+	$string = '<a href="' . get_permalink( $post->ID ) . '">' . $next;
+	if ( 'yes' == $title ) {
+		$string .= apply_filters( 'the_title', $post->post_title, $post->ID );
+	}
 	$string .= '</a>';
-	$format = str_replace('%', $string, $format);
+	$format  = str_replace( '%', $string, $format );
 	echo $format;
 }
 
@@ -203,11 +210,11 @@ function next_post($format='%', $next='next post: ', $title='yes', $in_same_cat=
  * @param int $category_id Not Used
  * @return bool
  */
-function user_can_create_post($user_id, $blog_id = 1, $category_id = 'None') {
+function user_can_create_post( $user_id, $blog_id = 1, $category_id = 'None' ) {
 	_deprecated_function( __FUNCTION__, '2.0.0', 'current_user_can()' );
 
-	$author_data = get_userdata($user_id);
-	return ($author_data->user_level > 1);
+	$author_data = get_userdata( $user_id );
+	return ( $author_data->user_level > 1 );
 }
 
 /**
@@ -222,11 +229,11 @@ function user_can_create_post($user_id, $blog_id = 1, $category_id = 'None') {
  * @param int $category_id Not Used
  * @return bool
  */
-function user_can_create_draft($user_id, $blog_id = 1, $category_id = 'None') {
+function user_can_create_draft( $user_id, $blog_id = 1, $category_id = 'None' ) {
 	_deprecated_function( __FUNCTION__, '2.0.0', 'current_user_can()' );
 
-	$author_data = get_userdata($user_id);
-	return ($author_data->user_level >= 1);
+	$author_data = get_userdata( $user_id );
+	return ( $author_data->user_level >= 1 );
 }
 
 /**
@@ -241,16 +248,16 @@ function user_can_create_draft($user_id, $blog_id = 1, $category_id = 'None') {
  * @param int $blog_id Not Used
  * @return bool
  */
-function user_can_edit_post($user_id, $post_id, $blog_id = 1) {
+function user_can_edit_post( $user_id, $post_id, $blog_id = 1 ) {
 	_deprecated_function( __FUNCTION__, '2.0.0', 'current_user_can()' );
 
-	$author_data = get_userdata($user_id);
-	$post = get_post($post_id);
-	$post_author_data = get_userdata($post->post_author);
+	$author_data      = get_userdata( $user_id );
+	$post             = get_post( $post_id );
+	$post_author_data = get_userdata( $post->post_author );
 
-	if ( (($user_id == $post_author_data->ID) && !($post->post_status == 'publish' && $author_data->user_level < 2))
-			|| ($author_data->user_level > $post_author_data->user_level)
-			|| ($author_data->user_level >= 10) ) {
+	if ( ( ( $user_id == $post_author_data->ID ) && ! ( $post->post_status == 'publish' && $author_data->user_level < 2 ) )
+			|| ( $author_data->user_level > $post_author_data->user_level )
+			|| ( $author_data->user_level >= 10 ) ) {
 		return true;
 	} else {
 		return false;
@@ -269,11 +276,11 @@ function user_can_edit_post($user_id, $post_id, $blog_id = 1) {
  * @param int $blog_id Not Used
  * @return bool
  */
-function user_can_delete_post($user_id, $post_id, $blog_id = 1) {
+function user_can_delete_post( $user_id, $post_id, $blog_id = 1 ) {
 	_deprecated_function( __FUNCTION__, '2.0.0', 'current_user_can()' );
 
 	// Right now if one can edit, one can delete.
-	return user_can_edit_post($user_id, $post_id, $blog_id);
+	return user_can_edit_post( $user_id, $post_id, $blog_id );
 }
 
 /**
@@ -288,11 +295,11 @@ function user_can_delete_post($user_id, $post_id, $blog_id = 1) {
  * @param int $category_id Not Used
  * @return bool
  */
-function user_can_set_post_date($user_id, $blog_id = 1, $category_id = 'None') {
+function user_can_set_post_date( $user_id, $blog_id = 1, $category_id = 'None' ) {
 	_deprecated_function( __FUNCTION__, '2.0.0', 'current_user_can()' );
 
-	$author_data = get_userdata($user_id);
-	return (($author_data->user_level > 4) && user_can_create_post($user_id, $blog_id, $category_id));
+	$author_data = get_userdata( $user_id );
+	return ( ( $author_data->user_level > 4 ) && user_can_create_post( $user_id, $blog_id, $category_id ) );
 }
 
 /**
@@ -307,11 +314,11 @@ function user_can_set_post_date($user_id, $blog_id = 1, $category_id = 'None') {
  * @param int $blog_id Not Used
  * @return bool returns true if $user_id can edit $post_id's date
  */
-function user_can_edit_post_date($user_id, $post_id, $blog_id = 1) {
+function user_can_edit_post_date( $user_id, $post_id, $blog_id = 1 ) {
 	_deprecated_function( __FUNCTION__, '2.0.0', 'current_user_can()' );
 
-	$author_data = get_userdata($user_id);
-	return (($author_data->user_level > 4) && user_can_edit_post($user_id, $post_id, $blog_id));
+	$author_data = get_userdata( $user_id );
+	return ( ( $author_data->user_level > 4 ) && user_can_edit_post( $user_id, $post_id, $blog_id ) );
 }
 
 /**
@@ -326,11 +333,11 @@ function user_can_edit_post_date($user_id, $post_id, $blog_id = 1) {
  * @param int $blog_id Not Used
  * @return bool returns true if $user_id can edit $post_id's comments
  */
-function user_can_edit_post_comments($user_id, $post_id, $blog_id = 1) {
+function user_can_edit_post_comments( $user_id, $post_id, $blog_id = 1 ) {
 	_deprecated_function( __FUNCTION__, '2.0.0', 'current_user_can()' );
 
 	// Right now if one can edit a post, one can edit comments made on it.
-	return user_can_edit_post($user_id, $post_id, $blog_id);
+	return user_can_edit_post( $user_id, $post_id, $blog_id );
 }
 
 /**
@@ -345,11 +352,11 @@ function user_can_edit_post_comments($user_id, $post_id, $blog_id = 1) {
  * @param int $blog_id Not Used
  * @return bool returns true if $user_id can delete $post_id's comments
  */
-function user_can_delete_post_comments($user_id, $post_id, $blog_id = 1) {
+function user_can_delete_post_comments( $user_id, $post_id, $blog_id = 1 ) {
 	_deprecated_function( __FUNCTION__, '2.0.0', 'current_user_can()' );
 
 	// Right now if one can edit comments, one can delete comments.
-	return user_can_edit_post_comments($user_id, $post_id, $blog_id);
+	return user_can_edit_post_comments( $user_id, $post_id, $blog_id );
 }
 
 /**
@@ -363,15 +370,16 @@ function user_can_delete_post_comments($user_id, $post_id, $blog_id = 1) {
  * @param int $other_user
  * @return bool
  */
-function user_can_edit_user($user_id, $other_user) {
+function user_can_edit_user( $user_id, $other_user ) {
 	_deprecated_function( __FUNCTION__, '2.0.0', 'current_user_can()' );
 
-	$user  = get_userdata($user_id);
-	$other = get_userdata($other_user);
-	if ( $user->user_level > $other->user_level || $user->user_level > 8 || $user->ID == $other->ID )
+	$user  = get_userdata( $user_id );
+	$other = get_userdata( $other_user );
+	if ( $user->user_level > $other->user_level || $user->user_level > 8 || $user->ID == $other->ID ) {
 		return true;
-	else
+	} else {
 		return false;
+	}
 }
 
 /**
@@ -399,17 +407,27 @@ function user_can_edit_user($user_id, $other_user) {
  *                                 Default -1.
  * @param int    $show_updated     Optional. Whether to show last updated timestamp. Default 0.
  */
-function get_linksbyname($cat_name = "noname", $before = '', $after = '<br />', $between = " ", $show_images = true, $orderby = 'id',
-						$show_description = true, $show_rating = false,
-						$limit = -1, $show_updated = 0) {
+function get_linksbyname(
+	$cat_name = 'noname',
+	$before = '',
+	$after = '<br />',
+	$between = ' ',
+	$show_images = true,
+	$orderby = 'id',
+	$show_description = true,
+	$show_rating = false,
+	$limit = -1,
+	$show_updated = 0
+) {
 	_deprecated_function( __FUNCTION__, '2.1.0', 'get_bookmarks()' );
 
 	$cat_id = -1;
-	$cat = get_term_by('name', $cat_name, 'link_category');
-	if ( $cat )
+	$cat    = get_term_by( 'name', $cat_name, 'link_category' );
+	if ( $cat ) {
 		$cat_id = $cat->term_id;
+	}
 
-	get_links($cat_id, $before, $after, $between, $show_images, $orderby, $show_description, $show_rating, $limit, $show_updated);
+	get_links( $cat_id, $before, $after, $between, $show_images, $orderby, $show_description, $show_rating, $limit, $show_updated );
 }
 
 /**
@@ -423,23 +441,23 @@ function get_linksbyname($cat_name = "noname", $before = '', $after = '<br />',
  * @param string $args
  * @return string|null
  */
-function wp_get_linksbyname($category, $args = '') {
-	_deprecated_function(__FUNCTION__, '2.1.0', 'wp_list_bookmarks()');
+function wp_get_linksbyname( $category, $args = '' ) {
+	_deprecated_function( __FUNCTION__, '2.1.0', 'wp_list_bookmarks()' );
 
 	$defaults = array(
-		'after' => '<br />',
-		'before' => '',
-		'categorize' => 0,
-		'category_after' => '',
-		'category_before' => '',
-		'category_name' => $category,
+		'after'            => '<br />',
+		'before'           => '',
+		'categorize'       => 0,
+		'category_after'   => '',
+		'category_before'  => '',
+		'category_name'    => $category,
 		'show_description' => 1,
-		'title_li' => '',
+		'title_li'         => '',
 	);
 
 	$parsed_args = wp_parse_args( $args, $defaults );
 
-	return wp_list_bookmarks($parsed_args);
+	return wp_list_bookmarks( $parsed_args );
 }
 
 /**
@@ -447,7 +465,7 @@ function wp_get_linksbyname($category, $args = '') {
  *
  *     $links = get_linkobjectsbyname( 'fred' );
  *     foreach ( $links as $link ) {
- *      	echo '<li>' . $link->link_name . '</li>';
+ *          echo '<li>' . $link->link_name . '</li>';
  *     }
  *
  * @since 1.0.1
@@ -464,15 +482,16 @@ function wp_get_linksbyname($category, $args = '') {
  *                         Default -1.
  * @return array
  */
-function get_linkobjectsbyname($cat_name = "noname" , $orderby = 'name', $limit = -1) {
+function get_linkobjectsbyname( $cat_name = 'noname', $orderby = 'name', $limit = -1 ) {
 	_deprecated_function( __FUNCTION__, '2.1.0', 'get_bookmarks()' );
 
 	$cat_id = -1;
-	$cat = get_term_by('name', $cat_name, 'link_category');
-	if ( $cat )
+	$cat    = get_term_by( 'name', $cat_name, 'link_category' );
+	if ( $cat ) {
 		$cat_id = $cat->term_id;
+	}
 
-	return get_linkobjects($cat_id, $orderby, $limit);
+	return get_linkobjects( $cat_id, $orderby, $limit );
 }
 
 /**
@@ -482,9 +501,9 @@ function get_linkobjectsbyname($cat_name = "noname" , $orderby = 'name', $limit
  *
  *     $links = get_linkobjects(1);
  *     if ($links) {
- *     	foreach ($links as $link) {
- *     		echo '<li>'.$link->link_name.'<br />'.$link->link_description.'</li>';
- *     	}
+ *      foreach ($links as $link) {
+ *          echo '<li>'.$link->link_name.'<br />'.$link->link_description.'</li>';
+ *      }
  *     }
  *
  * Fields are:
@@ -517,14 +536,21 @@ function get_linkobjectsbyname($cat_name = "noname" , $orderby = 'name', $limit
  *                         Default 0.
  * @return array
  */
-function get_linkobjects($category = 0, $orderby = 'name', $limit = 0) {
+function get_linkobjects( $category = 0, $orderby = 'name', $limit = 0 ) {
 	_deprecated_function( __FUNCTION__, '2.1.0', 'get_bookmarks()' );
 
-	$links = get_bookmarks( array( 'category' => $category, 'orderby' => $orderby, 'limit' => $limit ) ) ;
+	$links = get_bookmarks(
+		array(
+			'category' => $category,
+			'orderby'  => $orderby,
+			'limit'    => $limit,
+		)
+	);
 
 	$links_array = array();
-	foreach ($links as $link)
+	foreach ( $links as $link ) {
 		$links_array[] = $link;
+	}
 
 	return $links_array;
 }
@@ -549,15 +575,24 @@ function get_linkobjects($category = 0, $orderby = 'name', $limit = 0) {
  *                                 Specifying 'rand' as the order will return links in a random order.
  * @param bool   $show_description Optional. Whether to show the description if show_images=false/not defined.
  *                                 Default true.
- * @param int    $limit		       Optional. Limit to X entries. If not specified, all entries are shown.
+ * @param int    $limit            Optional. Limit to X entries. If not specified, all entries are shown.
  *                                 Default -1.
  * @param int    $show_updated     Optional. Whether to show last updated timestamp. Default 0.
  */
-function get_linksbyname_withrating($cat_name = "noname", $before = '', $after = '<br />', $between = " ",
-									$show_images = true, $orderby = 'id', $show_description = true, $limit = -1, $show_updated = 0) {
+function get_linksbyname_withrating(
+	$cat_name = 'noname',
+	$before = '',
+	$after = '<br />',
+	$between = ' ',
+	$show_images = true,
+	$orderby = 'id',
+	$show_description = true,
+	$limit = -1,
+	$show_updated = 0
+) {
 	_deprecated_function( __FUNCTION__, '2.1.0', 'get_bookmarks()' );
 
-	get_linksbyname($cat_name, $before, $after, $between, $show_images, $orderby, $show_description, true, $limit, $show_updated);
+	get_linksbyname( $cat_name, $before, $after, $between, $show_images, $orderby, $show_description, true, $limit, $show_updated );
 }
 
 /**
@@ -580,15 +615,24 @@ function get_linksbyname_withrating($cat_name = "noname", $before = '', $after =
  *                                 Specifying 'rand' as the order will return links in a random order.
  * @param bool   $show_description Optional. Whether to show the description if show_images=false/not defined.
  *                                 Default true.
- * @param int    $limit		       Optional. Limit to X entries. If not specified, all entries are shown.
+ * @param int    $limit            Optional. Limit to X entries. If not specified, all entries are shown.
  *                                 Default -1.
  * @param int    $show_updated     Optional. Whether to show last updated timestamp. Default 0.
  */
-function get_links_withrating($category = -1, $before = '', $after = '<br />', $between = " ", $show_images = true,
-							$orderby = 'id', $show_description = true, $limit = -1, $show_updated = 0) {
+function get_links_withrating(
+	$category = -1,
+	$before = '',
+	$after = '<br />',
+	$between = ' ',
+	$show_images = true,
+	$orderby = 'id',
+	$show_description = true,
+	$limit = -1,
+	$show_updated = 0
+) {
 	_deprecated_function( __FUNCTION__, '2.1.0', 'get_bookmarks()' );
 
-	get_links($category, $before, $after, $between, $show_images, $orderby, $show_description, true, $limit, $show_updated);
+	get_links( $category, $before, $after, $between, $show_images, $orderby, $show_description, true, $limit, $show_updated );
 }
 
 /**
@@ -600,7 +644,7 @@ function get_links_withrating($category = -1, $before = '', $after = '<br />', $
  * @param int $id The category to get. If no category supplied uses 0
  * @return int Only returns 0.
  */
-function get_autotoggle($id = 0) {
+function get_autotoggle( $id = 0 ) {
 	_deprecated_function( __FUNCTION__, '2.1.0' );
 	return 0;
 }
@@ -612,34 +656,69 @@ function get_autotoggle($id = 0) {
  * @deprecated 2.1.0 Use wp_list_categories()
  * @see wp_list_categories()
  *
- * @param int $optionall
+ * @param int    $optionall
  * @param string $all
  * @param string $sort_column
  * @param string $sort_order
  * @param string $file
- * @param bool $list
- * @param int $optiondates
- * @param int $optioncount
- * @param int $hide_empty
- * @param int $use_desc_for_title
- * @param bool $children
- * @param int $child_of
- * @param int $categories
- * @param int $recurse
+ * @param bool   $list
+ * @param int    $optiondates
+ * @param int    $optioncount
+ * @param int    $hide_empty
+ * @param int    $use_desc_for_title
+ * @param bool   $children
+ * @param int    $child_of
+ * @param int    $categories
+ * @param int    $recurse
  * @param string $feed
  * @param string $feed_image
  * @param string $exclude
- * @param bool $hierarchical
+ * @param bool   $hierarchical
  * @return null|false
  */
-function list_cats($optionall = 1, $all = 'All', $sort_column = 'ID', $sort_order = 'asc', $file = '', $list = true, $optiondates = 0,
-				$optioncount = 0, $hide_empty = 1, $use_desc_for_title = 1, $children=false, $child_of=0, $categories=0,
-				$recurse=0, $feed = '', $feed_image = '', $exclude = '', $hierarchical=false) {
+function list_cats(
+	$optionall = 1,
+	$all = 'All',
+	$sort_column = 'ID',
+	$sort_order = 'asc',
+	$file = '',
+	$list = true,
+	$optiondates = 0,
+	$optioncount = 0,
+	$hide_empty = 1,
+	$use_desc_for_title = 1,
+	$children = false,
+	$child_of = 0,
+	$categories = 0,
+	$recurse = 0,
+	$feed = '',
+	$feed_image = '',
+	$exclude = '',
+	$hierarchical = false
+) {
 	_deprecated_function( __FUNCTION__, '2.1.0', 'wp_list_categories()' );
 
-	$query = compact('optionall', 'all', 'sort_column', 'sort_order', 'file', 'list', 'optiondates', 'optioncount', 'hide_empty', 'use_desc_for_title', 'children',
-		'child_of', 'categories', 'recurse', 'feed', 'feed_image', 'exclude', 'hierarchical');
-	return wp_list_cats($query);
+	$query = compact(
+		'optionall',
+		'all',
+		'sort_column',
+		'sort_order',
+		'file',
+		'list',
+		'optiondates',
+		'optioncount',
+		'hide_empty',
+		'use_desc_for_title',
+		'children',
+		'child_of',
+		'categories',
+		'recurse',
+		'feed',
+		'feed_image',
+		'exclude',
+		'hierarchical'
+	);
+	return wp_list_cats( $query );
 }
 
 /**
@@ -652,27 +731,33 @@ function list_cats($optionall = 1, $all = 'All', $sort_column = 'ID', $sort_orde
  * @param string|array $args
  * @return null|string|false
  */
-function wp_list_cats($args = '') {
+function wp_list_cats( $args = '' ) {
 	_deprecated_function( __FUNCTION__, '2.1.0', 'wp_list_categories()' );
 
 	$parsed_args = wp_parse_args( $args );
 
 	// Map to new names.
-	if ( isset($parsed_args['optionall']) && isset($parsed_args['all']))
+	if ( isset( $parsed_args['optionall'] ) && isset( $parsed_args['all'] ) ) {
 		$parsed_args['show_option_all'] = $parsed_args['all'];
-	if ( isset($parsed_args['sort_column']) )
+	}
+	if ( isset( $parsed_args['sort_column'] ) ) {
 		$parsed_args['orderby'] = $parsed_args['sort_column'];
-	if ( isset($parsed_args['sort_order']) )
+	}
+	if ( isset( $parsed_args['sort_order'] ) ) {
 		$parsed_args['order'] = $parsed_args['sort_order'];
-	if ( isset($parsed_args['optiondates']) )
+	}
+	if ( isset( $parsed_args['optiondates'] ) ) {
 		$parsed_args['show_last_update'] = $parsed_args['optiondates'];
-	if ( isset($parsed_args['optioncount']) )
+	}
+	if ( isset( $parsed_args['optioncount'] ) ) {
 		$parsed_args['show_count'] = $parsed_args['optioncount'];
-	if ( isset($parsed_args['list']) )
+	}
+	if ( isset( $parsed_args['list'] ) ) {
 		$parsed_args['style'] = $parsed_args['list'] ? 'list' : 'break';
+	}
 	$parsed_args['title_li'] = '';
 
-	return wp_list_categories($parsed_args);
+	return wp_list_categories( $parsed_args );
 }
 
 /**
@@ -682,35 +767,55 @@ function wp_list_cats($args = '') {
  * @deprecated 2.1.0 Use wp_dropdown_categories()
  * @see wp_dropdown_categories()
  *
- * @param int $optionall
+ * @param int    $optionall
  * @param string $all
  * @param string $orderby
  * @param string $order
- * @param int $show_last_update
- * @param int $show_count
- * @param int $hide_empty
- * @param bool $optionnone
- * @param int $selected
- * @param int $exclude
+ * @param int    $show_last_update
+ * @param int    $show_count
+ * @param int    $hide_empty
+ * @param bool   $optionnone
+ * @param int    $selected
+ * @param int    $exclude
  * @return string
  */
-function dropdown_cats($optionall = 1, $all = 'All', $orderby = 'ID', $order = 'asc',
-		$show_last_update = 0, $show_count = 0, $hide_empty = 1, $optionnone = false,
-		$selected = 0, $exclude = 0) {
+function dropdown_cats(
+	$optionall = 1,
+	$all = 'All',
+	$orderby = 'ID',
+	$order = 'asc',
+	$show_last_update = 0,
+	$show_count = 0,
+	$hide_empty = 1,
+	$optionnone = false,
+	$selected = 0,
+	$exclude = 0
+) {
 	_deprecated_function( __FUNCTION__, '2.1.0', 'wp_dropdown_categories()' );
 
 	$show_option_all = '';
-	if ( $optionall )
+	if ( $optionall ) {
 		$show_option_all = $all;
+	}
 
 	$show_option_none = '';
-	if ( $optionnone )
+	if ( $optionnone ) {
 		$show_option_none = _x( 'None', 'Categories dropdown (show_option_none parameter)' );
+	}
 
-	$vars = compact('show_option_all', 'show_option_none', 'orderby', 'order',
-					'show_last_update', 'show_count', 'hide_empty', 'selected', 'exclude');
-	$query = add_query_arg($vars, '');
-	return wp_dropdown_categories($query);
+	$vars  = compact(
+		'show_option_all',
+		'show_option_none',
+		'orderby',
+		'order',
+		'show_last_update',
+		'show_count',
+		'hide_empty',
+		'selected',
+		'exclude'
+	);
+	$query = add_query_arg( $vars, '' );
+	return wp_dropdown_categories( $query );
 }
 
 /**
@@ -720,19 +825,19 @@ function dropdown_cats($optionall = 1, $all = 'All', $orderby = 'ID', $order = '
  * @deprecated 2.1.0 Use wp_list_authors()
  * @see wp_list_authors()
  *
- * @param bool $optioncount
- * @param bool $exclude_admin
- * @param bool $show_fullname
- * @param bool $hide_empty
+ * @param bool   $optioncount
+ * @param bool   $exclude_admin
+ * @param bool   $show_fullname
+ * @param bool   $hide_empty
  * @param string $feed
  * @param string $feed_image
  * @return null|string
  */
-function list_authors($optioncount = false, $exclude_admin = true, $show_fullname = false, $hide_empty = true, $feed = '', $feed_image = '') {
+function list_authors( $optioncount = false, $exclude_admin = true, $show_fullname = false, $hide_empty = true, $feed = '', $feed_image = '' ) {
 	_deprecated_function( __FUNCTION__, '2.1.0', 'wp_list_authors()' );
 
-	$args = compact('optioncount', 'exclude_admin', 'show_fullname', 'hide_empty', 'feed', 'feed_image');
-	return wp_list_authors($args);
+	$args = compact( 'optioncount', 'exclude_admin', 'show_fullname', 'hide_empty', 'feed', 'feed_image' );
+	return wp_list_authors( $args );
 }
 
 /**
@@ -746,9 +851,9 @@ function list_authors($optioncount = false, $exclude_admin = true, $show_fullnam
  * @param int $post_id
  * @return array
  */
-function wp_get_post_cats($blogid = '1', $post_id = 0) {
+function wp_get_post_cats( $blogid = '1', $post_id = 0 ) {
 	_deprecated_function( __FUNCTION__, '2.1.0', 'wp_get_post_categories()' );
-	return wp_get_post_categories($post_id);
+	return wp_get_post_categories( $post_id );
 }
 
 /**
@@ -759,14 +864,14 @@ function wp_get_post_cats($blogid = '1', $post_id = 0) {
  * @deprecated Use wp_set_post_categories()
  * @see wp_set_post_categories()
  *
- * @param int $blogid Not used
- * @param int $post_id
+ * @param int   $blogid Not used
+ * @param int   $post_id
  * @param array $post_categories
  * @return bool|mixed
  */
-function wp_set_post_cats($blogid = '1', $post_id = 0, $post_categories = array()) {
+function wp_set_post_cats( $blogid = '1', $post_id = 0, $post_categories = array() ) {
 	_deprecated_function( __FUNCTION__, '2.1.0', 'wp_set_post_categories()' );
-	return wp_set_post_categories($post_id, $post_categories);
+	return wp_set_post_categories( $post_id, $post_categories );
 }
 
 /**
@@ -781,13 +886,13 @@ function wp_set_post_cats($blogid = '1', $post_id = 0, $post_categories = array(
  * @param string $format
  * @param string $before
  * @param string $after
- * @param bool $show_post_count
+ * @param bool   $show_post_count
  * @return string|null
  */
-function get_archives($type='', $limit='', $format='html', $before = '', $after = '', $show_post_count = false) {
+function get_archives( $type = '', $limit = '', $format = 'html', $before = '', $after = '', $show_post_count = false ) {
 	_deprecated_function( __FUNCTION__, '2.1.0', 'wp_get_archives()' );
-	$args = compact('type', 'limit', 'format', 'before', 'after', 'show_post_count');
-	return wp_get_archives($args);
+	$args = compact( 'type', 'limit', 'format', 'before', 'after', 'show_post_count' );
+	return wp_get_archives( $args );
 }
 
 /**
@@ -797,18 +902,19 @@ function get_archives($type='', $limit='', $format='html', $before = '', $after
  * @deprecated 2.1.0 Use get_author_posts_url()
  * @see get_author_posts_url()
  *
- * @param bool $display
- * @param int $author_id
+ * @param bool   $display
+ * @param int    $author_id
  * @param string $author_nicename Optional.
  * @return string|null
  */
-function get_author_link($display, $author_id, $author_nicename = '') {
+function get_author_link( $display, $author_id, $author_nicename = '' ) {
 	_deprecated_function( __FUNCTION__, '2.1.0', 'get_author_posts_url()' );
 
-	$link = get_author_posts_url($author_id, $author_nicename);
+	$link = get_author_posts_url( $author_id, $author_nicename );
 
-	if ( $display )
+	if ( $display ) {
 		echo $link;
+	}
 	return $link;
 }
 
@@ -828,12 +934,19 @@ function get_author_link($display, $author_id, $author_nicename = '') {
  * @param string $more_file
  * @return string
  */
-function link_pages($before='<br />', $after='<br />', $next_or_number='number', $nextpagelink='next page', $previouspagelink='previous page',
-					$pagelink='%', $more_file='') {
+function link_pages(
+	$before = '<br />',
+	$after = '<br />',
+	$next_or_number = 'number',
+	$nextpagelink = 'next page',
+	$previouspagelink = 'previous page',
+	$pagelink = '%',
+	$more_file = ''
+) {
 	_deprecated_function( __FUNCTION__, '2.1.0', 'wp_link_pages()' );
 
-	$args = compact('before', 'after', 'next_or_number', 'nextpagelink', 'previouspagelink', 'pagelink', 'more_file');
-	return wp_link_pages($args);
+	$args = compact( 'before', 'after', 'next_or_number', 'nextpagelink', 'previouspagelink', 'pagelink', 'more_file' );
+	return wp_link_pages( $args );
 }
 
 /**
@@ -846,10 +959,10 @@ function link_pages($before='<br />', $after='<br />', $next_or_number='number',
  * @param string $option
  * @return string
  */
-function get_settings($option) {
+function get_settings( $option ) {
 	_deprecated_function( __FUNCTION__, '2.1.0', 'get_option()' );
 
-	return get_option($option);
+	return get_option( $option );
 }
 
 /**
@@ -873,7 +986,7 @@ function permalink_link() {
  *
  * @param string $deprecated
  */
-function permalink_single_rss($deprecated = '') {
+function permalink_single_rss( $deprecated = '' ) {
 	_deprecated_function( __FUNCTION__, '2.3.0', 'the_permalink_rss()' );
 	the_permalink_rss();
 }
@@ -888,33 +1001,33 @@ function permalink_single_rss($deprecated = '') {
  * @param string $args a query string
  * @return null|string
  */
-function wp_get_links($args = '') {
+function wp_get_links( $args = '' ) {
 	_deprecated_function( __FUNCTION__, '2.1.0', 'wp_list_bookmarks()' );
 
 	if ( ! str_contains( $args, '=' ) ) {
 		$cat_id = $args;
-		$args = add_query_arg( 'category', $cat_id, $args );
+		$args   = add_query_arg( 'category', $cat_id, $args );
 	}
 
 	$defaults = array(
-		'after' => '<br />',
-		'before' => '',
-		'between' => ' ',
-		'categorize' => 0,
-		'category' => '',
-		'echo' => true,
-		'limit' => -1,
-		'orderby' => 'name',
+		'after'            => '<br />',
+		'before'           => '',
+		'between'          => ' ',
+		'categorize'       => 0,
+		'category'         => '',
+		'echo'             => true,
+		'limit'            => -1,
+		'orderby'          => 'name',
 		'show_description' => true,
-		'show_images' => true,
-		'show_rating' => false,
-		'show_updated' => true,
-		'title_li' => '',
+		'show_images'      => true,
+		'show_rating'      => false,
+		'show_updated'     => true,
+		'title_li'         => '',
 	);
 
 	$parsed_args = wp_parse_args( $args, $defaults );
 
-	return wp_list_bookmarks($parsed_args);
+	return wp_list_bookmarks( $parsed_args );
 }
 
 /**
@@ -944,84 +1057,117 @@ function wp_get_links($args = '') {
  * @param bool   $display          Whether to display the results, or return them instead.
  * @return null|string
  */
-function get_links($category = -1, $before = '', $after = '<br />', $between = ' ', $show_images = true, $orderby = 'name',
-			$show_description = true, $show_rating = false, $limit = -1, $show_updated = 1, $display = true) {
+function get_links(
+	$category = -1,
+	$before = '',
+	$after = '<br />',
+	$between = ' ',
+	$show_images = true,
+	$orderby = 'name',
+	$show_description = true,
+	$show_rating = false,
+	$limit = -1,
+	$show_updated = 1,
+	$display = true
+) {
 	_deprecated_function( __FUNCTION__, '2.1.0', 'get_bookmarks()' );
 
 	$order = 'ASC';
-	if ( str_starts_with($orderby, '_') ) {
-		$order = 'DESC';
-		$orderby = substr($orderby, 1);
+	if ( str_starts_with( $orderby, '_' ) ) {
+		$order   = 'DESC';
+		$orderby = substr( $orderby, 1 );
 	}
 
-	if ( $category == -1 ) // get_bookmarks() uses '' to signify all categories.
+	if ( $category == -1 ) { // get_bookmarks() uses '' to signify all categories.
 		$category = '';
+	}
 
-	$results = get_bookmarks(array('category' => $category, 'orderby' => $orderby, 'order' => $order, 'show_updated' => $show_updated, 'limit' => $limit));
+	$results = get_bookmarks(
+		array(
+			'category'     => $category,
+			'orderby'      => $orderby,
+			'order'        => $order,
+			'show_updated' => $show_updated,
+			'limit'        => $limit,
+		)
+	);
 
-	if ( !$results )
+	if ( ! $results ) {
 		return;
+	}
 
 	$output = '';
 
 	foreach ( (array) $results as $row ) {
-		if ( !isset($row->recently_updated) )
+		if ( ! isset( $row->recently_updated ) ) {
 			$row->recently_updated = false;
+		}
 		$output .= $before;
-		if ( $show_updated && $row->recently_updated )
-			$output .= get_option('links_recently_updated_prepend');
+		if ( $show_updated && $row->recently_updated ) {
+			$output .= get_option( 'links_recently_updated_prepend' );
+		}
 		$the_link = '#';
-		if ( !empty($row->link_url) )
-			$the_link = esc_url($row->link_url);
+		if ( ! empty( $row->link_url ) ) {
+			$the_link = esc_url( $row->link_url );
+		}
 		$rel = $row->link_rel;
-		if ( '' != $rel )
+		if ( '' != $rel ) {
 			$rel = ' rel="' . $rel . '"';
+		}
 
-		$desc = esc_attr(sanitize_bookmark_field('link_description', $row->link_description, $row->link_id, 'display'));
-		$name = esc_attr(sanitize_bookmark_field('link_name', $row->link_name, $row->link_id, 'display'));
+		$desc  = esc_attr( sanitize_bookmark_field( 'link_description', $row->link_description, $row->link_id, 'display' ) );
+		$name  = esc_attr( sanitize_bookmark_field( 'link_name', $row->link_name, $row->link_id, 'display' ) );
 		$title = $desc;
 
-		if ( $show_updated )
-			if ( !str_starts_with($row->link_updated_f, '00') )
-				$title .= ' ('.__('Last updated') . ' ' . gmdate(get_option('links_updated_date_format'), $row->link_updated_f + (get_option('gmt_offset') * HOUR_IN_SECONDS)) . ')';
+		if ( $show_updated ) {
+			if ( ! str_starts_with( $row->link_updated_f, '00' ) ) {
+				$title .= ' (' . __( 'Last updated' ) . ' ' . gmdate( get_option( 'links_updated_date_format' ), $row->link_updated_f + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) ) . ')';
+			}
+		}
 
-		if ( '' != $title )
+		if ( '' != $title ) {
 			$title = ' title="' . $title . '"';
+		}
 
 		$alt = ' alt="' . $name . '"';
 
 		$target = $row->link_target;
-		if ( '' != $target )
+		if ( '' != $target ) {
 			$target = ' target="' . $target . '"';
+		}
 
-		$output .= '<a href="' . $the_link . '"' . $rel . $title . $target. '>';
+		$output .= '<a href="' . $the_link . '"' . $rel . $title . $target . '>';
 
 		if ( '' != $row->link_image && $show_images ) {
-			if ( str_contains( $row->link_image, 'http' ) )
+			if ( str_contains( $row->link_image, 'http' ) ) {
 				$output .= '<img src="' . $row->link_image . '"' . $alt . $title . ' />';
-			else // If it's a relative path.
-				$output .= '<img src="' . get_option('siteurl') . $row->link_image . '"' . $alt . $title . ' />';
+			} else { // If it's a relative path.
+				$output .= '<img src="' . get_option( 'siteurl' ) . $row->link_image . '"' . $alt . $title . ' />';
+			}
 		} else {
 			$output .= $name;
 		}
 
 		$output .= '</a>';
 
-		if ( $show_updated && $row->recently_updated )
-			$output .= get_option('links_recently_updated_append');
+		if ( $show_updated && $row->recently_updated ) {
+			$output .= get_option( 'links_recently_updated_append' );
+		}
 
-		if ( $show_description && '' != $desc )
+		if ( $show_description && '' != $desc ) {
 			$output .= $between . $desc;
+		}
 
-		if ($show_rating) {
-			$output .= $between . get_linkrating($row);
+		if ( $show_rating ) {
+			$output .= $between . get_linkrating( $row );
 		}
 
 		$output .= "$after\n";
 	} // End while.
 
-	if ( !$display )
+	if ( ! $display ) {
 		return $output;
+	}
 	echo $output;
 }
 
@@ -1037,22 +1183,30 @@ function get_links($category = -1, $before = '', $after = '<br />', $between = '
  *
  * @param string $order Sort link categories by 'name' or 'id'
  */
-function get_links_list($order = 'name') {
+function get_links_list( $order = 'name' ) {
 	_deprecated_function( __FUNCTION__, '2.1.0', 'wp_list_bookmarks()' );
 
-	$order = strtolower($order);
+	$order = strtolower( $order );
 
 	// Handle link category sorting.
 	$direction = 'ASC';
 	if ( str_starts_with( $order, '_' ) ) {
 		$direction = 'DESC';
-		$order = substr($order,1);
+		$order     = substr( $order, 1 );
 	}
 
-	if ( !isset($direction) )
+	if ( ! isset( $direction ) ) {
 		$direction = '';
+	}
 
-	$cats = get_categories(array('type' => 'link', 'orderby' => $order, 'order' => $direction, 'hierarchical' => 0));
+	$cats = get_categories(
+		array(
+			'type'         => 'link',
+			'orderby'      => $order,
+			'order'        => $direction,
+			'hierarchical' => 0,
+		)
+	);
 
 	// Display each category.
 	if ( $cats ) {
@@ -1060,9 +1214,9 @@ function get_links_list($order = 'name') {
 			// Handle each category.
 
 			// Display the category name.
-			echo '  <li id="linkcat-' . $cat->term_id . '" class="linkcat"><h2>' . apply_filters('link_category', $cat->name ) . "</h2>\n\t<ul>\n";
+			echo '  <li id="linkcat-' . $cat->term_id . '" class="linkcat"><h2>' . apply_filters( 'link_category', $cat->name ) . "</h2>\n\t<ul>\n";
 			// Call get_links() with all the appropriate params.
-			get_links($cat->term_id, '<li>', "</li>", "\n", true, 'name', false);
+			get_links( $cat->term_id, '<li>', '</li>', "\n", true, 'name', false );
 
 			// Close the last category.
 			echo "\n\t</ul>\n</li>\n";
@@ -1077,12 +1231,12 @@ function get_links_list($order = 'name') {
  * @deprecated 2.1.0
  *
  * @param string $text the text of the link
- * @param int $width the width of the popup window
- * @param int $height the height of the popup window
+ * @param int    $width the width of the popup window
+ * @param int    $height the height of the popup window
  * @param string $file the page to open in the popup window
- * @param bool $count the number of links in the db
+ * @param bool   $count the number of links in the db
  */
-function links_popup_script($text = 'Links', $width=400, $height=400, $file='links.all.php', $count = true) {
+function links_popup_script( $text = 'Links', $width = 400, $height = 400, $file = 'links.all.php', $count = true ) {
 	_deprecated_function( __FUNCTION__, '2.1.0' );
 }
 
@@ -1098,7 +1252,7 @@ function links_popup_script($text = 'Links', $width=400, $height=400, $file='lin
  */
 function get_linkrating( $link ) {
 	_deprecated_function( __FUNCTION__, '2.1.0', 'sanitize_bookmark_field()' );
-	return sanitize_bookmark_field('link_rating', $link->link_rating, $link->link_id, 'display');
+	return sanitize_bookmark_field( 'link_rating', $link->link_rating, $link->link_id, 'display' );
 }
 
 /**
@@ -1111,22 +1265,24 @@ function get_linkrating( $link ) {
  * @param int $id The category to get. If no category supplied uses 0
  * @return string
  */
-function get_linkcatname($id = 0) {
+function get_linkcatname( $id = 0 ) {
 	_deprecated_function( __FUNCTION__, '2.1.0', 'get_category()' );
 
 	$id = (int) $id;
 
-	if ( empty($id) )
+	if ( empty( $id ) ) {
 		return '';
+	}
 
-	$cats = wp_get_link_cats($id);
+	$cats = wp_get_link_cats( $id );
 
-	if ( empty($cats) || ! is_array($cats) )
+	if ( empty( $cats ) || ! is_array( $cats ) ) {
 		return '';
+	}
 
 	$cat_id = (int) $cats[0]; // Take the first cat.
 
-	$cat = get_category($cat_id);
+	$cat = get_category( $cat_id );
 	return $cat->name;
 }
 
@@ -1139,9 +1295,9 @@ function get_linkcatname($id = 0) {
  *
  * @param string $link_text
  */
-function comments_rss_link($link_text = 'Comments RSS') {
+function comments_rss_link( $link_text = 'Comments RSS' ) {
 	_deprecated_function( __FUNCTION__, '2.5.0', 'post_comments_feed_link()' );
-	post_comments_feed_link($link_text);
+	post_comments_feed_link( $link_text );
 }
 
 /**
@@ -1152,16 +1308,17 @@ function comments_rss_link($link_text = 'Comments RSS') {
  * @see get_category_feed_link()
  *
  * @param bool $display
- * @param int $cat_id
+ * @param int  $cat_id
  * @return string
  */
-function get_category_rss_link($display = false, $cat_id = 1) {
+function get_category_rss_link( $display = false, $cat_id = 1 ) {
 	_deprecated_function( __FUNCTION__, '2.5.0', 'get_category_feed_link()' );
 
-	$link = get_category_feed_link($cat_id, 'rss2');
+	$link = get_category_feed_link( $cat_id, 'rss2' );
 
-	if ( $display )
+	if ( $display ) {
 		echo $link;
+	}
 	return $link;
 }
 
@@ -1173,15 +1330,16 @@ function get_category_rss_link($display = false, $cat_id = 1) {
  * @see get_author_feed_link()
  *
  * @param bool $display
- * @param int $author_id
+ * @param int  $author_id
  * @return string
  */
-function get_author_rss_link($display = false, $author_id = 1) {
+function get_author_rss_link( $display = false, $author_id = 1 ) {
 	_deprecated_function( __FUNCTION__, '2.5.0', 'get_author_feed_link()' );
 
-	$link = get_author_feed_link($author_id);
-	if ( $display )
+	$link = get_author_feed_link( $author_id );
+	if ( $display ) {
 		echo $link;
+	}
 	return $link;
 }
 
@@ -1211,9 +1369,9 @@ function comments_rss() {
  * @param string $email    The user's email.
  * @return int The new user's ID.
  */
-function create_user($username, $password, $email) {
+function create_user( $username, $password, $email ) {
 	_deprecated_function( __FUNCTION__, '2.0.0', 'wp_create_user()' );
-	return wp_create_user($username, $password, $email);
+	return wp_create_user( $username, $password, $email );
 }
 
 /**
@@ -1233,14 +1391,14 @@ function gzip_compression() {
  * @deprecated 2.7.0 Use get_comment()
  * @see get_comment()
  *
- * @param int $comment_id The ID of the comment
- * @param int $no_cache Whether to use the cache (cast to bool)
+ * @param int  $comment_id The ID of the comment
+ * @param int  $no_cache Whether to use the cache (cast to bool)
  * @param bool $include_unapproved Whether to include unapproved comments
  * @return array The comment data
  */
 function get_commentdata( $comment_id, $no_cache = 0, $include_unapproved = false ) {
 	_deprecated_function( __FUNCTION__, '2.7.0', 'get_comment()' );
-	return get_comment($comment_id, ARRAY_A);
+	return get_comment( $comment_id, ARRAY_A );
 }
 
 /**
@@ -1274,23 +1432,26 @@ function get_catname( $cat_id ) {
  */
 function get_category_children( $id, $before = '/', $after = '', $visited = array() ) {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'get_term_children()' );
-	if ( 0 == $id )
+	if ( 0 == $id ) {
 		return '';
+	}
 
 	$chain = '';
 	/** TODO: Consult hierarchy */
 	$cat_ids = get_all_category_ids();
 	foreach ( (array) $cat_ids as $cat_id ) {
-		if ( $cat_id == $id )
+		if ( $cat_id == $id ) {
 			continue;
+		}
 
 		$category = get_category( $cat_id );
-		if ( is_wp_error( $category ) )
+		if ( is_wp_error( $category ) ) {
 			return $category;
-		if ( $category->parent == $id && !in_array( $category->term_id, $visited ) ) {
+		}
+		if ( $category->parent == $id && ! in_array( $category->term_id, $visited ) ) {
 			$visited[] = $category->term_id;
-			$chain .= $before.$category->term_id.$after;
-			$chain .= get_category_children( $category->term_id, $before, $after );
+			$chain    .= $before . $category->term_id . $after;
+			$chain    .= get_category_children( $category->term_id, $before, $after );
 		}
 	}
 	return $chain;
@@ -1332,7 +1493,7 @@ function get_all_category_ids() {
  */
 function get_the_author_description() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'description\')' );
-	return get_the_author_meta('description');
+	return get_the_author_meta( 'description' );
 }
 
 /**
@@ -1344,7 +1505,7 @@ function get_the_author_description() {
  */
 function the_author_description() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'description\')' );
-	the_author_meta('description');
+	the_author_meta( 'description' );
 }
 
 /**
@@ -1358,7 +1519,7 @@ function the_author_description() {
  */
 function get_the_author_login() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'login\')' );
-	return get_the_author_meta('login');
+	return get_the_author_meta( 'login' );
 }
 
 /**
@@ -1370,7 +1531,7 @@ function get_the_author_login() {
  */
 function the_author_login() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'login\')' );
-	the_author_meta('login');
+	the_author_meta( 'login' );
 }
 
 /**
@@ -1384,7 +1545,7 @@ function the_author_login() {
  */
 function get_the_author_firstname() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'first_name\')' );
-	return get_the_author_meta('first_name');
+	return get_the_author_meta( 'first_name' );
 }
 
 /**
@@ -1396,7 +1557,7 @@ function get_the_author_firstname() {
  */
 function the_author_firstname() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'first_name\')' );
-	the_author_meta('first_name');
+	the_author_meta( 'first_name' );
 }
 
 /**
@@ -1410,7 +1571,7 @@ function the_author_firstname() {
  */
 function get_the_author_lastname() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'last_name\')' );
-	return get_the_author_meta('last_name');
+	return get_the_author_meta( 'last_name' );
 }
 
 /**
@@ -1422,7 +1583,7 @@ function get_the_author_lastname() {
  */
 function the_author_lastname() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'last_name\')' );
-	the_author_meta('last_name');
+	the_author_meta( 'last_name' );
 }
 
 /**
@@ -1436,7 +1597,7 @@ function the_author_lastname() {
  */
 function get_the_author_nickname() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'nickname\')' );
-	return get_the_author_meta('nickname');
+	return get_the_author_meta( 'nickname' );
 }
 
 /**
@@ -1448,7 +1609,7 @@ function get_the_author_nickname() {
  */
 function the_author_nickname() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'nickname\')' );
-	the_author_meta('nickname');
+	the_author_meta( 'nickname' );
 }
 
 /**
@@ -1462,7 +1623,7 @@ function the_author_nickname() {
  */
 function get_the_author_email() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'email\')' );
-	return get_the_author_meta('email');
+	return get_the_author_meta( 'email' );
 }
 
 /**
@@ -1474,7 +1635,7 @@ function get_the_author_email() {
  */
 function the_author_email() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'email\')' );
-	the_author_meta('email');
+	the_author_meta( 'email' );
 }
 
 /**
@@ -1488,7 +1649,7 @@ function the_author_email() {
  */
 function get_the_author_icq() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'icq\')' );
-	return get_the_author_meta('icq');
+	return get_the_author_meta( 'icq' );
 }
 
 /**
@@ -1500,7 +1661,7 @@ function get_the_author_icq() {
  */
 function the_author_icq() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'icq\')' );
-	the_author_meta('icq');
+	the_author_meta( 'icq' );
 }
 
 /**
@@ -1514,7 +1675,7 @@ function the_author_icq() {
  */
 function get_the_author_yim() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'yim\')' );
-	return get_the_author_meta('yim');
+	return get_the_author_meta( 'yim' );
 }
 
 /**
@@ -1526,7 +1687,7 @@ function get_the_author_yim() {
  */
 function the_author_yim() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'yim\')' );
-	the_author_meta('yim');
+	the_author_meta( 'yim' );
 }
 
 /**
@@ -1540,7 +1701,7 @@ function the_author_yim() {
  */
 function get_the_author_msn() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'msn\')' );
-	return get_the_author_meta('msn');
+	return get_the_author_meta( 'msn' );
 }
 
 /**
@@ -1552,7 +1713,7 @@ function get_the_author_msn() {
  */
 function the_author_msn() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'msn\')' );
-	the_author_meta('msn');
+	the_author_meta( 'msn' );
 }
 
 /**
@@ -1566,7 +1727,7 @@ function the_author_msn() {
  */
 function get_the_author_aim() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'aim\')' );
-	return get_the_author_meta('aim');
+	return get_the_author_meta( 'aim' );
 }
 
 /**
@@ -1578,7 +1739,7 @@ function get_the_author_aim() {
  */
 function the_author_aim() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'aim\')' );
-	the_author_meta('aim');
+	the_author_meta( 'aim' );
 }
 
 /**
@@ -1593,7 +1754,7 @@ function the_author_aim() {
  */
 function get_author_name( $auth_id = false ) {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'display_name\')' );
-	return get_the_author_meta('display_name', $auth_id);
+	return get_the_author_meta( 'display_name', $auth_id );
 }
 
 /**
@@ -1607,7 +1768,7 @@ function get_author_name( $auth_id = false ) {
  */
 function get_the_author_url() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'url\')' );
-	return get_the_author_meta('url');
+	return get_the_author_meta( 'url' );
 }
 
 /**
@@ -1619,7 +1780,7 @@ function get_the_author_url() {
  */
 function the_author_url() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'url\')' );
-	the_author_meta('url');
+	the_author_meta( 'url' );
 }
 
 /**
@@ -1633,7 +1794,7 @@ function the_author_url() {
  */
 function get_the_author_ID() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'get_the_author_meta(\'ID\')' );
-	return get_the_author_meta('ID');
+	return get_the_author_meta( 'ID' );
 }
 
 /**
@@ -1645,7 +1806,7 @@ function get_the_author_ID() {
  */
 function the_author_ID() {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'the_author_meta(\'ID\')' );
-	the_author_meta('ID');
+	the_author_meta( 'ID' );
 }
 
 /**
@@ -1677,9 +1838,9 @@ function the_author_ID() {
  * @param int    $cut            Optional. Amount of words to keep for the content.
  * @param int    $encode_html    Optional. How to encode the content.
  */
-function the_content_rss($more_link_text='(more...)', $stripteaser=0, $more_file='', $cut = 0, $encode_html = 0) {
+function the_content_rss( $more_link_text = '(more...)', $stripteaser = 0, $more_file = '', $cut = 0, $encode_html = 0 ) {
 	_deprecated_function( __FUNCTION__, '2.9.0', 'the_content_feed()' );
-	$content = get_the_content($more_link_text, $stripteaser);
+	$content = get_the_content( $more_link_text, $stripteaser );
 
 	/**
 	 * Filters the post content in the context of an RSS feed.
@@ -1688,34 +1849,36 @@ function the_content_rss($more_link_text='(more...)', $stripteaser=0, $more_file
 	 *
 	 * @param string $content Content of the current post.
 	 */
-	$content = apply_filters('the_content_rss', $content);
-	if ( $cut && !$encode_html )
+	$content = apply_filters( 'the_content_rss', $content );
+	if ( $cut && ! $encode_html ) {
 		$encode_html = 2;
-	if ( 1== $encode_html ) {
-		$content = esc_html($content);
-		$cut = 0;
+	}
+	if ( 1 == $encode_html ) {
+		$content = esc_html( $content );
+		$cut     = 0;
 	} elseif ( 0 == $encode_html ) {
-		$content = make_url_footnote($content);
+		$content = make_url_footnote( $content );
 	} elseif ( 2 == $encode_html ) {
-		$content = strip_tags($content);
+		$content = wp_strip_all_tags( $content );
 	}
 	if ( $cut ) {
-		$blah = explode(' ', $content);
-		if ( count($blah) > $cut ) {
-			$k = $cut;
+		$blah = explode( ' ', $content );
+		if ( count( $blah ) > $cut ) {
+			$k             = $cut;
 			$use_dotdotdot = 1;
 		} else {
-			$k = count($blah);
+			$k             = count( $blah );
 			$use_dotdotdot = 0;
 		}
 
 		/** @todo Check performance, might be faster to use array slice instead. */
-		for ( $i=0; $i<$k; $i++ )
-			$excerpt .= $blah[$i].' ';
-		$excerpt .= ($use_dotdotdot) ? '...' : '';
-		$content = $excerpt;
+		for ( $i = 0; $i < $k; $i++ ) {
+			$excerpt .= $blah[ $i ] . ' ';
+		}
+		$excerpt .= ( $use_dotdotdot ) ? '...' : '';
+		$content  = $excerpt;
 	}
-	$content = str_replace(']]>', ']]&gt;', $content);
+	$content = str_replace( ']]>', ']]&gt;', $content );
 	echo $content;
 }
 
@@ -1736,15 +1899,15 @@ function make_url_footnote( $content ) {
 	preg_match_all( '/<a(.+?)href=\"(.+?)\"(.*?)>(.+?)<\/a>/', $content, $matches );
 	$links_summary = "\n";
 	for ( $i = 0, $c = count( $matches[0] ); $i < $c; $i++ ) {
-		$link_match = $matches[0][$i];
-		$link_number = '['.($i+1).']';
-		$link_url = $matches[2][$i];
-		$link_text = $matches[4][$i];
-		$content = str_replace( $link_match, $link_text . ' ' . $link_number, $content );
-		$link_url = ( ( strtolower( substr( $link_url, 0, 7 ) ) !== 'http://' ) && ( strtolower( substr( $link_url, 0, 8 ) ) !== 'https://' ) ) ? get_option( 'home' ) . $link_url : $link_url;
+		$link_match     = $matches[0][ $i ];
+		$link_number    = '[' . ( $i + 1 ) . ']';
+		$link_url       = $matches[2][ $i ];
+		$link_text      = $matches[4][ $i ];
+		$content        = str_replace( $link_match, $link_text . ' ' . $link_number, $content );
+		$link_url       = ( ( strtolower( substr( $link_url, 0, 7 ) ) !== 'http://' ) && ( strtolower( substr( $link_url, 0, 8 ) ) !== 'https://' ) ) ? get_option( 'home' ) . $link_url : $link_url;
 		$links_summary .= "\n" . $link_number . ' ' . $link_url;
 	}
-	$content  = strip_tags( $content );
+	$content  = wp_strip_all_tags( $content );
 	$content .= $links_summary;
 	return $content;
 }
@@ -1835,7 +1998,6 @@ function __ngettext( ...$args ) { // phpcs:ignore PHPCompatibility.FunctionNameR
 function __ngettext_noop( ...$args ) { // phpcs:ignore PHPCompatibility.FunctionNameRestrictions.ReservedFunctionNames.FunctionDoubleUnderscore
 	_deprecated_function( __FUNCTION__, '2.8.0', '_n_noop()' );
 	return _n_noop( ...$args );
-
 }
 
 /**
@@ -1862,23 +2024,25 @@ function get_alloptions() {
  * @param int   $id       Optional. Post ID.
  * @param bool  $fullsize Optional. Whether to use full size image. Default false.
  * @param array $max_dims Optional. Max image dimensions.
- * @param bool $permalink Optional. Whether to include permalink to image. Default false.
+ * @param bool  $permalink Optional. Whether to include permalink to image. Default false.
  * @return string
  */
-function get_the_attachment_link($id = 0, $fullsize = false, $max_dims = false, $permalink = false) {
+function get_the_attachment_link( $id = 0, $fullsize = false, $max_dims = false, $permalink = false ) {
 	_deprecated_function( __FUNCTION__, '2.5.0', 'wp_get_attachment_link()' );
-	$id = (int) $id;
-	$_post = get_post($id);
+	$id    = (int) $id;
+	$_post = get_post( $id );
 
-	if ( ('attachment' != $_post->post_type) || !$url = wp_get_attachment_url($_post->ID) )
-		return __('Missing Attachment');
+	if ( ( 'attachment' != $_post->post_type ) || ! $url = wp_get_attachment_url( $_post->ID ) ) {
+		return __( 'Missing Attachment' );
+	}
 
-	if ( $permalink )
-		$url = get_attachment_link($_post->ID);
+	if ( $permalink ) {
+		$url = get_attachment_link( $_post->ID );
+	}
 
-	$post_title = esc_attr($_post->post_title);
+	$post_title = esc_attr( $_post->post_title );
 
-	$innerHTML = get_attachment_innerHTML($_post->ID, $fullsize, $max_dims);
+	$innerHTML = get_attachment_innerHTML( $_post->ID, $fullsize, $max_dims );
 	return "<a href='$url' title='$post_title'>$innerHTML</a>";
 }
 
@@ -1896,32 +2060,34 @@ function get_the_attachment_link($id = 0, $fullsize = false, $max_dims = false,
 function get_attachment_icon_src( $id = 0, $fullsize = false ) {
 	_deprecated_function( __FUNCTION__, '2.5.0', 'wp_get_attachment_image_src()' );
 	$id = (int) $id;
-	if ( !$post = get_post($id) )
+	if ( ! $post = get_post( $id ) ) {
 		return false;
+	}
 
 	$file = get_attached_file( $post->ID );
 
-	if ( !$fullsize && $src = wp_get_attachment_thumb_url( $post->ID ) ) {
+	if ( ! $fullsize && $src = wp_get_attachment_thumb_url( $post->ID ) ) {
 		// We have a thumbnail desired, specified and existing.
 
-		$src_file = wp_basename($src);
+		$src_file = wp_basename( $src );
 	} elseif ( wp_attachment_is_image( $post->ID ) ) {
 		// We have an image without a thumbnail.
 
-		$src = wp_get_attachment_url( $post->ID );
+		$src      = wp_get_attachment_url( $post->ID );
 		$src_file = & $file;
 	} elseif ( $src = wp_mime_type_icon( $post->ID, '.svg' ) ) {
 		// No thumb, no image. We'll look for a mime-related icon instead.
 
 		/** This filter is documented in wp-includes/post.php */
 		$icon_dir = apply_filters( 'icon_dir', get_template_directory() . '/images' );
-		$src_file = $icon_dir . '/' . wp_basename($src);
+		$src_file = $icon_dir . '/' . wp_basename( $src );
 	}
 
-	if ( !isset($src) || !$src )
+	if ( ! isset( $src ) || ! $src ) {
 		return false;
+	}
 
-	return array($src, $src_file);
+	return array( $src, $src_file );
 }
 
 /**
@@ -1939,41 +2105,43 @@ function get_attachment_icon_src( $id = 0, $fullsize = false ) {
 function get_attachment_icon( $id = 0, $fullsize = false, $max_dims = false ) {
 	_deprecated_function( __FUNCTION__, '2.5.0', 'wp_get_attachment_image()' );
 	$id = (int) $id;
-	if ( !$post = get_post($id) )
+	if ( ! $post = get_post( $id ) ) {
 		return false;
+	}
 
-	if ( !$src = get_attachment_icon_src( $post->ID, $fullsize ) )
+	if ( ! $src = get_attachment_icon_src( $post->ID, $fullsize ) ) {
 		return false;
+	}
 
 	list($src, $src_file) = $src;
 
 	// Do we need to constrain the image?
-	if ( ($max_dims = apply_filters('attachment_max_dims', $max_dims)) && file_exists($src_file) ) {
+	if ( ( $max_dims = apply_filters( 'attachment_max_dims', $max_dims ) ) && file_exists( $src_file ) ) {
 
-		$imagesize = wp_getimagesize($src_file);
+		$imagesize = wp_getimagesize( $src_file );
 
-		if (($imagesize[0] > $max_dims[0]) || $imagesize[1] > $max_dims[1] ) {
-			$actual_aspect = $imagesize[0] / $imagesize[1];
+		if ( ( $imagesize[0] > $max_dims[0] ) || $imagesize[1] > $max_dims[1] ) {
+			$actual_aspect  = $imagesize[0] / $imagesize[1];
 			$desired_aspect = $max_dims[0] / $max_dims[1];
 
 			if ( $actual_aspect >= $desired_aspect ) {
-				$height = $actual_aspect * $max_dims[0];
-				$constraint = "width='{$max_dims[0]}' ";
-				$post->iconsize = array($max_dims[0], $height);
+				$height         = $actual_aspect * $max_dims[0];
+				$constraint     = "width='{$max_dims[0]}' ";
+				$post->iconsize = array( $max_dims[0], $height );
 			} else {
-				$width = $max_dims[1] / $actual_aspect;
-				$constraint = "height='{$max_dims[1]}' ";
-				$post->iconsize = array($width, $max_dims[1]);
+				$width          = $max_dims[1] / $actual_aspect;
+				$constraint     = "height='{$max_dims[1]}' ";
+				$post->iconsize = array( $width, $max_dims[1] );
 			}
 		} else {
-			$post->iconsize = array($imagesize[0], $imagesize[1]);
-			$constraint = '';
+			$post->iconsize = array( $imagesize[0], $imagesize[1] );
+			$constraint     = '';
 		}
 	} else {
 		$constraint = '';
 	}
 
-	$post_title = esc_attr($post->post_title);
+	$post_title = esc_attr( $post->post_title );
 
 	$icon = "<img src='$src' title='$post_title' alt='$post_title' $constraint/>";
 
@@ -1992,18 +2160,20 @@ function get_attachment_icon( $id = 0, $fullsize = false, $max_dims = false ) {
  * @param array $max_dims Optional. Dimensions of image.
  * @return string|false
  */
-function get_attachment_innerHTML($id = 0, $fullsize = false, $max_dims = false) {
+function get_attachment_innerHTML( $id = 0, $fullsize = false, $max_dims = false ) {
 	_deprecated_function( __FUNCTION__, '2.5.0', 'wp_get_attachment_image()' );
 	$id = (int) $id;
-	if ( !$post = get_post($id) )
+	if ( ! $post = get_post( $id ) ) {
 		return false;
+	}
 
-	if ( $innerHTML = get_attachment_icon($post->ID, $fullsize, $max_dims))
+	if ( $innerHTML = get_attachment_icon( $post->ID, $fullsize, $max_dims ) ) {
 		return $innerHTML;
+	}
 
-	$innerHTML = esc_attr($post->post_title);
+	$innerHTML = esc_attr( $post->post_title );
 
-	return apply_filters('attachment_innerHTML', $innerHTML, $post->ID);
+	return apply_filters( 'attachment_innerHTML', $innerHTML, $post->ID );
 }
 
 /**
@@ -2022,7 +2192,7 @@ function get_attachment_innerHTML($id = 0, $fullsize = false, $max_dims = false)
  */
 function get_link( $bookmark_id, $output = OBJECT, $filter = 'raw' ) {
 	_deprecated_function( __FUNCTION__, '2.1.0', 'get_bookmark()' );
-	return get_bookmark($bookmark_id, $output, $filter);
+	return get_bookmark( $bookmark_id, $output, $filter );
 }
 
 /**
@@ -2037,15 +2207,16 @@ function get_link( $bookmark_id, $output = OBJECT, $filter = 'raw' ) {
  * @see esc_url()
  *
  * @param string $url The URL to be cleaned.
- * @param array $protocols Optional. An array of acceptable protocols.
+ * @param array  $protocols Optional. An array of acceptable protocols.
  * @param string $context Optional. How the URL will be used. Default is 'display'.
  * @return string The cleaned $url after the {@see 'clean_url'} filter is applied.
  */
 function clean_url( $url, $protocols = null, $context = 'display' ) {
-	if ( $context == 'db' )
+	if ( $context == 'db' ) {
 		_deprecated_function( 'clean_url( $context = \'db\' )', '3.0.0', 'sanitize_url()' );
-	else
+	} else {
 		_deprecated_function( __FUNCTION__, '3.0.0', 'esc_url()' );
+	}
 	return esc_url( $url, $protocols, $context );
 }
 
@@ -2121,7 +2292,7 @@ function attribute_escape( $text ) {
  * @param string     $classname       Optional. Classname widget option. Default empty.
  * @param mixed      ...$params       Widget parameters.
  */
-function register_sidebar_widget($name, $output_callback, $classname = '', ...$params) {
+function register_sidebar_widget( $name, $output_callback, $classname = '', ...$params ) {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'wp_register_sidebar_widget()' );
 	// Compat.
 	if ( is_array( $name ) ) {
@@ -2150,9 +2321,9 @@ function register_sidebar_widget($name, $output_callback, $classname = '', ...$p
  *
  * @param int|string $id Widget ID.
  */
-function unregister_sidebar_widget($id) {
+function unregister_sidebar_widget( $id ) {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'wp_unregister_sidebar_widget()' );
-	return wp_unregister_sidebar_widget($id);
+	return wp_unregister_sidebar_widget( $id );
 }
 
 /**
@@ -2175,7 +2346,7 @@ function unregister_sidebar_widget($id) {
  * @param int        $height           Widget height.
  * @param mixed      ...$params        Widget parameters.
  */
-function register_widget_control($name, $control_callback, $width = '', $height = '', ...$params) {
+function register_widget_control( $name, $control_callback, $width = '', $height = '', ...$params ) {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'wp_register_widget_control()' );
 	// Compat.
 	if ( is_array( $name ) ) {
@@ -2207,9 +2378,9 @@ function register_widget_control($name, $control_callback, $width = '', $height
  *
  * @param int|string $id Widget ID.
  */
-function unregister_widget_control($id) {
+function unregister_widget_control( $id ) {
 	_deprecated_function( __FUNCTION__, '2.8.0', 'wp_unregister_widget_control()' );
-	return wp_unregister_widget_control($id);
+	return wp_unregister_widget_control( $id );
 }
 
 /**
@@ -2221,37 +2392,42 @@ function unregister_widget_control($id) {
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
- * @param int $user_id User ID.
+ * @param int    $user_id User ID.
  * @param string $meta_key Metadata key.
- * @param mixed $meta_value Optional. Metadata value. Default empty.
+ * @param mixed  $meta_value Optional. Metadata value. Default empty.
  * @return bool True deletion completed and false if user_id is not a number.
  */
 function delete_usermeta( $user_id, $meta_key, $meta_value = '' ) {
 	_deprecated_function( __FUNCTION__, '3.0.0', 'delete_user_meta()' );
 	global $wpdb;
-	if ( !is_numeric( $user_id ) )
+	if ( ! is_numeric( $user_id ) ) {
 		return false;
-	$meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);
+	}
+	$meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
 
-	if ( is_array($meta_value) || is_object($meta_value) )
-		$meta_value = serialize($meta_value);
+	if ( is_array( $meta_value ) || is_object( $meta_value ) ) {
+		$meta_value = serialize( $meta_value );
+	}
 	$meta_value = trim( $meta_value );
 
-	$cur = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $meta_key) );
+	$cur = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $meta_key ) );
 
-	if ( $cur && $cur->umeta_id )
+	if ( $cur && $cur->umeta_id ) {
 		do_action( 'delete_usermeta', $cur->umeta_id, $user_id, $meta_key, $meta_value );
+	}
 
-	if ( ! empty($meta_value) )
-		$wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s AND meta_value = %s", $user_id, $meta_key, $meta_value) );
-	else
-		$wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $meta_key) );
+	if ( ! empty( $meta_value ) ) {
+		$wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s AND meta_value = %s", $user_id, $meta_key, $meta_value ) );
+	} else {
+		$wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $meta_key ) );
+	}
 
 	clean_user_cache( $user_id );
 	wp_cache_delete( $user_id, 'user_meta' );
 
-	if ( $cur && $cur->umeta_id )
+	if ( $cur && $cur->umeta_id ) {
 		do_action( 'deleted_usermeta', $cur->umeta_id, $user_id, $meta_key, $meta_value );
+	}
 
 	return true;
 }
@@ -2270,7 +2446,7 @@ function delete_usermeta( $user_id, $meta_key, $meta_value = '' ) {
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
- * @param int $user_id User ID
+ * @param int    $user_id User ID
  * @param string $meta_key Optional. Metadata key. Default empty.
  * @return mixed
  */
@@ -2279,34 +2455,38 @@ function get_usermeta( $user_id, $meta_key = '' ) {
 	global $wpdb;
 	$user_id = (int) $user_id;
 
-	if ( !$user_id )
+	if ( ! $user_id ) {
 		return false;
+	}
 
-	if ( !empty($meta_key) ) {
-		$meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);
-		$user = wp_cache_get($user_id, 'users');
+	if ( ! empty( $meta_key ) ) {
+		$meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
+		$user     = wp_cache_get( $user_id, 'users' );
 		// Check the cached user object.
-		if ( false !== $user && isset($user->$meta_key) )
-			$metas = array($user->$meta_key);
-		else
-			$metas = $wpdb->get_col( $wpdb->prepare("SELECT meta_value FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $meta_key) );
+		if ( false !== $user && isset( $user->$meta_key ) ) {
+			$metas = array( $user->$meta_key );
+		} else {
+			$metas = $wpdb->get_col( $wpdb->prepare( "SELECT meta_value FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $meta_key ) );
+		}
 	} else {
-		$metas = $wpdb->get_col( $wpdb->prepare("SELECT meta_value FROM $wpdb->usermeta WHERE user_id = %d", $user_id) );
+		$metas = $wpdb->get_col( $wpdb->prepare( "SELECT meta_value FROM $wpdb->usermeta WHERE user_id = %d", $user_id ) );
 	}
 
-	if ( empty($metas) ) {
-		if ( empty($meta_key) )
+	if ( empty( $metas ) ) {
+		if ( empty( $meta_key ) ) {
 			return array();
-		else
+		} else {
 			return '';
+		}
 	}
 
-	$metas = array_map('maybe_unserialize', $metas);
+	$metas = array_map( 'maybe_unserialize', $metas );
 
-	if ( count($metas) === 1 )
+	if ( count( $metas ) === 1 ) {
 		return $metas[0];
-	else
+	} else {
 		return $metas;
+	}
 }
 
 /**
@@ -2324,46 +2504,51 @@ function get_usermeta( $user_id, $meta_key = '' ) {
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
- * @param int $user_id User ID
+ * @param int    $user_id User ID
  * @param string $meta_key Metadata key.
- * @param mixed $meta_value Metadata value.
+ * @param mixed  $meta_value Metadata value.
  * @return bool True on successful update, false on failure.
  */
 function update_usermeta( $user_id, $meta_key, $meta_value ) {
 	_deprecated_function( __FUNCTION__, '3.0.0', 'update_user_meta()' );
 	global $wpdb;
-	if ( !is_numeric( $user_id ) )
+	if ( ! is_numeric( $user_id ) ) {
 		return false;
-	$meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);
+	}
+	$meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
 
 	/** @todo Might need fix because usermeta data is assumed to be already escaped */
-	if ( is_string($meta_value) )
-		$meta_value = stripslashes($meta_value);
-	$meta_value = maybe_serialize($meta_value);
+	if ( is_string( $meta_value ) ) {
+		$meta_value = stripslashes( $meta_value );
+	}
+	$meta_value = maybe_serialize( $meta_value );
 
-	if (empty($meta_value)) {
-		return delete_usermeta($user_id, $meta_key);
+	if ( empty( $meta_value ) ) {
+		return delete_usermeta( $user_id, $meta_key );
 	}
 
-	$cur = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $meta_key) );
+	$cur = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $meta_key ) );
 
-	if ( $cur )
+	if ( $cur ) {
 		do_action( 'update_usermeta', $cur->umeta_id, $user_id, $meta_key, $meta_value );
+	}
 
-	if ( !$cur )
-		$wpdb->insert($wpdb->usermeta, compact('user_id', 'meta_key', 'meta_value') );
-	elseif ( $cur->meta_value != $meta_value )
-		$wpdb->update($wpdb->usermeta, compact('meta_value'), compact('user_id', 'meta_key') );
-	else
+	if ( ! $cur ) {
+		$wpdb->insert( $wpdb->usermeta, compact( 'user_id', 'meta_key', 'meta_value' ) );
+	} elseif ( $cur->meta_value != $meta_value ) {
+		$wpdb->update( $wpdb->usermeta, compact( 'meta_value' ), compact( 'user_id', 'meta_key' ) );
+	} else {
 		return false;
+	}
 
 	clean_user_cache( $user_id );
 	wp_cache_delete( $user_id, 'user_meta' );
 
-	if ( !$cur )
+	if ( ! $cur ) {
 		do_action( 'added_usermeta', $wpdb->insert_id, $user_id, $meta_key, $meta_value );
-	else
+	} else {
 		do_action( 'updated_usermeta', $cur->umeta_id, $user_id, $meta_key, $meta_value );
+	}
 
 	return true;
 }
@@ -2390,8 +2575,8 @@ function get_users_of_blog( $id = '' ) {
 	if ( empty( $id ) ) {
 		$id = get_current_blog_id();
 	}
-	$blog_prefix = $wpdb->get_blog_prefix($id);
-	$users = $wpdb->get_results( "SELECT user_id, user_id AS ID, user_login, display_name, user_email, meta_value FROM $wpdb->users, $wpdb->usermeta WHERE {$wpdb->users}.ID = {$wpdb->usermeta}.user_id AND meta_key = '{$blog_prefix}capabilities' ORDER BY {$wpdb->usermeta}.user_id" );
+	$blog_prefix = $wpdb->get_blog_prefix( $id );
+	$users       = $wpdb->get_results( "SELECT user_id, user_id AS ID, user_login, display_name, user_email, meta_value FROM $wpdb->users, $wpdb->usermeta WHERE {$wpdb->users}.ID = {$wpdb->usermeta}.user_id AND meta_key = '{$blog_prefix}capabilities' ORDER BY {$wpdb->usermeta}.user_id" );
 	return $users;
 }
 
@@ -2407,10 +2592,11 @@ function get_users_of_blog( $id = '' ) {
 function automatic_feed_links( $add = true ) {
 	_deprecated_function( __FUNCTION__, '3.0.0', "add_theme_support( 'automatic-feed-links' )" );
 
-	if ( $add )
+	if ( $add ) {
 		add_theme_support( 'automatic-feed-links' );
-	else
+	} else {
 		remove_action( 'wp_head', 'feed_links_extra', 3 ); // Just do this yourself in 3.0+.
+	}
 }
 
 /**
@@ -2458,8 +2644,8 @@ function get_usernumposts( $userid ) {
  * @param array $matches Single Match
  * @return string An HTML entity
  */
-function funky_javascript_callback($matches) {
-	return "&#".base_convert($matches[1],16,10).";";
+function funky_javascript_callback( $matches ) {
+	return '&#' . base_convert( $matches[1], 16, 10 ) . ';';
 }
 
 /**
@@ -2476,15 +2662,18 @@ function funky_javascript_callback($matches) {
  * @param string $text Text to be made safe.
  * @return string Fixed text.
  */
-function funky_javascript_fix($text) {
+function funky_javascript_fix( $text ) {
 	_deprecated_function( __FUNCTION__, '3.0.0' );
 	// Fixes for browsers' JavaScript bugs.
 	global $is_macIE, $is_winIE;
 
-	if ( $is_winIE || $is_macIE )
-		$text =  preg_replace_callback("/\%u([0-9A-F]{4,4})/",
-					"funky_javascript_callback",
-					$text);
+	if ( $is_winIE || $is_macIE ) {
+		$text = preg_replace_callback(
+			'/\%u([0-9A-F]{4,4})/',
+			'funky_javascript_callback',
+			$text
+		);
+	}
 
 	return $text;
 }
@@ -2512,8 +2701,8 @@ function is_taxonomy( $taxonomy ) {
  * @see term_exists()
  *
  * @param int|string $term The term to check
- * @param string $taxonomy The taxonomy name to use
- * @param int $parent ID of parent term under which to confine the exists search.
+ * @param string     $taxonomy The taxonomy name to use
+ * @param int        $parent ID of parent term under which to confine the exists search.
  * @return mixed Get the term ID or term object, if exists.
  */
 function is_term( $term, $taxonomy = '', $parent = 0 ) {
@@ -2542,8 +2731,9 @@ function is_plugin_page() {
 
 	global $plugin_page;
 
-	if ( isset($plugin_page) )
+	if ( isset( $plugin_page ) ) {
 		return true;
+	}
 
 	return false;
 }
@@ -2594,7 +2784,7 @@ function wp_timezone_supported() {
  * @param int    $tab_index     Optional. Unused.
  * @param bool   $extended      Optional. Unused.
  */
-function the_editor($content, $id = 'content', $prev_id = 'title', $media_buttons = true, $tab_index = 2, $extended = true) {
+function the_editor( $content, $id = 'content', $prev_id = 'title', $media_buttons = true, $tab_index = 2, $extended = true ) {
 	_deprecated_function( __FUNCTION__, '3.3.0', 'wp_editor()' );
 
 	wp_editor( $content, $id, array( 'media_buttons' => $media_buttons ) );
@@ -2609,21 +2799,26 @@ function the_editor($content, $id = 'content', $prev_id = 'title', $media_button
  * @param array $ids User ID numbers list.
  * @return array of arrays. The array is indexed by user_id, containing $metavalues object arrays.
  */
-function get_user_metavalues($ids) {
+function get_user_metavalues( $ids ) {
 	_deprecated_function( __FUNCTION__, '3.3.0' );
 
 	$objects = array();
 
-	$ids = array_map('intval', $ids);
-	foreach ( $ids as $id )
-		$objects[$id] = array();
+	$ids = array_map( 'intval', $ids );
+	foreach ( $ids as $id ) {
+		$objects[ $id ] = array();
+	}
 
-	$metas = update_meta_cache('user', $ids);
+	$metas = update_meta_cache( 'user', $ids );
 
 	foreach ( $metas as $id => $meta ) {
 		foreach ( $meta as $key => $metavalues ) {
 			foreach ( $metavalues as $value ) {
-				$objects[$id][] = (object)array( 'user_id' => $id, 'meta_key' => $key, 'meta_value' => $value);
+				$objects[ $id ][] = (object) array(
+					'user_id'    => $id,
+					'meta_key'   => $key,
+					'meta_value' => $value,
+				);
 			}
 		}
 	}
@@ -2643,25 +2838,29 @@ function get_user_metavalues($ids) {
  * @param string       $context Optional. How to sanitize user fields. Default 'display'.
  * @return object|array The now sanitized user object or array (will be the same type as $user).
  */
-function sanitize_user_object($user, $context = 'display') {
+function sanitize_user_object( $user, $context = 'display' ) {
 	_deprecated_function( __FUNCTION__, '3.3.0' );
 
-	if ( is_object($user) ) {
-		if ( !isset($user->ID) )
+	if ( is_object( $user ) ) {
+		if ( ! isset( $user->ID ) ) {
 			$user->ID = 0;
+		}
 		if ( ! ( $user instanceof WP_User ) ) {
-			$vars = get_object_vars($user);
-			foreach ( array_keys($vars) as $field ) {
-				if ( is_string($user->$field) || is_numeric($user->$field) )
-					$user->$field = sanitize_user_field($field, $user->$field, $user->ID, $context);
+			$vars = get_object_vars( $user );
+			foreach ( array_keys( $vars ) as $field ) {
+				if ( is_string( $user->$field ) || is_numeric( $user->$field ) ) {
+					$user->$field = sanitize_user_field( $field, $user->$field, $user->ID, $context );
+				}
 			}
 		}
 		$user->filter = $context;
 	} else {
-		if ( !isset($user['ID']) )
+		if ( ! isset( $user['ID'] ) ) {
 			$user['ID'] = 0;
-		foreach ( array_keys($user) as $field )
-			$user[$field] = sanitize_user_field($field, $user[$field], $user['ID'], $context);
+		}
+		foreach ( array_keys( $user ) as $field ) {
+			$user[ $field ] = sanitize_user_field( $field, $user[ $field ], $user['ID'], $context );
+		}
 		$user['filter'] = $context;
 	}
 
@@ -2684,29 +2883,31 @@ function sanitize_user_object($user, $context = 'display') {
  *                                    Default true.
  * @return string
  */
-function get_boundary_post_rel_link($title = '%title', $in_same_cat = false, $excluded_categories = '', $start = true) {
+function get_boundary_post_rel_link( $title = '%title', $in_same_cat = false, $excluded_categories = '', $start = true ) {
 	_deprecated_function( __FUNCTION__, '3.3.0' );
 
-	$posts = get_boundary_post($in_same_cat, $excluded_categories, $start);
+	$posts = get_boundary_post( $in_same_cat, $excluded_categories, $start );
 	// If there is no post, stop.
-	if ( empty($posts) )
+	if ( empty( $posts ) ) {
 		return;
+	}
 
 	// Even though we limited get_posts() to return only 1 item it still returns an array of objects.
 	$post = $posts[0];
 
-	if ( empty($post->post_title) )
-		$post->post_title = $start ? __('First Post') : __('Last Post');
+	if ( empty( $post->post_title ) ) {
+		$post->post_title = $start ? __( 'First Post' ) : __( 'Last Post' );
+	}
 
-	$date = mysql2date(get_option('date_format'), $post->post_date);
+	$date = mysql2date( get_option( 'date_format' ), $post->post_date );
 
-	$title = str_replace('%title', $post->post_title, $title);
-	$title = str_replace('%date', $date, $title);
-	$title = apply_filters('the_title', $title, $post->ID);
+	$title = str_replace( '%title', $post->post_title, $title );
+	$title = str_replace( '%date', $date, $title );
+	$title = apply_filters( 'the_title', $title, $post->ID );
 
-	$link = $start ? "<link rel='start' title='" : "<link rel='end' title='";
-	$link .= esc_attr($title);
-	$link .= "' href='" . get_permalink($post) . "' />\n";
+	$link  = $start ? "<link rel='start' title='" : "<link rel='end' title='";
+	$link .= esc_attr( $title );
+	$link .= "' href='" . get_permalink( $post ) . "' />\n";
 
 	$boundary = $start ? 'start' : 'end';
 	return apply_filters( "{$boundary}_post_rel_link", $link );
@@ -2719,13 +2920,13 @@ function get_boundary_post_rel_link($title = '%title', $in_same_cat = false, $ex
  * @deprecated 3.3.0
  *
  * @param string $title Optional. Link title format.
- * @param bool $in_same_cat Optional. Whether link should be in a same category.
+ * @param bool   $in_same_cat Optional. Whether link should be in a same category.
  * @param string $excluded_categories Optional. Excluded categories IDs.
  */
-function start_post_rel_link($title = '%title', $in_same_cat = false, $excluded_categories = '') {
+function start_post_rel_link( $title = '%title', $in_same_cat = false, $excluded_categories = '' ) {
 	_deprecated_function( __FUNCTION__, '3.3.0' );
 
-	echo get_boundary_post_rel_link($title, $in_same_cat, $excluded_categories, true);
+	echo get_boundary_post_rel_link( $title, $in_same_cat, $excluded_categories, true );
 }
 
 /**
@@ -2740,7 +2941,7 @@ function get_index_rel_link() {
 	_deprecated_function( __FUNCTION__, '3.3.0' );
 
 	$link = "<link rel='index' title='" . esc_attr( get_bloginfo( 'name', 'display' ) ) . "' href='" . esc_url( user_trailingslashit( get_bloginfo( 'url', 'display' ) ) ) . "' />\n";
-	return apply_filters( "index_rel_link", $link );
+	return apply_filters( 'index_rel_link', $link );
 }
 
 /**
@@ -2769,23 +2970,25 @@ function index_rel_link() {
 function get_parent_post_rel_link( $title = '%title' ) {
 	_deprecated_function( __FUNCTION__, '3.3.0' );
 
-	if ( ! empty( $GLOBALS['post'] ) && ! empty( $GLOBALS['post']->post_parent ) )
-		$post = get_post($GLOBALS['post']->post_parent);
+	if ( ! empty( $GLOBALS['post'] ) && ! empty( $GLOBALS['post']->post_parent ) ) {
+		$post = get_post( $GLOBALS['post']->post_parent );
+	}
 
-	if ( empty($post) )
+	if ( empty( $post ) ) {
 		return;
+	}
 
-	$date = mysql2date(get_option('date_format'), $post->post_date);
+	$date = mysql2date( get_option( 'date_format' ), $post->post_date );
 
-	$title = str_replace('%title', $post->post_title, $title);
-	$title = str_replace('%date', $date, $title);
-	$title = apply_filters('the_title', $title, $post->ID);
+	$title = str_replace( '%title', $post->post_title, $title );
+	$title = str_replace( '%date', $date, $title );
+	$title = apply_filters( 'the_title', $title, $post->ID );
 
-	$link = "<link rel='up' title='";
+	$link  = "<link rel='up' title='";
 	$link .= esc_attr( $title );
-	$link .= "' href='" . get_permalink($post) . "' />\n";
+	$link .= "' href='" . get_permalink( $post ) . "' />\n";
 
-	return apply_filters( "parent_post_rel_link", $link );
+	return apply_filters( 'parent_post_rel_link', $link );
 }
 
 /**
@@ -2799,7 +3002,7 @@ function get_parent_post_rel_link( $title = '%title' ) {
 function parent_post_rel_link( $title = '%title' ) {
 	_deprecated_function( __FUNCTION__, '3.3.0' );
 
-	echo get_parent_post_rel_link($title);
+	echo get_parent_post_rel_link( $title );
 }
 
 /**
@@ -2816,12 +3019,31 @@ function wp_admin_bar_dashboard_view_site_menu( $wp_admin_bar ) {
 	$user_id = get_current_user_id();
 
 	if ( 0 != $user_id ) {
-		if ( is_admin() )
-			$wp_admin_bar->add_menu( array( 'id' => 'view-site', 'title' => __( 'Visit Site' ), 'href' => home_url() ) );
-		elseif ( is_multisite() )
-			$wp_admin_bar->add_menu( array( 'id' => 'dashboard', 'title' => __( 'Dashboard' ), 'href' => get_dashboard_url( $user_id ) ) );
-		else
-			$wp_admin_bar->add_menu( array( 'id' => 'dashboard', 'title' => __( 'Dashboard' ), 'href' => admin_url() ) );
+		if ( is_admin() ) {
+			$wp_admin_bar->add_menu(
+				array(
+					'id'    => 'view-site',
+					'title' => __( 'Visit Site' ),
+					'href'  => home_url(),
+				)
+			);
+		} elseif ( is_multisite() ) {
+			$wp_admin_bar->add_menu(
+				array(
+					'id'    => 'dashboard',
+					'title' => __( 'Dashboard' ),
+					'href'  => get_dashboard_url( $user_id ),
+				)
+			);
+		} else {
+			$wp_admin_bar->add_menu(
+				array(
+					'id'    => 'dashboard',
+					'title' => __( 'Dashboard' ),
+					'href'  => admin_url(),
+				)
+			);
+		}
 	}
 }
 
@@ -2873,8 +3095,9 @@ function debug_fopen( $filename, $mode ) {
  */
 function debug_fwrite( $fp, $message ) {
 	_deprecated_function( __FUNCTION__, '3.4.0', 'error_log()' );
-	if ( ! empty( $GLOBALS['debug'] ) )
+	if ( ! empty( $GLOBALS['debug'] ) ) {
 		error_log( $message );
+	}
 }
 
 /**
@@ -2909,18 +3132,20 @@ function get_themes() {
 	_deprecated_function( __FUNCTION__, '3.4.0', 'wp_get_themes()' );
 
 	global $wp_themes;
-	if ( isset( $wp_themes ) )
+	if ( isset( $wp_themes ) ) {
 		return $wp_themes;
+	}
 
-	$themes = wp_get_themes();
+	$themes    = wp_get_themes();
 	$wp_themes = array();
 
 	foreach ( $themes as $theme ) {
-		$name = $theme->get('Name');
-		if ( isset( $wp_themes[ $name ] ) )
+		$name = $theme->get( 'Name' );
+		if ( isset( $wp_themes[ $name ] ) ) {
 			$wp_themes[ $name . '/' . $theme->get_stylesheet() ] = $theme;
-		else
+		} else {
 			$wp_themes[ $name ] = $theme;
+		}
 	}
 
 	return $wp_themes;
@@ -2940,8 +3165,9 @@ function get_theme( $theme ) {
 	_deprecated_function( __FUNCTION__, '3.4.0', 'wp_get_theme( $stylesheet )' );
 
 	$themes = get_themes();
-	if ( is_array( $themes ) && array_key_exists( $theme, $themes ) )
+	if ( is_array( $themes ) && array_key_exists( $theme, $themes ) ) {
 		return $themes[ $theme ];
+	}
 	return null;
 }
 
@@ -2957,10 +3183,11 @@ function get_theme( $theme ) {
 function get_current_theme() {
 	_deprecated_function( __FUNCTION__, '3.4.0', 'wp_get_theme()' );
 
-	if ( $theme = get_option( 'current_theme' ) )
+	if ( $theme = get_option( 'current_theme' ) ) {
 		return $theme;
+	}
 
-	return wp_get_theme()->get('Name');
+	return wp_get_theme()->get( 'Name' );
 }
 
 /**
@@ -2975,17 +3202,18 @@ function get_current_theme() {
  * @param array|string $matches The array or string
  * @return string The pre block without paragraph/line break conversion.
  */
-function clean_pre($matches) {
+function clean_pre( $matches ) {
 	_deprecated_function( __FUNCTION__, '3.4.0' );
 
-	if ( is_array($matches) )
-		$text = $matches[1] . $matches[2] . "</pre>";
-	else
+	if ( is_array( $matches ) ) {
+		$text = $matches[1] . $matches[2] . '</pre>';
+	} else {
 		$text = $matches;
+	}
 
-	$text = str_replace(array('<br />', '<br/>', '<br>'), array('', '', ''), $text);
-	$text = str_replace('<p>', "\n", $text);
-	$text = str_replace('</p>', '', $text);
+	$text = str_replace( array( '<br />', '<br/>', '<br>' ), array( '', '', '' ), $text );
+	$text = str_replace( '<p>', "\n", $text );
+	$text = str_replace( '</p>', '', $text );
 
 	return $text;
 }
@@ -3008,8 +3236,9 @@ function add_custom_image_header( $wp_head_callback, $admin_head_callback, $admi
 		'wp-head-callback'    => $wp_head_callback,
 		'admin-head-callback' => $admin_head_callback,
 	);
-	if ( $admin_preview_callback )
+	if ( $admin_preview_callback ) {
 		$args['admin-preview-callback'] = $admin_preview_callback;
+	}
 	return add_theme_support( 'custom-header', $args );
 }
 
@@ -3041,12 +3270,15 @@ function remove_custom_image_header() {
 function add_custom_background( $wp_head_callback = '', $admin_head_callback = '', $admin_preview_callback = '' ) {
 	_deprecated_function( __FUNCTION__, '3.4.0', 'add_theme_support( \'custom-background\', $args )' );
 	$args = array();
-	if ( $wp_head_callback )
+	if ( $wp_head_callback ) {
 		$args['wp-head-callback'] = $wp_head_callback;
-	if ( $admin_head_callback )
+	}
+	if ( $admin_head_callback ) {
 		$args['admin-head-callback'] = $admin_head_callback;
-	if ( $admin_preview_callback )
+	}
+	if ( $admin_preview_callback ) {
 		$args['admin-preview-callback'] = $admin_preview_callback;
+	}
 	return add_theme_support( 'custom-background', $args );
 }
 
@@ -3079,22 +3311,23 @@ function get_theme_data( $theme_file ) {
 	$theme = new WP_Theme( wp_basename( dirname( $theme_file ) ), dirname( dirname( $theme_file ) ) );
 
 	$theme_data = array(
-		'Name' => $theme->get('Name'),
-		'URI' => $theme->display('ThemeURI', true, false),
-		'Description' => $theme->display('Description', true, false),
-		'Author' => $theme->display('Author', true, false),
-		'AuthorURI' => $theme->display('AuthorURI', true, false),
-		'Version' => $theme->get('Version'),
-		'Template' => $theme->get('Template'),
-		'Status' => $theme->get('Status'),
-		'Tags' => $theme->get('Tags'),
-		'Title' => $theme->get('Name'),
-		'AuthorName' => $theme->get('Author'),
+		'Name'        => $theme->get( 'Name' ),
+		'URI'         => $theme->display( 'ThemeURI', true, false ),
+		'Description' => $theme->display( 'Description', true, false ),
+		'Author'      => $theme->display( 'Author', true, false ),
+		'AuthorURI'   => $theme->display( 'AuthorURI', true, false ),
+		'Version'     => $theme->get( 'Version' ),
+		'Template'    => $theme->get( 'Template' ),
+		'Status'      => $theme->get( 'Status' ),
+		'Tags'        => $theme->get( 'Tags' ),
+		'Title'       => $theme->get( 'Name' ),
+		'AuthorName'  => $theme->get( 'Author' ),
 	);
 
 	foreach ( apply_filters( 'extra_theme_headers', array() ) as $extra_header ) {
-		if ( ! isset( $theme_data[ $extra_header ] ) )
+		if ( ! isset( $theme_data[ $extra_header ] ) ) {
 			$theme_data[ $extra_header ] = $theme->get( $extra_header );
+		}
 	}
 
 	return $theme_data;
@@ -3163,8 +3396,9 @@ function wp_explain_nonce( $action ) {
  */
 function sticky_class( $post_id = null ) {
 	_deprecated_function( __FUNCTION__, '3.5.0', 'post_class()' );
-	if ( is_sticky( $post_id ) )
+	if ( is_sticky( $post_id ) ) {
 		echo ' sticky';
+	}
 }
 
 /**
@@ -3197,16 +3431,18 @@ function _get_post_ancestors( &$post ) {
 function wp_load_image( $file ) {
 	_deprecated_function( __FUNCTION__, '3.5.0', 'wp_get_image_editor()' );
 
-	if ( is_numeric( $file ) )
+	if ( is_numeric( $file ) ) {
 		$file = get_attached_file( $file );
+	}
 
 	if ( ! is_file( $file ) ) {
 		/* translators: %s: File name. */
 		return sprintf( __( 'File &#8220;%s&#8221; does not exist?' ), $file );
 	}
 
-	if ( ! function_exists('imagecreatefromstring') )
-		return __('The GD image library is not installed.');
+	if ( ! function_exists( 'imagecreatefromstring' ) ) {
+		return __( 'The GD image library is not installed.' );
+	}
 
 	// Set artificially high because GD uses uncompressed images in memory.
 	wp_raise_memory_limit( 'image' );
@@ -3249,19 +3485,22 @@ function image_resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $de
 	_deprecated_function( __FUNCTION__, '3.5.0', 'wp_get_image_editor()' );
 
 	$editor = wp_get_image_editor( $file );
-	if ( is_wp_error( $editor ) )
+	if ( is_wp_error( $editor ) ) {
 		return $editor;
+	}
 	$editor->set_quality( $jpeg_quality );
 
 	$resized = $editor->resize( $max_w, $max_h, $crop );
-	if ( is_wp_error( $resized ) )
+	if ( is_wp_error( $resized ) ) {
 		return $resized;
+	}
 
 	$dest_file = $editor->generate_filename( $suffix, $dest_path );
-	$saved = $editor->save( $dest_file );
+	$saved     = $editor->save( $dest_file );
 
-	if ( is_wp_error( $saved ) )
+	if ( is_wp_error( $saved ) ) {
 		return $saved;
+	}
 
 	return $dest_file;
 }
@@ -3276,7 +3515,7 @@ function image_resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $de
  * @deprecated 3.5.0 Use get_post()
  * @see get_post()
  *
- * @param int $postid Post ID.
+ * @param int    $postid Post ID.
  * @param string $mode How to return result, either OBJECT, ARRAY_N, or ARRAY_A.
  * @return WP_Post|null Post object or array holding post contents and information
  */
@@ -3296,11 +3535,12 @@ function wp_get_single_post( $postid = 0, $mode = OBJECT ) {
  * @param string $user_pass User password.
  * @return bool False if does not authenticate, true if username and password authenticates.
  */
-function user_pass_ok($user_login, $user_pass) {
+function user_pass_ok( $user_login, $user_pass ) {
 	_deprecated_function( __FUNCTION__, '3.5.0', 'wp_authenticate()' );
 	$user = wp_authenticate( $user_login, $user_pass );
-	if ( is_wp_error( $user ) )
+	if ( is_wp_error( $user ) ) {
 		return false;
+	}
 
 	return true;
 }
@@ -3323,34 +3563,34 @@ function _save_post_hook() {}
  * @param string $mime_type
  * @return bool
  */
-function gd_edit_image_support($mime_type) {
+function gd_edit_image_support( $mime_type ) {
 	_deprecated_function( __FUNCTION__, '3.5.0', 'wp_image_editor_supports()' );
 
-	if ( function_exists('imagetypes') ) {
-		switch( $mime_type ) {
+	if ( function_exists( 'imagetypes' ) ) {
+		switch ( $mime_type ) {
 			case 'image/jpeg':
-				return (imagetypes() & IMG_JPG) != 0;
+				return ( imagetypes() & IMG_JPG ) != 0;
 			case 'image/png':
-				return (imagetypes() & IMG_PNG) != 0;
+				return ( imagetypes() & IMG_PNG ) != 0;
 			case 'image/gif':
-				return (imagetypes() & IMG_GIF) != 0;
+				return ( imagetypes() & IMG_GIF ) != 0;
 			case 'image/webp':
-				return (imagetypes() & IMG_WEBP) != 0;
+				return ( imagetypes() & IMG_WEBP ) != 0;
 			case 'image/avif':
-				return (imagetypes() & IMG_AVIF) != 0;
-			}
+				return ( imagetypes() & IMG_AVIF ) != 0;
+		}
 	} else {
-		switch( $mime_type ) {
+		switch ( $mime_type ) {
 			case 'image/jpeg':
-				return function_exists('imagecreatefromjpeg');
+				return function_exists( 'imagecreatefromjpeg' );
 			case 'image/png':
-				return function_exists('imagecreatefrompng');
+				return function_exists( 'imagecreatefrompng' );
 			case 'image/gif':
-				return function_exists('imagecreatefromgif');
+				return function_exists( 'imagecreatefromgif' );
 			case 'image/webp':
-				return function_exists('imagecreatefromwebp');
+				return function_exists( 'imagecreatefromwebp' );
 			case 'image/avif':
-				return function_exists('imagecreatefromavif');
+				return function_exists( 'imagecreatefromavif' );
 		}
 	}
 	return false;
@@ -3369,7 +3609,13 @@ function gd_edit_image_support($mime_type) {
 function wp_convert_bytes_to_hr( $bytes ) {
 	_deprecated_function( __FUNCTION__, '3.6.0', 'size_format()' );
 
-	$units = array( 0 => 'B', 1 => 'KB', 2 => 'MB', 3 => 'GB', 4 => 'TB' );
+	$units = array(
+		0 => 'B',
+		1 => 'KB',
+		2 => 'MB',
+		3 => 'GB',
+		4 => 'TB',
+	);
 	$log   = log( $bytes, KB_IN_BYTES );
 	$power = (int) $log;
 	$size  = KB_IN_BYTES ** ( $log - $power );
@@ -3414,8 +3660,9 @@ function rich_edit_exists() {
 	global $wp_rich_edit_exists;
 	_deprecated_function( __FUNCTION__, '3.9.0' );
 
-	if ( ! isset( $wp_rich_edit_exists ) )
+	if ( ! isset( $wp_rich_edit_exists ) ) {
 		$wp_rich_edit_exists = file_exists( ABSPATH . WPINC . '/js/tinymce/tinymce.js' );
+	}
 
 	return $wp_rich_edit_exists;
 }
@@ -3460,9 +3707,9 @@ function format_to_post( $content ) {
  * @param string $text The text to be escaped.
  * @return string text, safe for inclusion in LIKE query.
  */
-function like_escape($text) {
+function like_escape( $text ) {
 	_deprecated_function( __FUNCTION__, '4.0.0', 'wpdb::esc_like()' );
-	return str_replace( array( "%", "_" ), array( "\\%", "\\_" ), $text );
+	return str_replace( array( '%', '_' ), array( '\\%', '\\_' ), $text );
 }
 
 /**
@@ -3482,7 +3729,7 @@ function url_is_accessable_via_ssl( $url ) {
 
 	$response = wp_remote_get( set_url_scheme( $url, 'https' ) );
 
-	if ( !is_wp_error( $response ) ) {
+	if ( ! is_wp_error( $response ) ) {
 		$status = wp_remote_retrieve_response_code( $response );
 		if ( 200 == $status || 401 == $status ) {
 			return true;
@@ -3578,7 +3825,7 @@ function preview_theme_ob_filter_callback( $matches ) {
  * @param string $text The text to be formatted.
  * @return string The formatted text after filter is applied.
  */
-function wp_richedit_pre($text) {
+function wp_richedit_pre( $text ) {
 	_deprecated_function( __FUNCTION__, '4.3.0', 'format_for_editor()' );
 
 	if ( empty( $text ) ) {
@@ -3600,9 +3847,9 @@ function wp_richedit_pre($text) {
 		return apply_filters( 'richedit_pre', '' );
 	}
 
-	$output = convert_chars($text);
-	$output = wpautop($output);
-	$output = htmlspecialchars($output, ENT_NOQUOTES, get_option( 'blog_charset' ) );
+	$output = convert_chars( $text );
+	$output = wpautop( $output );
+	$output = htmlspecialchars( $output, ENT_NOQUOTES, get_option( 'blog_charset' ) );
 
 	/** This filter is documented in wp-includes/deprecated.php */
 	return apply_filters( 'richedit_pre', $output );
@@ -3621,11 +3868,12 @@ function wp_richedit_pre($text) {
  * @param string $output The text to be formatted.
  * @return string Formatted text after filter applied.
  */
-function wp_htmledit_pre($output) {
+function wp_htmledit_pre( $output ) {
 	_deprecated_function( __FUNCTION__, '4.3.0', 'format_for_editor()' );
 
-	if ( !empty($output) )
-		$output = htmlspecialchars($output, ENT_NOQUOTES, get_option( 'blog_charset' ) ); // Convert only '< > &'.
+	if ( ! empty( $output ) ) {
+		$output = htmlspecialchars( $output, ENT_NOQUOTES, get_option( 'blog_charset' ) ); // Convert only '< > &'.
+	}
 
 	/**
 	 * Filters the text before it is formatted for the HTML editor.
@@ -3678,40 +3926,45 @@ function wp_get_http( $url, $file_path = false, $red = 1 ) {
 		@set_time_limit( 60 );
 	}
 
-	if ( $red > 5 )
+	if ( $red > 5 ) {
 		return false;
+	}
 
-	$options = array();
+	$options                = array();
 	$options['redirection'] = 5;
 
-	if ( false == $file_path )
+	if ( false == $file_path ) {
 		$options['method'] = 'HEAD';
-	else
+	} else {
 		$options['method'] = 'GET';
+	}
 
 	$response = wp_safe_remote_request( $url, $options );
 
-	if ( is_wp_error( $response ) )
+	if ( is_wp_error( $response ) ) {
 		return false;
+	}
 
-	$headers = wp_remote_retrieve_headers( $response );
+	$headers             = wp_remote_retrieve_headers( $response );
 	$headers['response'] = wp_remote_retrieve_response_code( $response );
 
 	// WP_HTTP no longer follows redirects for HEAD requests.
-	if ( 'HEAD' == $options['method'] && in_array($headers['response'], array(301, 302)) && isset( $headers['location'] ) ) {
+	if ( 'HEAD' == $options['method'] && in_array( $headers['response'], array( 301, 302 ) ) && isset( $headers['location'] ) ) {
 		return wp_get_http( $headers['location'], $file_path, ++$red );
 	}
 
-	if ( false == $file_path )
+	if ( false == $file_path ) {
 		return $headers;
+	}
 
 	// GET request - write it to the supplied filename.
-	$out_fp = fopen($file_path, 'w');
-	if ( !$out_fp )
+	$out_fp = fopen( $file_path, 'w' );
+	if ( ! $out_fp ) {
 		return $headers;
+	}
 
-	fwrite( $out_fp,  wp_remote_retrieve_body( $response ) );
-	fclose($out_fp);
+	fwrite( $out_fp, wp_remote_retrieve_body( $response ) );
+	fclose( $out_fp );
 	clearstatcache();
 
 	return $headers;
@@ -3785,7 +4038,7 @@ function comments_popup_script() {
  */
 function popuplinks( $text ) {
 	_deprecated_function( __FUNCTION__, '4.5.0' );
-	$text = preg_replace('/<a (.+?)>/i', "<a $1 target='_blank' rel='external'>", $text);
+	$text = preg_replace( '/<a (.+?)>/i', "<a $1 target='_blank' rel='external'>", $text );
 	return $text;
 }
 
@@ -3863,12 +4116,13 @@ function wp_kses_js_entities( $content ) {
 function _usort_terms_by_ID( $a, $b ) {
 	_deprecated_function( __FUNCTION__, '4.7.0', 'wp_list_sort()' );
 
-	if ( $a->term_id > $b->term_id )
+	if ( $a->term_id > $b->term_id ) {
 		return 1;
-	elseif ( $a->term_id < $b->term_id )
+	} elseif ( $a->term_id < $b->term_id ) {
 		return -1;
-	else
+	} else {
 		return 0;
+	}
 }
 
 /**
@@ -3909,21 +4163,24 @@ function _sort_nav_menu_items( $a, $b ) {
 
 	_deprecated_function( __FUNCTION__, '4.7.0', 'wp_list_sort()' );
 
-	if ( empty( $_menu_item_sort_prop ) )
+	if ( empty( $_menu_item_sort_prop ) ) {
 		return 0;
+	}
 
-	if ( ! isset( $a->$_menu_item_sort_prop ) || ! isset( $b->$_menu_item_sort_prop ) )
+	if ( ! isset( $a->$_menu_item_sort_prop ) || ! isset( $b->$_menu_item_sort_prop ) ) {
 		return 0;
+	}
 
 	$_a = (int) $a->$_menu_item_sort_prop;
 	$_b = (int) $b->$_menu_item_sort_prop;
 
-	if ( $a->$_menu_item_sort_prop == $b->$_menu_item_sort_prop )
+	if ( $a->$_menu_item_sort_prop == $b->$_menu_item_sort_prop ) {
 		return 0;
-	elseif ( $_a == $a->$_menu_item_sort_prop && $_b == $b->$_menu_item_sort_prop )
+	} elseif ( $_a == $a->$_menu_item_sort_prop && $_b == $b->$_menu_item_sort_prop ) {
 		return $_a < $_b ? -1 : 1;
-	else
+	} else {
 		return strcmp( $a->$_menu_item_sort_prop, $b->$_menu_item_sort_prop );
+	}
 }
 
 /**
@@ -4623,8 +4880,8 @@ function _resolve_home_block_template() {
 
 	if ( 'page' === $show_on_front && $front_page_id ) {
 		return array(
-				'postType' => 'page',
-				'postId'   => $front_page_id,
+			'postType' => 'page',
+			'postId'   => $front_page_id,
 		);
 	}
 
@@ -4636,8 +4893,8 @@ function _resolve_home_block_template() {
 	}
 
 	return array(
-			'postType' => 'wp_template',
-			'postId'   => $template->id,
+		'postType' => 'wp_template',
+		'postId'   => $template->id,
 	);
 }
 
@@ -5436,7 +5693,7 @@ function _wp_theme_json_webfonts_handler() {
 	 *
 	 * @return array Array of defined webfonts.
 	 */
-	$fn_get_webfonts_from_theme_json = static function() {
+	$fn_get_webfonts_from_theme_json = static function () {
 		// Get settings from theme.json.
 		$settings = WP_Theme_JSON_Resolver::get_merged_data()->get_settings();
 
@@ -5507,7 +5764,7 @@ function _wp_theme_json_webfonts_handler() {
 	 * @param array $src Webfont file(s) `src`.
 	 * @return array Webfont's `src` in URI.
 	 */
-	$fn_transform_src_into_uri = static function( array $src ) {
+	$fn_transform_src_into_uri = static function ( array $src ) {
 		foreach ( $src as $key => $url ) {
 			// Tweak the URL to be relative to the theme root.
 			if ( ! str_starts_with( $url, 'file:./' ) ) {
@@ -5528,7 +5785,7 @@ function _wp_theme_json_webfonts_handler() {
 	 * @param array $font_face Font face to convert.
 	 * @return array Font faces with each property in kebab-case format.
 	 */
-	$fn_convert_keys_to_kebab_case = static function( array $font_face ) {
+	$fn_convert_keys_to_kebab_case = static function ( array $font_face ) {
 		foreach ( $font_face as $property => $value ) {
 			$kebab_case               = _wp_to_kebab_case( $property );
 			$font_face[ $kebab_case ] = $value;
@@ -5548,16 +5805,16 @@ function _wp_theme_json_webfonts_handler() {
 	 * @param array $webfont The webfont arguments.
 	 * @return array|false The validated webfont arguments, or false if the webfont is invalid.
 	 */
-	$fn_validate_webfont = static function( $webfont ) {
+	$fn_validate_webfont = static function ( $webfont ) {
 		$webfont = wp_parse_args(
-				$webfont,
-				array(
-						'font-family'  => '',
-						'font-style'   => 'normal',
-						'font-weight'  => '400',
-						'font-display' => 'fallback',
-						'src'          => array(),
-				)
+			$webfont,
+			array(
+				'font-family'  => '',
+				'font-style'   => 'normal',
+				'font-weight'  => '400',
+				'font-display' => 'fallback',
+				'src'          => array(),
+			)
 		);
 
 		// Check the font-family.
@@ -5596,20 +5853,20 @@ function _wp_theme_json_webfonts_handler() {
 		}
 
 		$valid_props = array(
-				'ascend-override',
-				'descend-override',
-				'font-display',
-				'font-family',
-				'font-stretch',
-				'font-style',
-				'font-weight',
-				'font-variant',
-				'font-feature-settings',
-				'font-variation-settings',
-				'line-gap-override',
-				'size-adjust',
-				'src',
-				'unicode-range',
+			'ascend-override',
+			'descend-override',
+			'font-display',
+			'font-family',
+			'font-stretch',
+			'font-style',
+			'font-weight',
+			'font-variant',
+			'font-feature-settings',
+			'font-variation-settings',
+			'line-gap-override',
+			'size-adjust',
+			'src',
+			'unicode-range',
 		);
 
 		foreach ( $webfont as $prop => $value ) {
@@ -5631,7 +5888,7 @@ function _wp_theme_json_webfonts_handler() {
 	 * @uses $fn_convert_keys_to_kebab_case To run the function that converts keys into kebab-case.
 	 * @uses $fn_validate_webfont To run the function that validates each font-face (webfont) from theme.json.
 	 */
-	$fn_register_webfonts = static function() use ( &$registered_webfonts, $fn_get_webfonts_from_theme_json, $fn_convert_keys_to_kebab_case, $fn_validate_webfont, $fn_transform_src_into_uri ) {
+	$fn_register_webfonts = static function () use ( &$registered_webfonts, $fn_get_webfonts_from_theme_json, $fn_convert_keys_to_kebab_case, $fn_validate_webfont, $fn_transform_src_into_uri ) {
 		$registered_webfonts = array();
 
 		foreach ( $fn_get_webfonts_from_theme_json() as $webfont ) {
@@ -5662,7 +5919,7 @@ function _wp_theme_json_webfonts_handler() {
 	 * @param array $webfont Webfont to process.
 	 * @return array Ordered `src` items.
 	 */
-	$fn_order_src = static function( array $webfont ) {
+	$fn_order_src = static function ( array $webfont ) {
 		$src         = array();
 		$src_ordered = array();
 
@@ -5670,8 +5927,8 @@ function _wp_theme_json_webfonts_handler() {
 			// Add data URIs first.
 			if ( str_starts_with( trim( $url ), 'data:' ) ) {
 				$src_ordered[] = array(
-						'url'    => $url,
-						'format' => 'data',
+					'url'    => $url,
+					'format' => 'data',
 				);
 				continue;
 			}
@@ -5682,40 +5939,40 @@ function _wp_theme_json_webfonts_handler() {
 		// Add woff2.
 		if ( ! empty( $src['woff2'] ) ) {
 			$src_ordered[] = array(
-					'url'    => sanitize_url( $src['woff2'] ),
-					'format' => 'woff2',
+				'url'    => sanitize_url( $src['woff2'] ),
+				'format' => 'woff2',
 			);
 		}
 
 		// Add woff.
 		if ( ! empty( $src['woff'] ) ) {
 			$src_ordered[] = array(
-					'url'    => sanitize_url( $src['woff'] ),
-					'format' => 'woff',
+				'url'    => sanitize_url( $src['woff'] ),
+				'format' => 'woff',
 			);
 		}
 
 		// Add ttf.
 		if ( ! empty( $src['ttf'] ) ) {
 			$src_ordered[] = array(
-					'url'    => sanitize_url( $src['ttf'] ),
-					'format' => 'truetype',
+				'url'    => sanitize_url( $src['ttf'] ),
+				'format' => 'truetype',
 			);
 		}
 
 		// Add eot.
 		if ( ! empty( $src['eot'] ) ) {
 			$src_ordered[] = array(
-					'url'    => sanitize_url( $src['eot'] ),
-					'format' => 'embedded-opentype',
+				'url'    => sanitize_url( $src['eot'] ),
+				'format' => 'embedded-opentype',
 			);
 		}
 
 		// Add otf.
 		if ( ! empty( $src['otf'] ) ) {
 			$src_ordered[] = array(
-					'url'    => sanitize_url( $src['otf'] ),
-					'format' => 'opentype',
+				'url'    => sanitize_url( $src['otf'] ),
+				'format' => 'opentype',
 			);
 		}
 		$webfont['src'] = $src_ordered;
@@ -5733,7 +5990,7 @@ function _wp_theme_json_webfonts_handler() {
 	 * @param array  $value       Value to process.
 	 * @return string The CSS.
 	 */
-	$fn_compile_src = static function( $font_family, array $value ) {
+	$fn_compile_src = static function ( $font_family, array $value ) {
 		$src = '';
 
 		foreach ( $value as $item ) {
@@ -5755,7 +6012,7 @@ function _wp_theme_json_webfonts_handler() {
 	 * @param array $font_variation_settings Array of font variation settings.
 	 * @return string The CSS.
 	 */
-	$fn_compile_variations = static function( array $font_variation_settings ) {
+	$fn_compile_variations = static function ( array $font_variation_settings ) {
 		$variations = '';
 
 		foreach ( $font_variation_settings as $key => $value ) {
@@ -5776,7 +6033,7 @@ function _wp_theme_json_webfonts_handler() {
 	 * @param array $webfont Webfont to process.
 	 * @return string This font-family's CSS.
 	 */
-	$fn_build_font_face_css = static function( array $webfont ) use ( $fn_compile_src, $fn_compile_variations ) {
+	$fn_build_font_face_css = static function ( array $webfont ) use ( $fn_compile_src, $fn_compile_variations ) {
 		$css = '';
 
 		// Wrap font-family in quotes if it contains spaces.
@@ -5826,7 +6083,7 @@ function _wp_theme_json_webfonts_handler() {
 	 *
 	 * @return string The `@font-face` CSS.
 	 */
-	$fn_get_css = static function() use ( &$registered_webfonts, $fn_order_src, $fn_build_font_face_css ) {
+	$fn_get_css = static function () use ( &$registered_webfonts, $fn_order_src, $fn_build_font_face_css ) {
 		$css = '';
 
 		foreach ( $registered_webfonts as $webfont ) {
@@ -5847,7 +6104,7 @@ function _wp_theme_json_webfonts_handler() {
 	 *
 	 * @uses $fn_get_css To run the function that gets the CSS.
 	 */
-	$fn_generate_and_enqueue_styles = static function() use ( $fn_get_css ) {
+	$fn_generate_and_enqueue_styles = static function () use ( $fn_get_css ) {
 		// Generate the styles.
 		$styles = $fn_get_css();
 
@@ -5871,7 +6128,7 @@ function _wp_theme_json_webfonts_handler() {
 	 *
 	 * @uses $fn_get_css To run the function that gets the CSS.
 	 */
-	$fn_generate_and_enqueue_editor_styles = static function() use ( $fn_get_css ) {
+	$fn_generate_and_enqueue_editor_styles = static function () use ( $fn_get_css ) {
 		// Generate the styles.
 		$styles = $fn_get_css();
 
@@ -5968,7 +6225,7 @@ function _admin_bar_bump_cb() {
 	<style<?php echo $type_attr; ?> media="screen">
 	html { margin-top: 32px !important; }
 	@media screen and ( max-width: 782px ) {
-	  html { margin-top: 46px !important; }
+		html { margin-top: 46px !important; }
 	}
 	</style>
 	<?php
diff --git a/src/wp-includes/feed.php b/src/wp-includes/feed.php
index 8a6d256068..4f2cfca267 100644
--- a/src/wp-includes/feed.php
+++ b/src/wp-includes/feed.php
@@ -25,7 +25,7 @@
  * @return string
  */
 function get_bloginfo_rss( $show = '' ) {
-	$info = strip_tags( get_bloginfo( $show ) );
+	$info = wp_strip_all_tags( get_bloginfo( $show ) );
 	/**
 	 * Filters the bloginfo for use in RSS feeds.
 	 *
diff --git a/src/wp-includes/formatting.php b/src/wp-includes/formatting.php
index 3ecc352528..ca017e19b9 100644
--- a/src/wp-includes/formatting.php
+++ b/src/wp-includes/formatting.php
@@ -2259,7 +2259,7 @@ function sanitize_title_for_query( $title ) {
  * @return string The sanitized title.
  */
 function sanitize_title_with_dashes( $title, $raw_title = '', $context = 'display' ) {
-	$title = strip_tags( $title );
+	$title = wp_strip_all_tags( $title );
 	// Preserve escaped octets.
 	$title = preg_replace( '|%([a-fA-F0-9][a-fA-F0-9])|', '---$1---', $title );
 	// Remove percent signs that are not part of an octet.
@@ -4938,7 +4938,7 @@ function sanitize_option( $option, $value ) {
 			if ( is_wp_error( $value ) ) {
 				$error = $value->get_error_message();
 			} else {
-				$value = strip_tags( $value );
+				$value = wp_strip_all_tags( $value );
 				$value = wp_kses_data( $value );
 			}
 			break;
@@ -4962,12 +4962,10 @@ function sanitize_option( $option, $value ) {
 			$value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value );
 			if ( is_wp_error( $value ) ) {
 				$error = $value->get_error_message();
-			} else {
-				if ( preg_match( '#http(s?)://(.+)#i', $value ) ) {
+			} elseif ( preg_match( '#http(s?)://(.+)#i', $value ) ) {
 					$value = sanitize_url( $value );
-				} else {
-					$error = __( 'The WordPress address you entered did not appear to be a valid URL. Please enter a valid URL.' );
-				}
+			} else {
+				$error = __( 'The WordPress address you entered did not appear to be a valid URL. Please enter a valid URL.' );
 			}
 			break;
 
@@ -4975,12 +4973,10 @@ function sanitize_option( $option, $value ) {
 			$value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value );
 			if ( is_wp_error( $value ) ) {
 				$error = $value->get_error_message();
-			} else {
-				if ( preg_match( '#http(s?)://(.+)#i', $value ) ) {
+			} elseif ( preg_match( '#http(s?)://(.+)#i', $value ) ) {
 					$value = sanitize_url( $value );
-				} else {
-					$error = __( 'The Site address you entered did not appear to be a valid URL. Please enter a valid URL.' );
-				}
+			} else {
+				$error = __( 'The Site address you entered did not appear to be a valid URL. Please enter a valid URL.' );
 			}
 			break;
 
@@ -5495,8 +5491,8 @@ function normalize_whitespace( $str ) {
 /**
  * Properly strips all HTML tags including 'script' and 'style'.
  *
- * This differs from strip_tags() because it removes the contents of
- * the `<script>` and `<style>` tags. E.g. `strip_tags( '<script>something</script>' )`
+ * This differs from wp_strip_all_tags() because it removes the contents of
+ * the `<script>` and `<style>` tags. E.g. `wp_strip_all_tags( '<script>something</script>' )`
  * will return 'something'. wp_strip_all_tags() will return an empty string.
  *
  * @since 2.9.0
@@ -5534,7 +5530,7 @@ function wp_strip_all_tags( $text, $remove_breaks = false ) {
 	}
 
 	$text = preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $text );
-	$text = strip_tags( $text );
+	$text = wp_strip_all_tags( $text );
 
 	if ( $remove_breaks ) {
 		$text = preg_replace( '/[\r\n\t ]+/', ' ', $text );
diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php
index e96f0f7c37..4e2cedb81f 100644
--- a/src/wp-includes/general-template.php
+++ b/src/wp-includes/general-template.php
@@ -1416,7 +1416,7 @@ function wp_title( $sep = '&raquo;', $display = true, $seplocation = '' ) {
 	// If it's a search.
 	if ( is_search() ) {
 		/* translators: 1: Separator, 2: Search query. */
-		$title = sprintf( __( 'Search Results %1$s %2$s' ), $t_sep, strip_tags( $search ) );
+		$title = sprintf( __( 'Search Results %1$s %2$s' ), $t_sep, wp_strip_all_tags( $search ) );
 	}
 
 	// If it's a 404 page.
@@ -2195,7 +2195,7 @@ function wp_get_archives( $args = '' ) {
 					$url = get_permalink( $result );
 					if ( $result->post_title ) {
 						/** This filter is documented in wp-includes/post-template.php */
-						$text = strip_tags( apply_filters( 'the_title', $result->post_title, $result->ID ) );
+						$text = wp_strip_all_tags( apply_filters( 'the_title', $result->post_title, $result->ID ) );
 					} else {
 						$text = $result->ID;
 					}
@@ -4609,13 +4609,12 @@ function paginate_links( $args = '' ) {
 			);
 
 			$dots = true;
-		else :
-			if ( $args['show_all'] || ( $n <= $end_size || ( $current && $n >= $current - $mid_size && $n <= $current + $mid_size ) || $n > $total - $end_size ) ) :
+		elseif ( $args['show_all'] || ( $n <= $end_size || ( $current && $n >= $current - $mid_size && $n <= $current + $mid_size ) || $n > $total - $end_size ) ) :
 				$link = str_replace( '%_%', 1 == $n ? '' : $args['format'], $args['base'] );
 				$link = str_replace( '%#%', $n, $link );
-				if ( $add_args ) {
-					$link = add_query_arg( $add_args, $link );
-				}
+			if ( $add_args ) {
+				$link = add_query_arg( $add_args, $link );
+			}
 				$link .= $args['add_fragment'];
 
 				$page_links[] = sprintf(
@@ -4630,7 +4629,6 @@ function paginate_links( $args = '' ) {
 				$page_links[] = '<span class="page-numbers dots">' . __( '&hellip;' ) . '</span>';
 
 				$dots = false;
-			endif;
 		endif;
 	endfor;
 
diff --git a/src/wp-includes/kses.php b/src/wp-includes/kses.php
index cd30d845f8..98c634ef0e 100644
--- a/src/wp-includes/kses.php
+++ b/src/wp-includes/kses.php
@@ -1074,7 +1074,7 @@ function _wp_kses_split_callback( $matches ) {
  *
  * This function does a lot of work. It rejects some very malformed things like
  * `<:::>`. It returns an empty string, if the element isn't allowed (look ma, no
- * `strip_tags()`!). Otherwise it splits the tag into an element and an attribute
+ * `wp_strip_all_tags()`!). Otherwise it splits the tag into an element and an attribute
  * list.
  *
  * After the tag is split into an element and an attribute list, it is run
diff --git a/src/wp-includes/media.php b/src/wp-includes/media.php
index 2f280a5879..75ecf09c2c 100644
--- a/src/wp-includes/media.php
+++ b/src/wp-includes/media.php
@@ -576,10 +576,8 @@ function image_resize_dimensions( $orig_w, $orig_h, $dest_w, $dest_h, $crop = fa
 		if ( $orig_h < $dest_h ) {
 			return false;
 		}
-	} else {
-		if ( $orig_w < $dest_w && $orig_h < $dest_h ) {
+	} elseif ( $orig_w < $dest_w && $orig_h < $dest_h ) {
 			return false;
-		}
 	}
 
 	if ( $crop ) {
@@ -1075,7 +1073,7 @@ function wp_get_attachment_image( $attachment_id, $size = 'thumbnail', $icon = f
 		$default_attr = array(
 			'src'   => $src,
 			'class' => "attachment-$size_class size-$size_class",
-			'alt'   => trim( strip_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ),
+			'alt'   => trim( wp_strip_all_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ),
 		);
 
 		/**
diff --git a/src/wp-includes/ms-functions.php b/src/wp-includes/ms-functions.php
index fa8df6d108..6fb900c0e7 100644
--- a/src/wp-includes/ms-functions.php
+++ b/src/wp-includes/ms-functions.php
@@ -626,7 +626,7 @@ function wpmu_validate_blog_signup( $blogname, $blog_title, $user = '' ) {
 	$current_network = get_network();
 	$base            = $current_network->path;
 
-	$blog_title = strip_tags( $blog_title );
+	$blog_title = wp_strip_all_tags( $blog_title );
 
 	$errors        = new WP_Error();
 	$illegal_names = get_site_option( 'illegal_names' );
@@ -1368,7 +1368,7 @@ function wpmu_create_blog( $domain, $path, $title, $user_id, $options = array(),
 	);
 	$options  = wp_parse_args( $options, $defaults );
 
-	$title   = strip_tags( $title );
+	$title   = wp_strip_all_tags( $title );
 	$user_id = (int) $user_id;
 
 	// Check if the domain has been used already. We should return an error message.
diff --git a/src/wp-includes/post-template.php b/src/wp-includes/post-template.php
index 4f3bfbef0c..b48693740b 100644
--- a/src/wp-includes/post-template.php
+++ b/src/wp-includes/post-template.php
@@ -94,7 +94,7 @@ function the_title_attribute( $args = '' ) {
 	}
 
 	$title = $parsed_args['before'] . $title . $parsed_args['after'];
-	$title = esc_attr( strip_tags( $title ) );
+	$title = esc_attr( wp_strip_all_tags( $title ) );
 
 	if ( $parsed_args['echo'] ) {
 		echo $title;
@@ -337,7 +337,7 @@ function get_the_content( $more_link_text = null, $strip_teaser = false, $post =
 		$content = explode( $matches[0], $content, 2 );
 
 		if ( ! empty( $matches[1] ) && ! empty( $more_link_text ) ) {
-			$more_link_text = strip_tags( wp_kses_no_null( trim( $matches[1] ) ) );
+			$more_link_text = wp_strip_all_tags( wp_kses_no_null( trim( $matches[1] ) ) );
 		}
 
 		$has_teaser = true;
@@ -1060,14 +1060,12 @@ function _wp_link_page( $i ) {
 
 	if ( 1 === $i ) {
 		$url = get_permalink();
-	} else {
-		if ( ! get_option( 'permalink_structure' ) || in_array( $post->post_status, array( 'draft', 'pending' ), true ) ) {
+	} elseif ( ! get_option( 'permalink_structure' ) || in_array( $post->post_status, array( 'draft', 'pending' ), true ) ) {
 			$url = add_query_arg( 'page', $i, get_permalink() );
-		} elseif ( 'page' === get_option( 'show_on_front' ) && (int) get_option( 'page_on_front' ) === $post->ID ) {
-			$url = trailingslashit( get_permalink() ) . user_trailingslashit( "$wp_rewrite->pagination_base/" . $i, 'single_paged' );
-		} else {
-			$url = trailingslashit( get_permalink() ) . user_trailingslashit( $i, 'single_paged' );
-		}
+	} elseif ( 'page' === get_option( 'show_on_front' ) && (int) get_option( 'page_on_front' ) === $post->ID ) {
+		$url = trailingslashit( get_permalink() ) . user_trailingslashit( "$wp_rewrite->pagination_base/" . $i, 'single_paged' );
+	} else {
+		$url = trailingslashit( get_permalink() ) . user_trailingslashit( $i, 'single_paged' );
 	}
 
 	if ( is_preview() ) {
diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php
index eb90e762f5..3309271c54 100644
--- a/src/wp-includes/post.php
+++ b/src/wp-includes/post.php
@@ -642,7 +642,8 @@ function create_initial_post_types() {
 		array(
 			'label'       => _x( 'Published', 'post status' ),
 			'public'      => true,
-			'_builtin'    => true, /* internal use only. */
+			'_builtin'    => true, /*
+		internal use only. */
 			/* translators: %s: Number of published posts. */
 			'label_count' => _n_noop(
 				'Published <span class="count">(%s)</span>',
@@ -656,7 +657,8 @@ function create_initial_post_types() {
 		array(
 			'label'       => _x( 'Scheduled', 'post status' ),
 			'protected'   => true,
-			'_builtin'    => true, /* internal use only. */
+			'_builtin'    => true, /*
+		internal use only. */
 			/* translators: %s: Number of scheduled posts. */
 			'label_count' => _n_noop(
 				'Scheduled <span class="count">(%s)</span>',
@@ -670,7 +672,8 @@ function create_initial_post_types() {
 		array(
 			'label'         => _x( 'Draft', 'post status' ),
 			'protected'     => true,
-			'_builtin'      => true, /* internal use only. */
+			'_builtin'      => true, /*
+		internal use only. */
 			/* translators: %s: Number of draft posts. */
 			'label_count'   => _n_noop(
 				'Draft <span class="count">(%s)</span>',
@@ -685,7 +688,8 @@ function create_initial_post_types() {
 		array(
 			'label'         => _x( 'Pending', 'post status' ),
 			'protected'     => true,
-			'_builtin'      => true, /* internal use only. */
+			'_builtin'      => true, /*
+		internal use only. */
 			/* translators: %s: Number of pending posts. */
 			'label_count'   => _n_noop(
 				'Pending <span class="count">(%s)</span>',
@@ -700,7 +704,8 @@ function create_initial_post_types() {
 		array(
 			'label'       => _x( 'Private', 'post status' ),
 			'private'     => true,
-			'_builtin'    => true, /* internal use only. */
+			'_builtin'    => true, /*
+		internal use only. */
 			/* translators: %s: Number of private posts. */
 			'label_count' => _n_noop(
 				'Private <span class="count">(%s)</span>',
@@ -714,7 +719,8 @@ function create_initial_post_types() {
 		array(
 			'label'                     => _x( 'Trash', 'post status' ),
 			'internal'                  => true,
-			'_builtin'                  => true, /* internal use only. */
+			'_builtin'                  => true, /*
+		internal use only. */
 			/* translators: %s: Number of trashed posts. */
 			'label_count'               => _n_noop(
 				'Trash <span class="count">(%s)</span>',
@@ -749,7 +755,8 @@ function create_initial_post_types() {
 		array(
 			'label'               => _x( 'Pending', 'request status' ),
 			'internal'            => true,
-			'_builtin'            => true, /* internal use only. */
+			'_builtin'            => true, /*
+		internal use only. */
 			/* translators: %s: Number of pending requests. */
 			'label_count'         => _n_noop(
 				'Pending <span class="count">(%s)</span>',
@@ -764,7 +771,8 @@ function create_initial_post_types() {
 		array(
 			'label'               => _x( 'Confirmed', 'request status' ),
 			'internal'            => true,
-			'_builtin'            => true, /* internal use only. */
+			'_builtin'            => true, /*
+		internal use only. */
 			/* translators: %s: Number of confirmed requests. */
 			'label_count'         => _n_noop(
 				'Confirmed <span class="count">(%s)</span>',
@@ -779,7 +787,8 @@ function create_initial_post_types() {
 		array(
 			'label'               => _x( 'Failed', 'request status' ),
 			'internal'            => true,
-			'_builtin'            => true, /* internal use only. */
+			'_builtin'            => true, /*
+		internal use only. */
 			/* translators: %s: Number of failed requests. */
 			'label_count'         => _n_noop(
 				'Failed <span class="count">(%s)</span>',
@@ -794,7 +803,8 @@ function create_initial_post_types() {
 		array(
 			'label'               => _x( 'Completed', 'request status' ),
 			'internal'            => true,
-			'_builtin'            => true, /* internal use only. */
+			'_builtin'            => true, /*
+		internal use only. */
 			/* translators: %s: Number of completed requests. */
 			'label_count'         => _n_noop(
 				'Completed <span class="count">(%s)</span>',
@@ -5940,7 +5950,7 @@ function trackback_url_list( $tb_list, $post_id ) {
 		$postdata = get_post( $post_id, ARRAY_A );
 
 		// Form an excerpt.
-		$excerpt = strip_tags( $postdata['post_excerpt'] ? $postdata['post_excerpt'] : $postdata['post_content'] );
+		$excerpt = wp_strip_all_tags( $postdata['post_excerpt'] ? $postdata['post_excerpt'] : $postdata['post_content'] );
 
 		if ( strlen( $excerpt ) > 255 ) {
 			$excerpt = substr( $excerpt, 0, 252 ) . '&hellip;';
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-plugins-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-plugins-controller.php
index d0dd5fce4c..ee94c2d5a8 100644
--- a/src/wp-includes/rest-api/endpoints/class-wp-rest-plugins-controller.php
+++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-plugins-controller.php
@@ -809,7 +809,7 @@ class WP_REST_Plugins_Controller extends WP_REST_Controller {
 			$matched_search = false;
 
 			foreach ( $item as $field ) {
-				if ( is_string( $field ) && str_contains( strip_tags( $field ), $search ) ) {
+				if ( is_string( $field ) && str_contains( wp_strip_all_tags( $field ), $search ) ) {
 					$matched_search = true;
 					break;
 				}
diff --git a/src/wp-includes/rss.php b/src/wp-includes/rss.php
index d113eee1c2..beaeaccdf7 100644
--- a/src/wp-includes/rss.php
+++ b/src/wp-includes/rss.php
@@ -27,42 +27,42 @@ _deprecated_file( basename( __FILE__ ), '3.0.0', WPINC . '/class-simplepie.php'
 do_action( 'load_feed_engine' );
 
 /** RSS feed constant. */
-define('RSS', 'RSS');
-define('ATOM', 'Atom');
-define('MAGPIE_USER_AGENT', 'WordPress/' . $GLOBALS['wp_version']);
+define( 'RSS', 'RSS' );
+define( 'ATOM', 'Atom' );
+define( 'MAGPIE_USER_AGENT', 'WordPress/' . $GLOBALS['wp_version'] );
 
 class MagpieRSS {
 	var $parser;
-	var $current_item	= array();	// item currently being parsed
-	var $items			= array();	// collection of parsed items
-	var $channel		= array();	// hash of channel fields
-	var $textinput		= array();
-	var $image			= array();
+	var $current_item = array();  // item currently being parsed
+	var $items        = array();  // collection of parsed items
+	var $channel      = array();  // hash of channel fields
+	var $textinput    = array();
+	var $image        = array();
 	var $feed_type;
 	var $feed_version;
 
 	// parser variables
-	var $stack				= array(); // parser stack
-	var $inchannel			= false;
-	var $initem 			= false;
-	var $incontent			= false; // if in Atom <content mode="xml"> field
-	var $intextinput		= false;
-	var $inimage 			= false;
-	var $current_field		= '';
-	var $current_namespace	= false;
+	var $stack             = array(); // parser stack
+	var $inchannel         = false;
+	var $initem            = false;
+	var $incontent         = false; // if in Atom <content mode="xml"> field
+	var $intextinput       = false;
+	var $inimage           = false;
+	var $current_field     = '';
+	var $current_namespace = false;
 
-	//var $ERROR = "";
+	// var $ERROR = "";
 
-	var $_CONTENT_CONSTRUCTS = array('content', 'summary', 'info', 'title', 'tagline', 'copyright');
+	var $_CONTENT_CONSTRUCTS = array( 'content', 'summary', 'info', 'title', 'tagline', 'copyright' );
 
 	/**
 	 * PHP5 constructor.
 	 */
 	function __construct( $source ) {
 
-		# Check if PHP xml isn't compiled
-		#
-		if ( ! function_exists('xml_parser_create') ) {
+		// Check if PHP xml isn't compiled
+		//
+		if ( ! function_exists( 'xml_parser_create' ) ) {
 			wp_trigger_error( '', "PHP's XML extension is not available. Please contact your hosting provider to enable PHP's XML extension." );
 			return;
 		}
@@ -71,23 +71,26 @@ class MagpieRSS {
 
 		$this->parser = $parser;
 
-		# pass in parser, and a reference to this object
-		# set up handlers
-		#
-		xml_set_element_handler($this->parser,
-				array( $this, 'feed_start_element' ), array( $this, 'feed_end_element' ) );
+		// pass in parser, and a reference to this object
+		// set up handlers
+		//
+		xml_set_element_handler(
+			$this->parser,
+			array( $this, 'feed_start_element' ),
+			array( $this, 'feed_end_element' )
+		);
 
 		xml_set_character_data_handler( $this->parser, array( $this, 'feed_cdata' ) );
 
 		$status = xml_parse( $this->parser, $source );
 
-		if (! $status ) {
+		if ( ! $status ) {
 			$errorcode = xml_get_error_code( $this->parser );
 			if ( $errorcode != XML_ERROR_NONE ) {
-				$xml_error = xml_error_string( $errorcode );
-				$error_line = xml_get_current_line_number($this->parser);
-				$error_col = xml_get_current_column_number($this->parser);
-				$errormsg = "$xml_error at line $error_line, column $error_col";
+				$xml_error  = xml_error_string( $errorcode );
+				$error_line = xml_get_current_line_number( $this->parser );
+				$error_col  = xml_get_current_column_number( $this->parser );
+				$errormsg   = "$xml_error at line $error_line, column $error_col";
 
 				$this->error( $errormsg );
 			}
@@ -106,74 +109,64 @@ class MagpieRSS {
 		self::__construct( $source );
 	}
 
-	function feed_start_element($p, $element, &$attrs) {
-		$el = $element = strtolower($element);
-		$attrs = array_change_key_case($attrs, CASE_LOWER);
+	function feed_start_element( $p, $element, &$attrs ) {
+		$el    = $element = strtolower( $element );
+		$attrs = array_change_key_case( $attrs, CASE_LOWER );
 
 		// check for a namespace, and split if found
-		$ns	= false;
+		$ns = false;
 		if ( strpos( $element, ':' ) ) {
-			list($ns, $el) = explode( ':', $element, 2);
+			list($ns, $el) = explode( ':', $element, 2 );
 		}
 		if ( $ns and $ns != 'rdf' ) {
 			$this->current_namespace = $ns;
 		}
 
-		# if feed type isn't set, then this is first element of feed
-		# identify feed from root element
-		#
-		if (!isset($this->feed_type) ) {
+		// if feed type isn't set, then this is first element of feed
+		// identify feed from root element
+		//
+		if ( ! isset( $this->feed_type ) ) {
 			if ( $el == 'rdf' ) {
-				$this->feed_type = RSS;
+				$this->feed_type    = RSS;
 				$this->feed_version = '1.0';
-			}
-			elseif ( $el == 'rss' ) {
-				$this->feed_type = RSS;
+			} elseif ( $el == 'rss' ) {
+				$this->feed_type    = RSS;
 				$this->feed_version = $attrs['version'];
-			}
-			elseif ( $el == 'feed' ) {
-				$this->feed_type = ATOM;
+			} elseif ( $el == 'feed' ) {
+				$this->feed_type    = ATOM;
 				$this->feed_version = $attrs['version'];
-				$this->inchannel = true;
+				$this->inchannel    = true;
 			}
 			return;
 		}
 
-		if ( $el == 'channel' )
-		{
+		if ( $el == 'channel' ) {
 			$this->inchannel = true;
-		}
-		elseif ($el == 'item' or $el == 'entry' )
-		{
+		} elseif ( $el == 'item' or $el == 'entry' ) {
 			$this->initem = true;
-			if ( isset($attrs['rdf:about']) ) {
+			if ( isset( $attrs['rdf:about'] ) ) {
 				$this->current_item['about'] = $attrs['rdf:about'];
 			}
 		}
 
 		// if we're in the default namespace of an RSS feed,
-		//  record textinput or image fields
+		// record textinput or image fields
 		elseif (
 			$this->feed_type == RSS and
 			$this->current_namespace == '' and
-			$el == 'textinput' )
-		{
+			$el == 'textinput' ) {
 			$this->intextinput = true;
-		}
-
-		elseif (
+		} elseif (
 			$this->feed_type == RSS and
 			$this->current_namespace == '' and
-			$el == 'image' )
-		{
+			$el == 'image' ) {
 			$this->inimage = true;
 		}
 
-		# handle atom content constructs
-		elseif ( $this->feed_type == ATOM and in_array($el, $this->_CONTENT_CONSTRUCTS) )
-		{
+		// handle atom content constructs
+		elseif ( $this->feed_type == ATOM and in_array( $el, $this->_CONTENT_CONSTRUCTS ) ) {
 			// avoid clashing w/ RSS mod_content
-			if ($el == 'content' ) {
+			if ( $el == 'content' ) {
 				$el = 'atom_content';
 			}
 
@@ -182,15 +175,18 @@ class MagpieRSS {
 		}
 
 		// if inside an Atom content construct (e.g. content or summary) field treat tags as text
-		elseif ($this->feed_type == ATOM and $this->incontent )
-		{
+		elseif ( $this->feed_type == ATOM and $this->incontent ) {
 			// if tags are inlined, then flatten
-			$attrs_str = join(' ',
-					array_map(array('MagpieRSS', 'map_attrs'),
-					array_keys($attrs),
-					array_values($attrs) ) );
+			$attrs_str = join(
+				' ',
+				array_map(
+					array( 'MagpieRSS', 'map_attrs' ),
+					array_keys( $attrs ),
+					array_values( $attrs )
+				)
+			);
 
-			$this->append_content( "<$element $attrs_str>"  );
+			$this->append_content( "<$element $attrs_str>" );
 
 			array_unshift( $this->stack, $el );
 		}
@@ -199,175 +195,163 @@ class MagpieRSS {
 		// Magpie treats link elements of type rel='alternate'
 		// as being equivalent to RSS's simple link element.
 		//
-		elseif ($this->feed_type == ATOM and $el == 'link' )
-		{
-			if ( isset($attrs['rel']) and $attrs['rel'] == 'alternate' )
-			{
+		elseif ( $this->feed_type == ATOM and $el == 'link' ) {
+			if ( isset( $attrs['rel'] ) and $attrs['rel'] == 'alternate' ) {
 				$link_el = 'link';
-			}
-			else {
+			} else {
 				$link_el = 'link_' . $attrs['rel'];
 			}
 
-			$this->append($link_el, $attrs['href']);
+			$this->append( $link_el, $attrs['href'] );
 		}
 		// set stack[0] to current element
 		else {
-			array_unshift($this->stack, $el);
+			array_unshift( $this->stack, $el );
 		}
 	}
 
-	function feed_cdata ($p, $text) {
+	function feed_cdata( $p, $text ) {
 
-		if ($this->feed_type == ATOM and $this->incontent)
-		{
+		if ( $this->feed_type == ATOM and $this->incontent ) {
 			$this->append_content( $text );
-		}
-		else {
-			$current_el = join('_', array_reverse($this->stack));
-			$this->append($current_el, $text);
+		} else {
+			$current_el = join( '_', array_reverse( $this->stack ) );
+			$this->append( $current_el, $text );
 		}
 	}
 
-	function feed_end_element ($p, $el) {
-		$el = strtolower($el);
+	function feed_end_element( $p, $el ) {
+		$el = strtolower( $el );
 
-		if ( $el == 'item' or $el == 'entry' )
-		{
-			$this->items[] = $this->current_item;
+		if ( $el == 'item' or $el == 'entry' ) {
+			$this->items[]      = $this->current_item;
 			$this->current_item = array();
-			$this->initem = false;
-		}
-		elseif ($this->feed_type == RSS and $this->current_namespace == '' and $el == 'textinput' )
-		{
+			$this->initem       = false;
+		} elseif ( $this->feed_type == RSS and $this->current_namespace == '' and $el == 'textinput' ) {
 			$this->intextinput = false;
-		}
-		elseif ($this->feed_type == RSS and $this->current_namespace == '' and $el == 'image' )
-		{
+		} elseif ( $this->feed_type == RSS and $this->current_namespace == '' and $el == 'image' ) {
 			$this->inimage = false;
-		}
-		elseif ($this->feed_type == ATOM and in_array($el, $this->_CONTENT_CONSTRUCTS) )
-		{
+		} elseif ( $this->feed_type == ATOM and in_array( $el, $this->_CONTENT_CONSTRUCTS ) ) {
 			$this->incontent = false;
-		}
-		elseif ($el == 'channel' or $el == 'feed' )
-		{
+		} elseif ( $el == 'channel' or $el == 'feed' ) {
 			$this->inchannel = false;
-		}
-		elseif ($this->feed_type == ATOM and $this->incontent  ) {
+		} elseif ( $this->feed_type == ATOM and $this->incontent ) {
 			// balance tags properly
 			// note: This may not actually be necessary
-			if ( $this->stack[0] == $el )
-			{
-				$this->append_content("</$el>");
-			}
-			else {
-				$this->append_content("<$el />");
+			if ( $this->stack[0] == $el ) {
+				$this->append_content( "</$el>" );
+			} else {
+				$this->append_content( "<$el />" );
 			}
 
 			array_shift( $this->stack );
-		}
-		else {
+		} else {
 			array_shift( $this->stack );
 		}
 
 		$this->current_namespace = false;
 	}
 
-	function concat (&$str1, $str2="") {
-		if (!isset($str1) ) {
-			$str1="";
+	function concat( &$str1, $str2 = '' ) {
+		if ( ! isset( $str1 ) ) {
+			$str1 = '';
 		}
 		$str1 .= $str2;
 	}
 
-	function append_content($text) {
+	function append_content( $text ) {
 		if ( $this->initem ) {
 			$this->concat( $this->current_item[ $this->incontent ], $text );
-		}
-		elseif ( $this->inchannel ) {
+		} elseif ( $this->inchannel ) {
 			$this->concat( $this->channel[ $this->incontent ], $text );
 		}
 	}
 
 	// smart append - field and namespace aware
-	function append($el, $text) {
-		if (!$el) {
+	function append( $el, $text ) {
+		if ( ! $el ) {
 			return;
 		}
-		if ( $this->current_namespace )
-		{
+		if ( $this->current_namespace ) {
 			if ( $this->initem ) {
 				$this->concat(
-					$this->current_item[ $this->current_namespace ][ $el ], $text);
-			}
-			elseif ($this->inchannel) {
-				$this->concat(
-					$this->channel[ $this->current_namespace][ $el ], $text );
-			}
-			elseif ($this->intextinput) {
-				$this->concat(
-					$this->textinput[ $this->current_namespace][ $el ], $text );
-			}
-			elseif ($this->inimage) {
-				$this->concat(
-					$this->image[ $this->current_namespace ][ $el ], $text );
-			}
-		}
-		else {
-			if ( $this->initem ) {
+					$this->current_item[ $this->current_namespace ][ $el ],
+					$text
+				);
+			} elseif ( $this->inchannel ) {
 				$this->concat(
-					$this->current_item[ $el ], $text);
-			}
-			elseif ($this->intextinput) {
+					$this->channel[ $this->current_namespace ][ $el ],
+					$text
+				);
+			} elseif ( $this->intextinput ) {
 				$this->concat(
-					$this->textinput[ $el ], $text );
-			}
-			elseif ($this->inimage) {
+					$this->textinput[ $this->current_namespace ][ $el ],
+					$text
+				);
+			} elseif ( $this->inimage ) {
 				$this->concat(
-					$this->image[ $el ], $text );
+					$this->image[ $this->current_namespace ][ $el ],
+					$text
+				);
 			}
-			elseif ($this->inchannel) {
+		} elseif ( $this->initem ) {
 				$this->concat(
-					$this->channel[ $el ], $text );
-			}
-
+					$this->current_item[ $el ],
+					$text
+				);
+		} elseif ( $this->intextinput ) {
+			$this->concat(
+				$this->textinput[ $el ],
+				$text
+			);
+		} elseif ( $this->inimage ) {
+			$this->concat(
+				$this->image[ $el ],
+				$text
+			);
+		} elseif ( $this->inchannel ) {
+			$this->concat(
+				$this->channel[ $el ],
+				$text
+			);
 		}
 	}
 
-	function normalize () {
+	function normalize() {
 		// if atom populate rss fields
 		if ( $this->is_atom() ) {
 			$this->channel['description'] = $this->channel['tagline'];
-			for ( $i = 0; $i < count($this->items); $i++) {
-				$item = $this->items[$i];
-				if ( isset($item['summary']) )
+			for ( $i = 0; $i < count( $this->items ); $i++ ) {
+				$item = $this->items[ $i ];
+				if ( isset( $item['summary'] ) ) {
 					$item['description'] = $item['summary'];
-				if ( isset($item['atom_content']))
+				}
+				if ( isset( $item['atom_content'] ) ) {
 					$item['content']['encoded'] = $item['atom_content'];
+				}
 
-				$this->items[$i] = $item;
+				$this->items[ $i ] = $item;
 			}
-		}
-		elseif ( $this->is_rss() ) {
+		} elseif ( $this->is_rss() ) {
 			$this->channel['tagline'] = $this->channel['description'];
-			for ( $i = 0; $i < count($this->items); $i++) {
-				$item = $this->items[$i];
-				if ( isset($item['description']))
+			for ( $i = 0; $i < count( $this->items ); $i++ ) {
+				$item = $this->items[ $i ];
+				if ( isset( $item['description'] ) ) {
 					$item['summary'] = $item['description'];
-				if ( isset($item['content']['encoded'] ) )
+				}
+				if ( isset( $item['content']['encoded'] ) ) {
 					$item['atom_content'] = $item['content']['encoded'];
+				}
 
-				$this->items[$i] = $item;
+				$this->items[ $i ] = $item;
 			}
 		}
 	}
 
-	function is_rss () {
+	function is_rss() {
 		if ( $this->feed_type == RSS ) {
 			return $this->feed_version;
-		}
-		else {
+		} else {
 			return false;
 		}
 	}
@@ -375,162 +359,155 @@ class MagpieRSS {
 	function is_atom() {
 		if ( $this->feed_type == ATOM ) {
 			return $this->feed_version;
-		}
-		else {
+		} else {
 			return false;
 		}
 	}
 
-	function map_attrs($k, $v) {
+	function map_attrs( $k, $v ) {
 		return "$k=\"$v\"";
 	}
 
 	function error( $errormsg, $lvl = E_USER_WARNING ) {
 		if ( MAGPIE_DEBUG ) {
-			wp_trigger_error('', $errormsg, $lvl);
+			wp_trigger_error( '', $errormsg, $lvl );
 		} else {
-			error_log( $errormsg, 0);
+			error_log( $errormsg, 0 );
 		}
 	}
-
 }
 
-if ( !function_exists('fetch_rss') ) :
-/**
- * Build Magpie object based on RSS from URL.
- *
- * @since 1.5.0
- * @package External
- * @subpackage MagpieRSS
- *
- * @param string $url URL to retrieve feed.
- * @return MagpieRSS|false MagpieRSS object on success, false on failure.
- */
-function fetch_rss ($url) {
-	// initialize constants
-	init();
-
-	if ( !isset($url) ) {
-		// error("fetch_rss called without a url");
-		return false;
-	}
+if ( ! function_exists( 'fetch_rss' ) ) :
+	/**
+	 * Build Magpie object based on RSS from URL.
+	 *
+	 * @since 1.5.0
+	 * @package External
+	 * @subpackage MagpieRSS
+	 *
+	 * @param string $url URL to retrieve feed.
+	 * @return MagpieRSS|false MagpieRSS object on success, false on failure.
+	 */
+	function fetch_rss( $url ) {
+		// initialize constants
+		init();
 
-	// if cache is disabled
-	if ( !MAGPIE_CACHE_ON ) {
-		// fetch file, and parse it
-		$resp = _fetch_remote_file( $url );
-		if ( is_success( $resp->status ) ) {
-			return _response_to_rss( $resp );
-		}
-		else {
-			// error("Failed to fetch $url and cache is off");
+		if ( ! isset( $url ) ) {
+			// error("fetch_rss called without a url");
 			return false;
 		}
-	}
-	// else cache is ON
-	else {
-		// Flow
-		// 1. check cache
-		// 2. if there is a hit, make sure it's fresh
-		// 3. if cached obj fails freshness check, fetch remote
-		// 4. if remote fails, return stale object, or error
-
-		$cache = new RSSCache( MAGPIE_CACHE_DIR, MAGPIE_CACHE_AGE );
 
-		if (MAGPIE_DEBUG and $cache->ERROR) {
-			debug($cache->ERROR, E_USER_WARNING);
+		// if cache is disabled
+		if ( ! MAGPIE_CACHE_ON ) {
+			// fetch file, and parse it
+			$resp = _fetch_remote_file( $url );
+			if ( is_success( $resp->status ) ) {
+				return _response_to_rss( $resp );
+			} else {
+				// error("Failed to fetch $url and cache is off");
+				return false;
+			}
 		}
+		// else cache is ON
+		else {
+			// Flow
+			// 1. check cache
+			// 2. if there is a hit, make sure it's fresh
+			// 3. if cached obj fails freshness check, fetch remote
+			// 4. if remote fails, return stale object, or error
 
-		$cache_status 	 = 0;		// response of check_cache
-		$request_headers = array(); // HTTP headers to send with fetch
-		$rss 			 = 0;		// parsed RSS object
-		$errormsg		 = 0;		// errors, if any
+			$cache = new RSSCache( MAGPIE_CACHE_DIR, MAGPIE_CACHE_AGE );
 
-		if (!$cache->ERROR) {
-			// return cache HIT, MISS, or STALE
-			$cache_status = $cache->check_cache( $url );
-		}
-
-		// if object cached, and cache is fresh, return cached obj
-		if ( $cache_status == 'HIT' ) {
-			$rss = $cache->get( $url );
-			if ( isset($rss) and $rss ) {
-				$rss->from_cache = 1;
-				if ( MAGPIE_DEBUG > 1) {
-				debug("MagpieRSS: Cache HIT", E_USER_NOTICE);
-			}
-				return $rss;
+			if ( MAGPIE_DEBUG and $cache->ERROR ) {
+				debug( $cache->ERROR, E_USER_WARNING );
 			}
-		}
 
-		// else attempt a conditional get
+			$cache_status    = 0;       // response of check_cache
+			$request_headers = array(); // HTTP headers to send with fetch
+			$rss             = 0;       // parsed RSS object
+			$errormsg        = 0;       // errors, if any
 
-		// set up headers
-		if ( $cache_status == 'STALE' ) {
-			$rss = $cache->get( $url );
-			if ( isset($rss->etag) and $rss->last_modified ) {
-				$request_headers['If-None-Match'] = $rss->etag;
-				$request_headers['If-Last-Modified'] = $rss->last_modified;
+			if ( ! $cache->ERROR ) {
+				// return cache HIT, MISS, or STALE
+				$cache_status = $cache->check_cache( $url );
 			}
-		}
 
-		$resp = _fetch_remote_file( $url, $request_headers );
+			// if object cached, and cache is fresh, return cached obj
+			if ( $cache_status == 'HIT' ) {
+				$rss = $cache->get( $url );
+				if ( isset( $rss ) and $rss ) {
+					$rss->from_cache = 1;
+					if ( MAGPIE_DEBUG > 1 ) {
+						debug( 'MagpieRSS: Cache HIT', E_USER_NOTICE );
+					}
+					return $rss;
+				}
+			}
+
+			// else attempt a conditional get
 
-		if (isset($resp) and $resp) {
-			if ($resp->status == '304' ) {
-				// we have the most current copy
-				if ( MAGPIE_DEBUG > 1) {
-					debug("Got 304 for $url");
+			// set up headers
+			if ( $cache_status == 'STALE' ) {
+				$rss = $cache->get( $url );
+				if ( isset( $rss->etag ) and $rss->last_modified ) {
+					$request_headers['If-None-Match']    = $rss->etag;
+					$request_headers['If-Last-Modified'] = $rss->last_modified;
 				}
-				// reset cache on 304 (at minutillo insistent prodding)
-				$cache->set($url, $rss);
-				return $rss;
 			}
-			elseif ( is_success( $resp->status ) ) {
-				$rss = _response_to_rss( $resp );
-				if ( $rss ) {
-					if (MAGPIE_DEBUG > 1) {
-						debug("Fetch successful");
+
+			$resp = _fetch_remote_file( $url, $request_headers );
+
+			if ( isset( $resp ) and $resp ) {
+				if ( $resp->status == '304' ) {
+					// we have the most current copy
+					if ( MAGPIE_DEBUG > 1 ) {
+						debug( "Got 304 for $url" );
 					}
-					// add object to cache
+					// reset cache on 304 (at minutillo insistent prodding)
 					$cache->set( $url, $rss );
 					return $rss;
+				} elseif ( is_success( $resp->status ) ) {
+					$rss = _response_to_rss( $resp );
+					if ( $rss ) {
+						if ( MAGPIE_DEBUG > 1 ) {
+							debug( 'Fetch successful' );
+						}
+						// add object to cache
+						$cache->set( $url, $rss );
+						return $rss;
+					}
+				} else {
+					$errormsg = "Failed to fetch $url. ";
+					if ( $resp->error ) {
+						// compensate for Snoopy's annoying habit to tacking
+						// on '\n'
+						$http_error = substr( $resp->error, 0, -2 );
+						$errormsg  .= "(HTTP Error: $http_error)";
+					} else {
+						$errormsg .= '(HTTP Response: ' . $resp->response_code . ')';
+					}
 				}
+			} else {
+				$errormsg = 'Unable to retrieve RSS file for unknown reasons.';
 			}
-			else {
-				$errormsg = "Failed to fetch $url. ";
-				if ( $resp->error ) {
-					# compensate for Snoopy's annoying habit to tacking
-					# on '\n'
-					$http_error = substr($resp->error, 0, -2);
-					$errormsg .= "(HTTP Error: $http_error)";
-				}
-				else {
-					$errormsg .=  "(HTTP Response: " . $resp->response_code .')';
-				}
-			}
-		}
-		else {
-			$errormsg = "Unable to retrieve RSS file for unknown reasons.";
-		}
 
-		// else fetch failed
+			// else fetch failed
 
-		// attempt to return cached object
-		if ($rss) {
-			if ( MAGPIE_DEBUG ) {
-				debug("Returning STALE object for $url");
+			// attempt to return cached object
+			if ( $rss ) {
+				if ( MAGPIE_DEBUG ) {
+					debug( "Returning STALE object for $url" );
+				}
+				return $rss;
 			}
-			return $rss;
-		}
 
-		// else we totally failed
-		// error( $errormsg );
+			// else we totally failed
+			// error( $errormsg );
 
-		return false;
+			return false;
 
-	} // end if ( !MAGPIE_CACHE_ON ) {
-} // end fetch_rss()
+		} // end if ( !MAGPIE_CACHE_ON ) {
+	} // end fetch_rss()
 endif;
 
 /**
@@ -541,18 +518,24 @@ endif;
  * @subpackage MagpieRSS
  *
  * @param string $url URL to retrieve
- * @param array $headers Optional. Headers to send to the URL. Default empty string.
+ * @param array  $headers Optional. Headers to send to the URL. Default empty string.
  * @return Snoopy style response
  */
-function _fetch_remote_file($url, $headers = "" ) {
-	$resp = wp_safe_remote_request( $url, array( 'headers' => $headers, 'timeout' => MAGPIE_FETCH_TIME_OUT ) );
-	if ( is_wp_error($resp) ) {
-		$error = array_shift($resp->errors);
-
-		$resp = new stdClass;
-		$resp->status = 500;
+function _fetch_remote_file( $url, $headers = '' ) {
+	$resp = wp_safe_remote_request(
+		$url,
+		array(
+			'headers' => $headers,
+			'timeout' => MAGPIE_FETCH_TIME_OUT,
+		)
+	);
+	if ( is_wp_error( $resp ) ) {
+		$error = array_shift( $resp->errors );
+
+		$resp                = new stdClass();
+		$resp->status        = 500;
 		$resp->response_code = 500;
-		$resp->error = $error[0] . "\n"; //\n = Snoopy compatibility
+		$resp->error         = $error[0] . "\n"; // \n = Snoopy compatibility
 		return $resp;
 	}
 
@@ -560,19 +543,20 @@ function _fetch_remote_file($url, $headers = "" ) {
 	// Also note, WP_HTTP lowercases all keys, Snoopy did not.
 	$return_headers = array();
 	foreach ( wp_remote_retrieve_headers( $resp ) as $key => $value ) {
-		if ( !is_array($value) ) {
+		if ( ! is_array( $value ) ) {
 			$return_headers[] = "$key: $value";
 		} else {
-			foreach ( $value as $v )
+			foreach ( $value as $v ) {
 				$return_headers[] = "$key: $v";
+			}
 		}
 	}
 
-	$response = new stdClass;
-	$response->status = wp_remote_retrieve_response_code( $resp );
+	$response                = new stdClass();
+	$response->status        = wp_remote_retrieve_response_code( $resp );
 	$response->response_code = wp_remote_retrieve_response_code( $resp );
-	$response->headers = $return_headers;
-	$response->results = wp_remote_retrieve_body( $resp );
+	$response->headers       = $return_headers;
+	$response->results       = wp_remote_retrieve_body( $resp );
 
 	return $response;
 }
@@ -587,21 +571,20 @@ function _fetch_remote_file($url, $headers = "" ) {
  * @param array $resp
  * @return MagpieRSS|bool
  */
-function _response_to_rss ($resp) {
+function _response_to_rss( $resp ) {
 	$rss = new MagpieRSS( $resp->results );
 
 	// if RSS parsed successfully
-	if ( $rss && (!isset($rss->ERROR) || !$rss->ERROR) ) {
+	if ( $rss && ( ! isset( $rss->ERROR ) || ! $rss->ERROR ) ) {
 
 		// find Etag, and Last-Modified
-		foreach ( (array) $resp->headers as $h) {
+		foreach ( (array) $resp->headers as $h ) {
 			// 2003-03-02 - Nicola Asuni (www.tecnick.com) - fixed bug "Undefined offset: 1"
-			if (strpos($h, ": ")) {
-				list($field, $val) = explode(": ", $h, 2);
-			}
-			else {
+			if ( strpos( $h, ': ' ) ) {
+				list($field, $val) = explode( ': ', $h, 2 );
+			} else {
 				$field = $h;
-				$val = "";
+				$val   = '';
 			}
 
 			if ( $field == 'etag' ) {
@@ -616,10 +599,10 @@ function _response_to_rss ($resp) {
 		return $rss;
 	} // else construct error message
 	else {
-		$errormsg = "Failed to parse RSS file.";
+		$errormsg = 'Failed to parse RSS file.';
 
-		if ($rss) {
-			$errormsg .= " (" . $rss->ERROR . ")";
+		if ( $rss ) {
+			$errormsg .= ' (' . $rss->ERROR . ')';
 		}
 		// error($errormsg);
 
@@ -631,91 +614,89 @@ function _response_to_rss ($resp) {
  * Set up constants with default values, unless user overrides.
  *
  * @since 1.5.0
- * 
+ *
  * @global string $wp_version The WordPress version string.
- * 
+ *
  * @package External
  * @subpackage MagpieRSS
  */
-function init () {
-	if ( defined('MAGPIE_INITALIZED') ) {
+function init() {
+	if ( defined( 'MAGPIE_INITALIZED' ) ) {
 		return;
-	}
-	else {
-		define('MAGPIE_INITALIZED', 1);
+	} else {
+		define( 'MAGPIE_INITALIZED', 1 );
 	}
 
-	if ( !defined('MAGPIE_CACHE_ON') ) {
-		define('MAGPIE_CACHE_ON', 1);
+	if ( ! defined( 'MAGPIE_CACHE_ON' ) ) {
+		define( 'MAGPIE_CACHE_ON', 1 );
 	}
 
-	if ( !defined('MAGPIE_CACHE_DIR') ) {
-		define('MAGPIE_CACHE_DIR', './cache');
+	if ( ! defined( 'MAGPIE_CACHE_DIR' ) ) {
+		define( 'MAGPIE_CACHE_DIR', './cache' );
 	}
 
-	if ( !defined('MAGPIE_CACHE_AGE') ) {
-		define('MAGPIE_CACHE_AGE', 60*60); // one hour
+	if ( ! defined( 'MAGPIE_CACHE_AGE' ) ) {
+		define( 'MAGPIE_CACHE_AGE', 60 * 60 ); // one hour
 	}
 
-	if ( !defined('MAGPIE_CACHE_FRESH_ONLY') ) {
-		define('MAGPIE_CACHE_FRESH_ONLY', 0);
+	if ( ! defined( 'MAGPIE_CACHE_FRESH_ONLY' ) ) {
+		define( 'MAGPIE_CACHE_FRESH_ONLY', 0 );
 	}
 
-		if ( !defined('MAGPIE_DEBUG') ) {
-		define('MAGPIE_DEBUG', 0);
+	if ( ! defined( 'MAGPIE_DEBUG' ) ) {
+		define( 'MAGPIE_DEBUG', 0 );
 	}
 
-	if ( !defined('MAGPIE_USER_AGENT') ) {
+	if ( ! defined( 'MAGPIE_USER_AGENT' ) ) {
 		$ua = 'WordPress/' . $GLOBALS['wp_version'];
 
 		if ( MAGPIE_CACHE_ON ) {
 			$ua = $ua . ')';
-		}
-		else {
+		} else {
 			$ua = $ua . '; No cache)';
 		}
 
-		define('MAGPIE_USER_AGENT', $ua);
+		define( 'MAGPIE_USER_AGENT', $ua );
 	}
 
-	if ( !defined('MAGPIE_FETCH_TIME_OUT') ) {
-		define('MAGPIE_FETCH_TIME_OUT', 2);	// 2 second timeout
+	if ( ! defined( 'MAGPIE_FETCH_TIME_OUT' ) ) {
+		define( 'MAGPIE_FETCH_TIME_OUT', 2 ); // 2 second timeout
 	}
 
 	// use gzip encoding to fetch rss files if supported?
-	if ( !defined('MAGPIE_USE_GZIP') ) {
-		define('MAGPIE_USE_GZIP', true);
+	if ( ! defined( 'MAGPIE_USE_GZIP' ) ) {
+		define( 'MAGPIE_USE_GZIP', true );
 	}
 }
 
-function is_info ($sc) {
+function is_info( $sc ) {
 	return $sc >= 100 && $sc < 200;
 }
 
-function is_success ($sc) {
+function is_success( $sc ) {
 	return $sc >= 200 && $sc < 300;
 }
 
-function is_redirect ($sc) {
+function is_redirect( $sc ) {
 	return $sc >= 300 && $sc < 400;
 }
 
-function is_error ($sc) {
+function is_error( $sc ) {
 	return $sc >= 400 && $sc < 600;
 }
 
-function is_client_error ($sc) {
+function is_client_error( $sc ) {
 	return $sc >= 400 && $sc < 500;
 }
 
-function is_server_error ($sc) {
+function is_server_error( $sc ) {
 	return $sc >= 500 && $sc < 600;
 }
 
 class RSSCache {
-	var $BASE_CACHE;	// where the cache files are stored
-	var $MAX_AGE	= 43200;  		// when are files stale, default twelve hours
-	var $ERROR 		= '';			// accumulate error messages
+	var $BASE_CACHE;    // where the cache files are stored
+	var $MAX_AGE = 43200;        // when are files stale, default twelve hours
+	var $ERROR   = '';           // accumulate error messages
 
 	/**
 	 * PHP5 constructor.
@@ -728,7 +709,6 @@ class RSSCache {
 		if ( $age ) {
 			$this->MAX_AGE = $age;
 		}
-
 	}
 
 	/**
@@ -738,28 +718,30 @@ class RSSCache {
 		self::__construct( $base, $age );
 	}
 
-/*=======================================================================*\
-	Function:	set
-	Purpose:	add an item to the cache, keyed on url
-	Input:		url from which the rss file was fetched
-	Output:		true on success
-\*=======================================================================*/
-	function set ($url, $rss) {
+	/*
+	=======================================================================*\
+	Function:   set
+	Purpose:    add an item to the cache, keyed on url
+	Input:      url from which the rss file was fetched
+	Output:     true on success
+	\*=======================================================================*/
+	function set( $url, $rss ) {
 		$cache_option = 'rss_' . $this->file_name( $url );
 
-		set_transient($cache_option, $rss, $this->MAX_AGE);
+		set_transient( $cache_option, $rss, $this->MAX_AGE );
 
 		return $cache_option;
 	}
 
-/*=======================================================================*\
-	Function:	get
-	Purpose:	fetch an item from the cache
-	Input:		url from which the rss file was fetched
-	Output:		cached object on HIT, false on MISS
-\*=======================================================================*/
-	function get ($url) {
-		$this->ERROR = "";
+	/*
+	=======================================================================*\
+	Function:   get
+	Purpose:    fetch an item from the cache
+	Input:      url from which the rss file was fetched
+	Output:     cached object on HIT, false on MISS
+	\*=======================================================================*/
+	function get( $url ) {
+		$this->ERROR  = '';
 		$cache_option = 'rss_' . $this->file_name( $url );
 
 		if ( ! $rss = get_transient( $cache_option ) ) {
@@ -772,18 +754,19 @@ class RSSCache {
 		return $rss;
 	}
 
-/*=======================================================================*\
-	Function:	check_cache
-	Purpose:	check a url for membership in the cache
+	/*
+	=======================================================================*\
+	Function:   check_cache
+	Purpose:    check a url for membership in the cache
 				and whether the object is older then MAX_AGE (ie. STALE)
-	Input:		url from which the rss file was fetched
-	Output:		cached object on HIT, false on MISS
-\*=======================================================================*/
-	function check_cache ( $url ) {
-		$this->ERROR = "";
+	Input:      url from which the rss file was fetched
+	Output:     cached object on HIT, false on MISS
+	\*=======================================================================*/
+	function check_cache( $url ) {
+		$this->ERROR  = '';
 		$cache_option = 'rss_' . $this->file_name( $url );
 
-		if ( get_transient($cache_option) ) {
+		if ( get_transient( $cache_option ) ) {
 			// object exists and is current
 				return 'HIT';
 		} else {
@@ -792,159 +775,163 @@ class RSSCache {
 		}
 	}
 
-/*=======================================================================*\
-	Function:	serialize
-\*=======================================================================*/
-	function serialize ( $rss ) {
+	/*
+	=======================================================================*\
+	Function:   serialize
+	\*=======================================================================*/
+	function serialize( $rss ) {
 		return serialize( $rss );
 	}
 
-/*=======================================================================*\
-	Function:	unserialize
-\*=======================================================================*/
-	function unserialize ( $data ) {
+	/*
+	=======================================================================*\
+	Function:   unserialize
+	\*=======================================================================*/
+	function unserialize( $data ) {
 		return unserialize( $data );
 	}
 
-/*=======================================================================*\
-	Function:	file_name
-	Purpose:	map url to location in cache
-	Input:		url from which the rss file was fetched
-	Output:		a file name
-\*=======================================================================*/
-	function file_name ($url) {
+	/*
+	=======================================================================*\
+	Function:   file_name
+	Purpose:    map url to location in cache
+	Input:      url from which the rss file was fetched
+	Output:     a file name
+	\*=======================================================================*/
+	function file_name( $url ) {
 		return md5( $url );
 	}
 
-/*=======================================================================*\
-	Function:	error
-	Purpose:	register error
-\*=======================================================================*/
-	function error ($errormsg, $lvl=E_USER_WARNING) {
+	/*
+	=======================================================================*\
+	Function:   error
+	Purpose:    register error
+	\*=======================================================================*/
+	function error( $errormsg, $lvl = E_USER_WARNING ) {
 		$this->ERROR = $errormsg;
 		if ( MAGPIE_DEBUG ) {
-			wp_trigger_error( '', $errormsg, $lvl);
-		}
-		else {
-			error_log( $errormsg, 0);
+			wp_trigger_error( '', $errormsg, $lvl );
+		} else {
+			error_log( $errormsg, 0 );
 		}
 	}
-			function debug ($debugmsg, $lvl=E_USER_NOTICE) {
+	function debug( $debugmsg, $lvl = E_USER_NOTICE ) {
 		if ( MAGPIE_DEBUG ) {
-			$this->error("MagpieRSS [debug] $debugmsg", $lvl);
+			$this->error( "MagpieRSS [debug] $debugmsg", $lvl );
 		}
 	}
 }
 
-if ( !function_exists('parse_w3cdtf') ) :
-function parse_w3cdtf ( $date_str ) {
+if ( ! function_exists( 'parse_w3cdtf' ) ) :
+	function parse_w3cdtf( $date_str ) {
 
-	# regex to match W3C date/time formats
-	$pat = "/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(:(\d{2}))?(?:([-+])(\d{2}):?(\d{2})|(Z))?/";
+		// regex to match W3C date/time formats
+		$pat = '/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(:(\d{2}))?(?:([-+])(\d{2}):?(\d{2})|(Z))?/';
 
-	if ( preg_match( $pat, $date_str, $match ) ) {
-		list( $year, $month, $day, $hours, $minutes, $seconds) =
-			array( $match[1], $match[2], $match[3], $match[4], $match[5], $match[7]);
+		if ( preg_match( $pat, $date_str, $match ) ) {
+			list( $year, $month, $day, $hours, $minutes, $seconds) =
+			array( $match[1], $match[2], $match[3], $match[4], $match[5], $match[7] );
 
-		# calc epoch for current date assuming GMT
-		$epoch = gmmktime( $hours, $minutes, $seconds, $month, $day, $year);
+			// calc epoch for current date assuming GMT
+			$epoch = gmmktime( $hours, $minutes, $seconds, $month, $day, $year );
 
-		$offset = 0;
-		if ( $match[11] == 'Z' ) {
-			# zulu time, aka GMT
-		}
-		else {
-			list( $tz_mod, $tz_hour, $tz_min ) =
-				array( $match[8], $match[9], $match[10]);
+			$offset = 0;
+			if ( $match[11] == 'Z' ) {
+				// zulu time, aka GMT
+			} else {
+				list( $tz_mod, $tz_hour, $tz_min ) =
+				array( $match[8], $match[9], $match[10] );
 
-			# zero out the variables
-			if ( ! $tz_hour ) { $tz_hour = 0; }
-			if ( ! $tz_min ) { $tz_min = 0; }
+				// zero out the variables
+				if ( ! $tz_hour ) {
+					$tz_hour = 0; }
+				if ( ! $tz_min ) {
+					$tz_min = 0; }
 
-			$offset_secs = (($tz_hour*60)+$tz_min)*60;
+				$offset_secs = ( ( $tz_hour * 60 ) + $tz_min ) * 60;
 
-			# is timezone ahead of GMT?  then subtract offset
-			#
-			if ( $tz_mod == '+' ) {
-				$offset_secs = $offset_secs * -1;
-			}
+				// is timezone ahead of GMT?  then subtract offset
+				//
+				if ( $tz_mod == '+' ) {
+					$offset_secs = $offset_secs * -1;
+				}
 
-			$offset = $offset_secs;
+				$offset = $offset_secs;
+			}
+			$epoch = $epoch + $offset;
+			return $epoch;
+		} else {
+			return -1;
 		}
-		$epoch = $epoch + $offset;
-		return $epoch;
-	}
-	else {
-		return -1;
 	}
-}
 endif;
 
-if ( !function_exists('wp_rss') ) :
-/**
- * Display all RSS items in a HTML ordered list.
- *
- * @since 1.5.0
- * @package External
- * @subpackage MagpieRSS
- *
- * @param string $url URL of feed to display. Will not auto sense feed URL.
- * @param int $num_items Optional. Number of items to display, default is all.
- */
-function wp_rss( $url, $num_items = -1 ) {
-	if ( $rss = fetch_rss( $url ) ) {
-		echo '<ul>';
+if ( ! function_exists( 'wp_rss' ) ) :
+	/**
+	 * Display all RSS items in a HTML ordered list.
+	 *
+	 * @since 1.5.0
+	 * @package External
+	 * @subpackage MagpieRSS
+	 *
+	 * @param string $url URL of feed to display. Will not auto sense feed URL.
+	 * @param int    $num_items Optional. Number of items to display, default is all.
+	 */
+	function wp_rss( $url, $num_items = -1 ) {
+		if ( $rss = fetch_rss( $url ) ) {
+			echo '<ul>';
 
-		if ( $num_items !== -1 ) {
-			$rss->items = array_slice( $rss->items, 0, $num_items );
-		}
+			if ( $num_items !== -1 ) {
+				$rss->items = array_slice( $rss->items, 0, $num_items );
+			}
 
-		foreach ( (array) $rss->items as $item ) {
-			printf(
-				'<li><a href="%1$s" title="%2$s">%3$s</a></li>',
-				esc_url( $item['link'] ),
-				esc_attr( strip_tags( $item['description'] ) ),
-				esc_html( $item['title'] )
-			);
-		}
+			foreach ( (array) $rss->items as $item ) {
+				printf(
+					'<li><a href="%1$s" title="%2$s">%3$s</a></li>',
+					esc_url( $item['link'] ),
+					esc_attr( wp_strip_all_tags( $item['description'] ) ),
+					esc_html( $item['title'] )
+				);
+			}
 
-		echo '</ul>';
-	} else {
-		_e( 'An error has occurred, which probably means the feed is down. Try again later.' );
+			echo '</ul>';
+		} else {
+			_e( 'An error has occurred, which probably means the feed is down. Try again later.' );
+		}
 	}
-}
 endif;
 
-if ( !function_exists('get_rss') ) :
-/**
- * Display RSS items in HTML list items.
- *
- * You have to specify which HTML list you want, either ordered or unordered
- * before using the function. You also have to specify how many items you wish
- * to display. You can't display all of them like you can with wp_rss()
- * function.
- *
- * @since 1.5.0
- * @package External
- * @subpackage MagpieRSS
- *
- * @param string $url URL of feed to display. Will not auto sense feed URL.
- * @param int $num_items Optional. Number of items to display, default is all.
- * @return bool False on failure.
- */
-function get_rss ($url, $num_items = 5) { // Like get posts, but for RSS
-	$rss = fetch_rss($url);
-	if ( $rss ) {
-		$rss->items = array_slice($rss->items, 0, $num_items);
-		foreach ( (array) $rss->items as $item ) {
-			echo "<li>\n";
-			echo "<a href='$item[link]' title='$item[description]'>";
-			echo esc_html($item['title']);
-			echo "</a><br />\n";
-			echo "</li>\n";
+if ( ! function_exists( 'get_rss' ) ) :
+	/**
+	 * Display RSS items in HTML list items.
+	 *
+	 * You have to specify which HTML list you want, either ordered or unordered
+	 * before using the function. You also have to specify how many items you wish
+	 * to display. You can't display all of them like you can with wp_rss()
+	 * function.
+	 *
+	 * @since 1.5.0
+	 * @package External
+	 * @subpackage MagpieRSS
+	 *
+	 * @param string $url URL of feed to display. Will not auto sense feed URL.
+	 * @param int    $num_items Optional. Number of items to display, default is all.
+	 * @return bool False on failure.
+	 */
+	function get_rss( $url, $num_items = 5 ) {
+		// Like get posts, but for RSS
+		$rss = fetch_rss( $url );
+		if ( $rss ) {
+			$rss->items = array_slice( $rss->items, 0, $num_items );
+			foreach ( (array) $rss->items as $item ) {
+				echo "<li>\n";
+				echo "<a href='$item[link]' title='$item[description]'>";
+				echo esc_html( $item['title'] );
+				echo "</a><br />\n";
+				echo "</li>\n";
+			}
+		} else {
+			return false;
 		}
-	} else {
-		return false;
 	}
-}
 endif;
diff --git a/src/wp-includes/theme.php b/src/wp-includes/theme.php
index 1a9b2479ad..717da65cce 100644
--- a/src/wp-includes/theme.php
+++ b/src/wp-includes/theme.php
@@ -1395,10 +1395,8 @@ function _get_random_header_data() {
 		} elseif ( ! empty( $_wp_default_headers ) ) {
 			if ( 'random-default-image' === $header_image_mod ) {
 				$headers = $_wp_default_headers;
-			} else {
-				if ( current_theme_supports( 'custom-header', 'random-default' ) ) {
+			} elseif ( current_theme_supports( 'custom-header', 'random-default' ) ) {
 					$headers = $_wp_default_headers;
-				}
 			}
 		}
 
@@ -1464,14 +1462,12 @@ function is_random_header_image( $type = 'any' ) {
 		) {
 			return true;
 		}
-	} else {
-		if ( "random-$type-image" === $header_image_mod ) {
+	} elseif ( "random-$type-image" === $header_image_mod ) {
 			return true;
-		} elseif ( 'default' === $type
+	} elseif ( 'default' === $type
 			&& empty( $header_image_mod ) && '' !== get_random_header_image()
 		) {
-			return true;
-		}
+		return true;
 	}
 
 	return false;
@@ -1961,7 +1957,7 @@ function wp_custom_css_cb() {
 		<style<?php echo $type_attr; ?> id="wp-custom-css">
 			<?php
 			// Note that esc_html() cannot be used because `div &gt; span` is not interpreted properly.
-			echo strip_tags( $styles );
+			echo wp_strip_all_tags( $styles );
 			?>
 		</style>
 		<?php
diff --git a/src/wp-includes/widgets.php b/src/wp-includes/widgets.php
index 32d8a95e1b..1edf5b3fe2 100644
--- a/src/wp-includes/widgets.php
+++ b/src/wp-includes/widgets.php
@@ -634,7 +634,6 @@ function _register_widget_update_callback( $id_base, $update_callback, $options
  *                                  Default empty array.
  * @param mixed      ...$params     Optional additional parameters to pass to the callback function when it's called.
  */
-
 function _register_widget_form_callback( $id, $name, $form_callback, $options = array(), ...$params ) {
 	global $wp_registered_widget_controls;
 
@@ -1665,9 +1664,9 @@ function wp_widget_rss_output( $rss, $args = array() ) {
 			if ( is_object( $author ) ) {
 				$author = $author->get_name();
 				$author = ' <cite>' . esc_html( strip_tags( $author ) ) . '</cite>';
-			}
+			}wp_strip_all_tags
 		}
-
+		wp_strip_all_tags
 		if ( '' === $link ) {
 			echo "<li>$title{$date}{$summary}{$author}</li>";
 		} elseif ( $show_summary ) {
@@ -1795,8 +1794,9 @@ function wp_widget_rss_process( $widget_rss, $check_feed = true ) {
 		$rss = fetch_feed( $url );
 
 		if ( is_wp_error( $rss ) ) {
-			$error = $rss->get_error_message();
+			$error = $rss->get_error_meswp_strip_all_tags
 		} else {
+			wp_strip_all_tags
 			$link = esc_url( strip_tags( $rss->get_permalink() ) );
 			while ( stristr( $link, 'http' ) !== $link ) {
 				$link = substr( $link, 1 );
@@ -1809,7 +1809,7 @@ function wp_widget_rss_process( $widget_rss, $check_feed = true ) {
 
 	return compact( 'title', 'url', 'link', 'items', 'error', 'show_summary', 'show_author', 'show_date' );
 }
-
+wp_strip_all_tags
 /**
  * Registers all of the default WordPress widgets on startup.
  *
diff --git a/src/wp-includes/widgets/class-wp-nav-menu-widget.php b/src/wp-includes/widgets/class-wp-nav-menu-widget.php
index 731e5bd7dd..4135bb8178 100644
--- a/src/wp-includes/widgets/class-wp-nav-menu-widget.php
+++ b/src/wp-includes/widgets/class-wp-nav-menu-widget.php
@@ -73,7 +73,7 @@ class WP_Nav_Menu_Widget extends WP_Widget {
 
 		if ( 'html5' === $format ) {
 			// The title may be filtered: Strip out HTML and make sure the aria-label is never empty.
-			$title      = trim( strip_tags( $title ) );
+			$title      = trim( wp_strip_all_tags( $title ) );
 			$aria_label = $title ? $title : $default_title;
 
 			$nav_menu_args = array(
diff --git a/src/wp-includes/widgets/class-wp-widget-archives.php b/src/wp-includes/widgets/class-wp-widget-archives.php
index 7457244833..b4327c5fa0 100644
--- a/src/wp-includes/widgets/class-wp-widget-archives.php
+++ b/src/wp-includes/widgets/class-wp-widget-archives.php
@@ -129,7 +129,7 @@ class WP_Widget_Archives extends WP_Widget {
 
 			if ( 'html5' === $format ) {
 				// The title may be filtered: Strip out HTML and make sure the aria-label is never empty.
-				$title      = trim( strip_tags( $title ) );
+				$title      = trim( wp_strip_all_tags( $title ) );
 				$aria_label = $title ? $title : $default_title;
 				echo '<nav aria-label="' . esc_attr( $aria_label ) . '">';
 			}
diff --git a/src/wp-includes/widgets/class-wp-widget-categories.php b/src/wp-includes/widgets/class-wp-widget-categories.php
index b79881e752..266911d2ac 100644
--- a/src/wp-includes/widgets/class-wp-widget-categories.php
+++ b/src/wp-includes/widgets/class-wp-widget-categories.php
@@ -117,7 +117,7 @@ class WP_Widget_Categories extends WP_Widget {
 
 			if ( 'html5' === $format ) {
 				// The title may be filtered: Strip out HTML and make sure the aria-label is never empty.
-				$title      = trim( strip_tags( $title ) );
+				$title      = trim( wp_strip_all_tags( $title ) );
 				$aria_label = $title ? $title : $default_title;
 				echo '<nav aria-label="' . esc_attr( $aria_label ) . '">';
 			}
diff --git a/src/wp-includes/widgets/class-wp-widget-meta.php b/src/wp-includes/widgets/class-wp-widget-meta.php
index 2ab2857dcd..c935cba3a8 100644
--- a/src/wp-includes/widgets/class-wp-widget-meta.php
+++ b/src/wp-includes/widgets/class-wp-widget-meta.php
@@ -62,7 +62,7 @@ class WP_Widget_Meta extends WP_Widget {
 
 		if ( 'html5' === $format ) {
 			// The title may be filtered: Strip out HTML and make sure the aria-label is never empty.
-			$title      = trim( strip_tags( $title ) );
+			$title      = trim( wp_strip_all_tags( $title ) );
 			$aria_label = $title ? $title : $default_title;
 			echo '<nav aria-label="' . esc_attr( $aria_label ) . '">';
 		}
diff --git a/src/wp-includes/widgets/class-wp-widget-pages.php b/src/wp-includes/widgets/class-wp-widget-pages.php
index 36da121e5c..d4522d5d37 100644
--- a/src/wp-includes/widgets/class-wp-widget-pages.php
+++ b/src/wp-includes/widgets/class-wp-widget-pages.php
@@ -99,7 +99,7 @@ class WP_Widget_Pages extends WP_Widget {
 
 			if ( 'html5' === $format ) {
 				// The title may be filtered: Strip out HTML and make sure the aria-label is never empty.
-				$title      = trim( strip_tags( $title ) );
+				$title      = trim( wp_strip_all_tags( $title ) );
 				$aria_label = $title ? $title : $default_title;
 				echo '<nav aria-label="' . esc_attr( $aria_label ) . '">';
 			}
diff --git a/src/wp-includes/widgets/class-wp-widget-recent-comments.php b/src/wp-includes/widgets/class-wp-widget-recent-comments.php
index 5d92938283..1e0ba5d6b2 100644
--- a/src/wp-includes/widgets/class-wp-widget-recent-comments.php
+++ b/src/wp-includes/widgets/class-wp-widget-recent-comments.php
@@ -132,7 +132,7 @@ class WP_Widget_Recent_Comments extends WP_Widget {
 
 		if ( 'html5' === $format ) {
 			// The title may be filtered: Strip out HTML and make sure the aria-label is never empty.
-			$title      = trim( strip_tags( $title ) );
+			$title      = trim( wp_strip_all_tags( $title ) );
 			$aria_label = $title ? $title : $default_title;
 			$output    .= '<nav aria-label="' . esc_attr( $aria_label ) . '">';
 		}
diff --git a/src/wp-includes/widgets/class-wp-widget-recent-posts.php b/src/wp-includes/widgets/class-wp-widget-recent-posts.php
index c73bb5b0bc..b65f48b9cc 100644
--- a/src/wp-includes/widgets/class-wp-widget-recent-posts.php
+++ b/src/wp-includes/widgets/class-wp-widget-recent-posts.php
@@ -101,7 +101,7 @@ class WP_Widget_Recent_Posts extends WP_Widget {
 
 		if ( 'html5' === $format ) {
 			// The title may be filtered: Strip out HTML and make sure the aria-label is never empty.
-			$title      = trim( strip_tags( $title ) );
+			$title      = trim( wp_strip_all_tags( $title ) );
 			$aria_label = $title ? $title : $default_title;
 			echo '<nav aria-label="' . esc_attr( $aria_label ) . '">';
 		}
diff --git a/src/wp-includes/widgets/class-wp-widget-rss.php b/src/wp-includes/widgets/class-wp-widget-rss.php
index a4a1b198b9..b21f568f8c 100644
--- a/src/wp-includes/widgets/class-wp-widget-rss.php
+++ b/src/wp-includes/widgets/class-wp-widget-rss.php
@@ -69,11 +69,11 @@ class WP_Widget_RSS extends WP_Widget {
 		$link  = '';
 
 		if ( ! is_wp_error( $rss ) ) {
-			$desc = esc_attr( strip_tags( html_entity_decode( $rss->get_description(), ENT_QUOTES, get_option( 'blog_charset' ) ) ) );
+			$desc = esc_attr( wp_strip_all_tags( html_entity_decode( $rss->get_description(), ENT_QUOTES, get_option( 'blog_charset' ) ) ) );
 			if ( empty( $title ) ) {
-				$title = strip_tags( $rss->get_title() );
+				$title = wp_strip_all_tags( $rss->get_title() );
 			}
-			$link = strip_tags( $rss->get_permalink() );
+			$link = wp_strip_all_tags( $rss->get_permalink() );
 			while ( ! empty( $link ) && stristr( $link, 'http' ) !== $link ) {
 				$link = substr( $link, 1 );
 			}
@@ -88,7 +88,7 @@ class WP_Widget_RSS extends WP_Widget {
 
 		if ( $title ) {
 			$feed_link = '';
-			$feed_url  = strip_tags( $url );
+			$feed_url  = wp_strip_all_tags( $url );
 			$feed_icon = includes_url( 'images/rss.png' );
 			$feed_link = sprintf(
 				'<a class="rsswidget rss-widget-feed" href="%1$s"><img class="rss-widget-icon" style="border:0" width="14" height="14" src="%2$s" alt="%3$s"%4$s /></a> ',
@@ -125,7 +125,7 @@ class WP_Widget_RSS extends WP_Widget {
 
 		if ( 'html5' === $format ) {
 			// The title may be filtered: Strip out HTML and make sure the aria-label is never empty.
-			$title      = trim( strip_tags( $title ) );
+			$title      = trim( wp_strip_all_tags( $title ) );
 			$aria_label = $title ? $title : __( 'RSS Feed' );
 			echo '<nav aria-label="' . esc_attr( $aria_label ) . '">';
 		}
diff --git a/src/wp-includes/widgets/class-wp-widget-tag-cloud.php b/src/wp-includes/widgets/class-wp-widget-tag-cloud.php
index c56a774b11..d63af9c5c6 100644
--- a/src/wp-includes/widgets/class-wp-widget-tag-cloud.php
+++ b/src/wp-includes/widgets/class-wp-widget-tag-cloud.php
@@ -44,13 +44,11 @@ class WP_Widget_Tag_Cloud extends WP_Widget {
 
 		if ( ! empty( $instance['title'] ) ) {
 			$title = $instance['title'];
-		} else {
-			if ( 'post_tag' === $current_taxonomy ) {
+		} elseif ( 'post_tag' === $current_taxonomy ) {
 				$title = __( 'Tags' );
-			} else {
-				$tax   = get_taxonomy( $current_taxonomy );
-				$title = $tax->labels->name;
-			}
+		} else {
+			$tax   = get_taxonomy( $current_taxonomy );
+			$title = $tax->labels->name;
 		}
 
 		$default_title = $title;
@@ -100,7 +98,7 @@ class WP_Widget_Tag_Cloud extends WP_Widget {
 
 		if ( 'html5' === $format ) {
 			// The title may be filtered: Strip out HTML and make sure the aria-label is never empty.
-			$title      = trim( strip_tags( $title ) );
+			$title      = trim( wp_strip_all_tags( $title ) );
 			$aria_label = $title ? $title : $default_title;
 			echo '<nav aria-label="' . esc_attr( $aria_label ) . '">';
 		}
