wp_mail

The timeline below displays how wordpress function wp_mail has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 6.3

/**
 * Sends an email, similar to PHP's mail function.
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * The default content type is `text/plain` which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 * @since 5.5.0 is_email() is used for email validation,
 *              instead of PHPMailer's default validator.
 *
 * @global PHPMailer\PHPMailer\PHPMailer $phpmailer
 *
 * @param string|string[] $to          Array or comma-separated list of email addresses to send message.
 * @param string          $subject     Email subject.
 * @param string          $message     Message contents.
 * @param string|string[] $headers     Optional. Additional headers.
 * @param string|string[] $attachments Optional. Paths to files to attach.
 * @return bool Whether the email was sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out.
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args {
     *     Array of the `wp_mail()` arguments.
     *
     *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
     *     @type string          $subject     Email subject.
     *     @type string          $message     Message contents.
     *     @type string|string[] $headers     Additional headers.
     *     @type string|string[] $attachments Paths to files to attach.
     * }
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    /**
     * Filters whether to preempt sending an email.
     *
     * Returning a non-null value will short-circuit {@see wp_mail()}, returning
     * that value instead. A boolean return value should be used to indicate whether
     * the email was successfully sent.
     *
     * @since 5.7.0
     *
     * @param null|bool $return Short-circuit return value.
     * @param array     $atts {
     *     Array of the `wp_mail()` arguments.
     *
     *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
     *     @type string          $subject     Email subject.
     *     @type string          $message     Message contents.
     *     @type string|string[] $headers     Additional headers.
     *     @type string|string[] $attachments Paths to files to attach.
     * }
     */
    $pre_wp_mail = apply_filters('pre_wp_mail', null, $atts);
    if (null !== $pre_wp_mail) {
        return $pre_wp_mail;
    }
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing.
    if (!$phpmailer instanceof PHPMailer\PHPMailer\PHPMailer) {
        require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
        require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
        require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
        $phpmailer = new PHPMailer\PHPMailer\PHPMailer(true);
        $phpmailer::$validator = static function ($email) {
            return (bool) is_email($email);
        };
    }
    // Headers.
    $cc = array();
    $bcc = array();
    $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            /*
             * Explode the headers out, so this function can take
             * both string headers and an array of headers.
             */
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents.
        if (!empty($tempheaders)) {
            // Iterate through the raw headers.
            foreach ((array) $tempheaders as $header) {
                if (!str_contains($header, ':')) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out.
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew.
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a "From:" header if it's there.
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if (false !== $bracket_pos) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (str_contains($content, ';')) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array.
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set.
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // Set "From" name and email.
    // If we don't have a name from the input headers.
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /*
     * If we don't have an email from the input headers, default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist,
     * but there's no easy alternative. Defaulting to admin_email might appear to be
     * another option, but some hosts may refuse to relay mail from an unknown domain.
     * See https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = wp_parse_url(network_home_url(), PHP_URL_HOST);
        $from_email = 'wordpress@';
        if (null !== $sitename) {
            if (str_starts_with($sitename, 'www.')) {
                $sitename = substr($sitename, 4);
            }
            $from_email .= $sitename;
        }
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body.
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses.
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>".
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) === 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail().
    $phpmailer->isMail();
    // Set Content-Type and charset.
    // If we don't have a Content-Type from the input headers.
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type.
    if ('text/html' === $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers.
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers.
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            // Only add custom headers not added automatically by PHPMailer.
            if (!in_array($name, array('MIME-Version', 'X-Mailer'), true)) {
                try {
                    $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
                } catch (PHPMailer\PHPMailer\Exception $e) {
                    continue;
                }
            }
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf('Content-Type: %s; boundary="%s"', $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $filename => $attachment) {
            $filename = is_string($filename) ? $filename : '';
            try {
                $phpmailer->addAttachment($attachment, $filename);
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    $mail_data = compact('to', 'subject', 'message', 'headers', 'attachments');
    // Send!
    try {
        $send = $phpmailer->send();
        /**
         * Fires after PHPMailer has successfully sent an email.
         *
         * The firing of this action does not necessarily mean that the recipient(s) received the
         * email successfully. It only means that the `send` method above was able to
         * process the request without any errors.
         *
         * @since 5.9.0
         *
         * @param array $mail_data {
         *     An array containing the email recipient(s), subject, message, headers, and attachments.
         *
         *     @type string[] $to          Email addresses to send message.
         *     @type string   $subject     Email subject.
         *     @type string   $message     Message contents.
         *     @type string[] $headers     Additional headers.
         *     @type string[] $attachments Paths to files to attach.
         * }
         */
        do_action('wp_mail_succeeded', $mail_data);
        return $send;
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a PHPMailer\PHPMailer\Exception is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the PHPMailer\PHPMailer\Exception message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_data));
        return false;
    }
}

WordPress Version: 6.2

/**
 * Sends an email, similar to PHP's mail function.
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * The default content type is `text/plain` which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 * @since 5.5.0 is_email() is used for email validation,
 *              instead of PHPMailer's default validator.
 *
 * @global PHPMailer\PHPMailer\PHPMailer $phpmailer
 *
 * @param string|string[] $to          Array or comma-separated list of email addresses to send message.
 * @param string          $subject     Email subject.
 * @param string          $message     Message contents.
 * @param string|string[] $headers     Optional. Additional headers.
 * @param string|string[] $attachments Optional. Paths to files to attach.
 * @return bool Whether the email was sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out.
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args {
     *     Array of the `wp_mail()` arguments.
     *
     *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
     *     @type string          $subject     Email subject.
     *     @type string          $message     Message contents.
     *     @type string|string[] $headers     Additional headers.
     *     @type string|string[] $attachments Paths to files to attach.
     * }
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    /**
     * Filters whether to preempt sending an email.
     *
     * Returning a non-null value will short-circuit {@see wp_mail()}, returning
     * that value instead. A boolean return value should be used to indicate whether
     * the email was successfully sent.
     *
     * @since 5.7.0
     *
     * @param null|bool $return Short-circuit return value.
     * @param array     $atts {
     *     Array of the `wp_mail()` arguments.
     *
     *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
     *     @type string          $subject     Email subject.
     *     @type string          $message     Message contents.
     *     @type string|string[] $headers     Additional headers.
     *     @type string|string[] $attachments Paths to files to attach.
     * }
     */
    $pre_wp_mail = apply_filters('pre_wp_mail', null, $atts);
    if (null !== $pre_wp_mail) {
        return $pre_wp_mail;
    }
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing.
    if (!$phpmailer instanceof PHPMailer\PHPMailer\PHPMailer) {
        require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
        require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
        require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
        $phpmailer = new PHPMailer\PHPMailer\PHPMailer(true);
        $phpmailer::$validator = static function ($email) {
            return (bool) is_email($email);
        };
    }
    // Headers.
    $cc = array();
    $bcc = array();
    $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take
            // both string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents.
        if (!empty($tempheaders)) {
            // Iterate through the raw headers.
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out.
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew.
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a "From:" header if it's there.
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if (false !== $bracket_pos) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array.
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set.
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // Set "From" name and email.
    // If we don't have a name from the input headers.
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /*
     * If we don't have an email from the input headers, default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist,
     * but there's no easy alternative. Defaulting to admin_email might appear to be
     * another option, but some hosts may refuse to relay mail from an unknown domain.
     * See https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = wp_parse_url(network_home_url(), PHP_URL_HOST);
        $from_email = 'wordpress@';
        if (null !== $sitename) {
            if ('www.' === substr($sitename, 0, 4)) {
                $sitename = substr($sitename, 4);
            }
            $from_email .= $sitename;
        }
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body.
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses.
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>".
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail().
    $phpmailer->isMail();
    // Set Content-Type and charset.
    // If we don't have a Content-Type from the input headers.
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type.
    if ('text/html' === $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers.
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers.
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            // Only add custom headers not added automatically by PHPMailer.
            if (!in_array($name, array('MIME-Version', 'X-Mailer'), true)) {
                try {
                    $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
                } catch (PHPMailer\PHPMailer\Exception $e) {
                    continue;
                }
            }
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf('Content-Type: %s; boundary="%s"', $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $filename => $attachment) {
            $filename = is_string($filename) ? $filename : '';
            try {
                $phpmailer->addAttachment($attachment, $filename);
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    $mail_data = compact('to', 'subject', 'message', 'headers', 'attachments');
    // Send!
    try {
        $send = $phpmailer->send();
        /**
         * Fires after PHPMailer has successfully sent an email.
         *
         * The firing of this action does not necessarily mean that the recipient(s) received the
         * email successfully. It only means that the `send` method above was able to
         * process the request without any errors.
         *
         * @since 5.9.0
         *
         * @param array $mail_data {
         *     An array containing the email recipient(s), subject, message, headers, and attachments.
         *
         *     @type string[] $to          Email addresses to send message.
         *     @type string   $subject     Email subject.
         *     @type string   $message     Message contents.
         *     @type string[] $headers     Additional headers.
         *     @type string[] $attachments Paths to files to attach.
         * }
         */
        do_action('wp_mail_succeeded', $mail_data);
        return $send;
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a PHPMailer\PHPMailer\Exception is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the PHPMailer\PHPMailer\Exception message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_data));
        return false;
    }
}

WordPress Version: 6.1

/**
 * Sends an email, similar to PHP's mail function.
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * The default content type is `text/plain` which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 * @since 5.5.0 is_email() is used for email validation,
 *              instead of PHPMailer's default validator.
 *
 * @global PHPMailer\PHPMailer\PHPMailer $phpmailer
 *
 * @param string|string[] $to          Array or comma-separated list of email addresses to send message.
 * @param string          $subject     Email subject.
 * @param string          $message     Message contents.
 * @param string|string[] $headers     Optional. Additional headers.
 * @param string|string[] $attachments Optional. Paths to files to attach.
 * @return bool Whether the email was sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out.
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args {
     *     Array of the `wp_mail()` arguments.
     *
     *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
     *     @type string          $subject     Email subject.
     *     @type string          $message     Message contents.
     *     @type string|string[] $headers     Additional headers.
     *     @type string|string[] $attachments Paths to files to attach.
     * }
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    /**
     * Filters whether to preempt sending an email.
     *
     * Returning a non-null value will short-circuit {@see wp_mail()}, returning
     * that value instead. A boolean return value should be used to indicate whether
     * the email was successfully sent.
     *
     * @since 5.7.0
     *
     * @param null|bool $return Short-circuit return value.
     * @param array     $atts {
     *     Array of the `wp_mail()` arguments.
     *
     *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
     *     @type string          $subject     Email subject.
     *     @type string          $message     Message contents.
     *     @type string|string[] $headers     Additional headers.
     *     @type string|string[] $attachments Paths to files to attach.
     * }
     */
    $pre_wp_mail = apply_filters('pre_wp_mail', null, $atts);
    if (null !== $pre_wp_mail) {
        return $pre_wp_mail;
    }
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing.
    if (!$phpmailer instanceof PHPMailer\PHPMailer\PHPMailer) {
        require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
        require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
        require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
        $phpmailer = new PHPMailer\PHPMailer\PHPMailer(true);
        $phpmailer::$validator = static function ($email) {
            return (bool) is_email($email);
        };
    }
    // Headers.
    $cc = array();
    $bcc = array();
    $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take
            // both string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents.
        if (!empty($tempheaders)) {
            // Iterate through the raw headers.
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out.
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew.
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a "From:" header if it's there.
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if (false !== $bracket_pos) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array.
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set.
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // Set "From" name and email.
    // If we don't have a name from the input headers.
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /*
     * If we don't have an email from the input headers, default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist,
     * but there's no easy alternative. Defaulting to admin_email might appear to be
     * another option, but some hosts may refuse to relay mail from an unknown domain.
     * See https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = wp_parse_url(network_home_url(), PHP_URL_HOST);
        $from_email = 'wordpress@';
        if (null !== $sitename) {
            if ('www.' === substr($sitename, 0, 4)) {
                $sitename = substr($sitename, 4);
            }
            $from_email .= $sitename;
        }
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body.
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses.
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>".
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail().
    $phpmailer->isMail();
    // Set Content-Type and charset.
    // If we don't have a content-type from the input headers.
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type.
    if ('text/html' === $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers.
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers.
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            // Only add custom headers not added automatically by PHPMailer.
            if (!in_array($name, array('MIME-Version', 'X-Mailer'), true)) {
                try {
                    $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
                } catch (PHPMailer\PHPMailer\Exception $e) {
                    continue;
                }
            }
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf('Content-Type: %s; boundary="%s"', $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    $mail_data = compact('to', 'subject', 'message', 'headers', 'attachments');
    // Send!
    try {
        $send = $phpmailer->send();
        /**
         * Fires after PHPMailer has successfully sent an email.
         *
         * The firing of this action does not necessarily mean that the recipient(s) received the
         * email successfully. It only means that the `send` method above was able to
         * process the request without any errors.
         *
         * @since 5.9.0
         *
         * @param array $mail_data {
         *     An array containing the email recipient(s), subject, message, headers, and attachments.
         *
         *     @type string[] $to          Email addresses to send message.
         *     @type string   $subject     Email subject.
         *     @type string   $message     Message contents.
         *     @type string[] $headers     Additional headers.
         *     @type string[] $attachments Paths to files to attach.
         * }
         */
        do_action('wp_mail_succeeded', $mail_data);
        return $send;
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a PHPMailer\PHPMailer\Exception is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the PHPMailer\PHPMailer\Exception message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_data));
        return false;
    }
}

WordPress Version: 9.5

/**
 * Sends an email, similar to PHP's mail function.
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * The default content type is `text/plain` which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 * @since 5.5.0 is_email() is used for email validation,
 *              instead of PHPMailer's default validator.
 *
 * @global PHPMailer\PHPMailer\PHPMailer $phpmailer
 *
 * @param string|string[] $to          Array or comma-separated list of email addresses to send message.
 * @param string          $subject     Email subject.
 * @param string          $message     Message contents.
 * @param string|string[] $headers     Optional. Additional headers.
 * @param string|string[] $attachments Optional. Paths to files to attach.
 * @return bool Whether the email was sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out.
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args {
     *     Array of the `wp_mail()` arguments.
     *
     *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
     *     @type string          $subject     Email subject.
     *     @type string          $message     Message contents.
     *     @type string|string[] $headers     Additional headers.
     *     @type string|string[] $attachments Paths to files to attach.
     * }
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    /**
     * Filters whether to preempt sending an email.
     *
     * Returning a non-null value will short-circuit {@see wp_mail()}, returning
     * that value instead. A boolean return value should be used to indicate whether
     * the email was successfully sent.
     *
     * @since 5.7.0
     *
     * @param null|bool $return Short-circuit return value.
     * @param array     $atts {
     *     Array of the `wp_mail()` arguments.
     *
     *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
     *     @type string          $subject     Email subject.
     *     @type string          $message     Message contents.
     *     @type string|string[] $headers     Additional headers.
     *     @type string|string[] $attachments Paths to files to attach.
     * }
     */
    $pre_wp_mail = apply_filters('pre_wp_mail', null, $atts);
    if (null !== $pre_wp_mail) {
        return $pre_wp_mail;
    }
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing.
    if (!$phpmailer instanceof PHPMailer\PHPMailer\PHPMailer) {
        require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
        require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
        require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
        $phpmailer = new PHPMailer\PHPMailer\PHPMailer(true);
        $phpmailer::$validator = static function ($email) {
            return (bool) is_email($email);
        };
    }
    // Headers.
    $cc = array();
    $bcc = array();
    $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take
            // both string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents.
        if (!empty($tempheaders)) {
            // Iterate through the raw headers.
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out.
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew.
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a "From:" header if it's there.
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if (false !== $bracket_pos) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array.
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set.
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // Set "From" name and email.
    // If we don't have a name from the input headers.
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /*
     * If we don't have an email from the input headers, default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist,
     * but there's no easy alternative. Defaulting to admin_email might appear to be
     * another option, but some hosts may refuse to relay mail from an unknown domain.
     * See https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = wp_parse_url(network_home_url(), PHP_URL_HOST);
        if ('www.' === substr($sitename, 0, 4)) {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body.
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses.
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>".
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail().
    $phpmailer->isMail();
    // Set Content-Type and charset.
    // If we don't have a content-type from the input headers.
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type.
    if ('text/html' === $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers.
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers.
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            // Only add custom headers not added automatically by PHPMailer.
            if (!in_array($name, array('MIME-Version', 'X-Mailer'), true)) {
                try {
                    $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
                } catch (PHPMailer\PHPMailer\Exception $e) {
                    continue;
                }
            }
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf('Content-Type: %s; boundary="%s"', $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    $mail_data = compact('to', 'subject', 'message', 'headers', 'attachments');
    // Send!
    try {
        $send = $phpmailer->send();
        /**
         * Fires after PHPMailer has successfully sent a mail.
         *
         * The firing of this action does not necessarily mean that the recipient received the
         * email successfully. It only means that the `send` method above was able to
         * process the request without any errors.
         *
         * @since 5.9.0
         *
         * @param array $mail_data An array containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_succeeded', $mail_data);
        return $send;
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a PHPMailer\PHPMailer\Exception is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the PHPMailer\PHPMailer\Exception message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_data));
        return false;
    }
}

WordPress Version: 5.9

/**
 * Sends an email, similar to PHP's mail function.
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * The default content type is `text/plain` which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 * @since 5.5.0 is_email() is used for email validation,
 *              instead of PHPMailer's default validator.
 *
 * @global PHPMailer\PHPMailer\PHPMailer $phpmailer
 *
 * @param string|string[] $to          Array or comma-separated list of email addresses to send message.
 * @param string          $subject     Email subject.
 * @param string          $message     Message contents.
 * @param string|string[] $headers     Optional. Additional headers.
 * @param string|string[] $attachments Optional. Paths to files to attach.
 * @return bool Whether the email was sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out.
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args {
     *     Array of the `wp_mail()` arguments.
     *
     *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
     *     @type string          $subject     Email subject.
     *     @type string          $message     Message contents.
     *     @type string|string[] $headers     Additional headers.
     *     @type string|string[] $attachments Paths to files to attach.
     * }
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    /**
     * Filters whether to preempt sending an email.
     *
     * Returning a non-null value will short-circuit {@see wp_mail()}, returning
     * that value instead. A boolean return value should be used to indicate whether
     * the email was successfully sent.
     *
     * @since 5.7.0
     *
     * @param null|bool $return Short-circuit return value.
     * @param array     $atts {
     *     Array of the `wp_mail()` arguments.
     *
     *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
     *     @type string          $subject     Email subject.
     *     @type string          $message     Message contents.
     *     @type string|string[] $headers     Additional headers.
     *     @type string|string[] $attachments Paths to files to attach.
     * }
     */
    $pre_wp_mail = apply_filters('pre_wp_mail', null, $atts);
    if (null !== $pre_wp_mail) {
        return $pre_wp_mail;
    }
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing.
    if (!$phpmailer instanceof PHPMailer\PHPMailer\PHPMailer) {
        require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
        require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
        require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
        $phpmailer = new PHPMailer\PHPMailer\PHPMailer(true);
        $phpmailer::$validator = static function ($email) {
            return (bool) is_email($email);
        };
    }
    // Headers.
    $cc = array();
    $bcc = array();
    $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take
            // both string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents.
        if (!empty($tempheaders)) {
            // Iterate through the raw headers.
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out.
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew.
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a "From:" header if it's there.
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if (false !== $bracket_pos) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array.
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set.
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    // Set "From" name and email.
    // If we don't have a name from the input headers.
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /*
     * If we don't have an email from the input headers, default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist,
     * but there's no easy alternative. Defaulting to admin_email might appear to be
     * another option, but some hosts may refuse to relay mail from an unknown domain.
     * See https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = wp_parse_url(network_home_url(), PHP_URL_HOST);
        if ('www.' === substr($sitename, 0, 4)) {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body.
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses.
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>".
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail().
    $phpmailer->isMail();
    // Set Content-Type and charset.
    // If we don't have a content-type from the input headers.
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type.
    if ('text/html' === $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers.
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers.
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            // Only add custom headers not added automatically by PHPMailer.
            if (!in_array($name, array('MIME-Version', 'X-Mailer'), true)) {
                try {
                    $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
                } catch (PHPMailer\PHPMailer\Exception $e) {
                    continue;
                }
            }
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf('Content-Type: %s; boundary="%s"', $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    $mail_data = compact('to', 'subject', 'message', 'headers', 'attachments');
    // Send!
    try {
        $send = $phpmailer->send();
        /**
         * Fires after PHPMailer has successfully sent a mail.
         *
         * The firing of this action does not necessarily mean that the recipient received the
         * email successfully. It only means that the `send` method above was able to
         * process the request without any errors.
         *
         * @since 5.9.0
         *
         * @param array $mail_data An array containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_succeeded', $mail_data);
        return $send;
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a PHPMailer\PHPMailer\Exception is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the PHPMailer\PHPMailer\Exception message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_data));
        return false;
    }
}

WordPress Version: 8.6

/**
 * Sends an email, similar to PHP's mail function.
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * The default content type is `text/plain` which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 * @since 5.5.0 is_email() is used for email validation,
 *              instead of PHPMailer's default validator.
 *
 * @global PHPMailer\PHPMailer\PHPMailer $phpmailer
 *
 * @param string|string[] $to          Array or comma-separated list of email addresses to send message.
 * @param string          $subject     Email subject.
 * @param string          $message     Message contents.
 * @param string|string[] $headers     Optional. Additional headers.
 * @param string|string[] $attachments Optional. Paths to files to attach.
 * @return bool Whether the email was sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out.
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args {
     *     Array of the `wp_mail()` arguments.
     *
     *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
     *     @type string          $subject     Email subject.
     *     @type string          $message     Message contents.
     *     @type string|string[] $headers     Additional headers.
     *     @type string|string[] $attachments Paths to files to attach.
     * }
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    /**
     * Filters whether to preempt sending an email.
     *
     * Returning a non-null value will short-circuit {@see wp_mail()}, returning
     * that value instead. A boolean return value should be used to indicate whether
     * the email was successfully sent.
     *
     * @since 5.7.0
     *
     * @param null|bool $return Short-circuit return value.
     * @param array     $atts {
     *     Array of the `wp_mail()` arguments.
     *
     *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
     *     @type string          $subject     Email subject.
     *     @type string          $message     Message contents.
     *     @type string|string[] $headers     Additional headers.
     *     @type string|string[] $attachments Paths to files to attach.
     * }
     */
    $pre_wp_mail = apply_filters('pre_wp_mail', null, $atts);
    if (null !== $pre_wp_mail) {
        return $pre_wp_mail;
    }
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing.
    if (!$phpmailer instanceof PHPMailer\PHPMailer\PHPMailer) {
        require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
        require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
        require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
        $phpmailer = new PHPMailer\PHPMailer\PHPMailer(true);
        $phpmailer::$validator = static function ($email) {
            return (bool) is_email($email);
        };
    }
    // Headers.
    $cc = array();
    $bcc = array();
    $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take
            // both string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents.
        if (!empty($tempheaders)) {
            // Iterate through the raw headers.
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out.
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew.
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a "From:" header if it's there.
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if (false !== $bracket_pos) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array.
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set.
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // Set "From" name and email.
    // If we don't have a name from the input headers.
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /*
     * If we don't have an email from the input headers, default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist,
     * but there's no easy alternative. Defaulting to admin_email might appear to be
     * another option, but some hosts may refuse to relay mail from an unknown domain.
     * See https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = wp_parse_url(network_home_url(), PHP_URL_HOST);
        if ('www.' === substr($sitename, 0, 4)) {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body.
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses.
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>".
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail().
    $phpmailer->isMail();
    // Set Content-Type and charset.
    // If we don't have a content-type from the input headers.
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type.
    if ('text/html' === $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers.
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers.
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            // Only add custom headers not added automatically by PHPMailer.
            if (!in_array($name, array('MIME-Version', 'X-Mailer'), true)) {
                try {
                    $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
                } catch (PHPMailer\PHPMailer\Exception $e) {
                    continue;
                }
            }
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf('Content-Type: %s; boundary="%s"', $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a PHPMailer\PHPMailer\Exception is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the PHPMailer\PHPMailer\Exception message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 5.8

/**
 * Sends an email, similar to PHP's mail function.
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * The default content type is `text/plain` which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 * @since 5.5.0 is_email() is used for email validation,
 *              instead of PHPMailer's default validator.
 *
 * @global PHPMailer\PHPMailer\PHPMailer $phpmailer
 *
 * @param string|string[] $to          Array or comma-separated list of email addresses to send message.
 * @param string          $subject     Email subject.
 * @param string          $message     Message contents.
 * @param string|string[] $headers     Optional. Additional headers.
 * @param string|string[] $attachments Optional. Paths to files to attach.
 * @return bool Whether the email was sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out.
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args {
     *     Array of the `wp_mail()` arguments.
     *
     *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
     *     @type string          $subject     Email subject.
     *     @type string          $message     Message contents.
     *     @type string|string[] $headers     Additional headers.
     *     @type string|string[] $attachments Paths to files to attach.
     * }
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    /**
     * Filters whether to preempt sending an email.
     *
     * Returning a non-null value will short-circuit {@see wp_mail()}, returning
     * that value instead. A boolean return value should be used to indicate whether
     * the email was successfully sent.
     *
     * @since 5.7.0
     *
     * @param null|bool $return Short-circuit return value.
     * @param array     $atts {
     *     Array of the `wp_mail()` arguments.
     *
     *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
     *     @type string          $subject     Email subject.
     *     @type string          $message     Message contents.
     *     @type string|string[] $headers     Additional headers.
     *     @type string|string[] $attachments Paths to files to attach.
     * }
     */
    $pre_wp_mail = apply_filters('pre_wp_mail', null, $atts);
    if (null !== $pre_wp_mail) {
        return $pre_wp_mail;
    }
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing.
    if (!$phpmailer instanceof PHPMailer\PHPMailer\PHPMailer) {
        require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
        require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
        require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
        $phpmailer = new PHPMailer\PHPMailer\PHPMailer(true);
        $phpmailer::$validator = static function ($email) {
            return (bool) is_email($email);
        };
    }
    // Headers.
    $cc = array();
    $bcc = array();
    $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take
            // both string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents.
        if (!empty($tempheaders)) {
            // Iterate through the raw headers.
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out.
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew.
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a "From:" header if it's there.
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if (false !== $bracket_pos) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array.
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set.
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    // Set "From" name and email.
    // If we don't have a name from the input headers.
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /*
     * If we don't have an email from the input headers, default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist,
     * but there's no easy alternative. Defaulting to admin_email might appear to be
     * another option, but some hosts may refuse to relay mail from an unknown domain.
     * See https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = wp_parse_url(network_home_url(), PHP_URL_HOST);
        if ('www.' === substr($sitename, 0, 4)) {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body.
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses.
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>".
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail().
    $phpmailer->isMail();
    // Set Content-Type and charset.
    // If we don't have a content-type from the input headers.
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type.
    if ('text/html' === $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers.
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers.
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            // Only add custom headers not added automatically by PHPMailer.
            if (!in_array($name, array('MIME-Version', 'X-Mailer'), true)) {
                try {
                    $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
                } catch (PHPMailer\PHPMailer\Exception $e) {
                    continue;
                }
            }
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf('Content-Type: %s; boundary="%s"', $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a PHPMailer\PHPMailer\Exception is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the PHPMailer\PHPMailer\Exception message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 7.8

/**
 * Sends an email, similar to PHP's mail function.
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * The default content type is `text/plain` which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer\PHPMailer\PHPMailer $phpmailer
 *
 * @param string|string[] $to          Array or comma-separated list of email addresses to send message.
 * @param string          $subject     Email subject.
 * @param string          $message     Message contents.
 * @param string|string[] $headers     Optional. Additional headers.
 * @param string|string[] $attachments Optional. Paths to files to attach.
 * @return bool Whether the email was sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out.
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args {
     *     Array of the `wp_mail()` arguments.
     *
     *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
     *     @type string          $subject     Email subject.
     *     @type string          $message     Message contents.
     *     @type string|string[] $headers     Additional headers.
     *     @type string|string[] $attachments Paths to files to attach.
     * }
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    /**
     * Filters whether to preempt sending an email.
     *
     * Returning a non-null value will short-circuit {@see wp_mail()}, returning
     * that value instead. A boolean return value should be used to indicate whether
     * the email was successfully sent.
     *
     * @since 5.7.0
     *
     * @param null|bool $return Short-circuit return value.
     * @param array     $atts {
     *     Array of the `wp_mail()` arguments.
     *
     *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
     *     @type string          $subject     Email subject.
     *     @type string          $message     Message contents.
     *     @type string|string[] $headers     Additional headers.
     *     @type string|string[] $attachments Paths to files to attach.
     * }
     */
    $pre_wp_mail = apply_filters('pre_wp_mail', null, $atts);
    if (null !== $pre_wp_mail) {
        return $pre_wp_mail;
    }
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing.
    if (!$phpmailer instanceof PHPMailer\PHPMailer\PHPMailer) {
        require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
        require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
        require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
        $phpmailer = new PHPMailer\PHPMailer\PHPMailer(true);
        $phpmailer::$validator = static function ($email) {
            return (bool) is_email($email);
        };
    }
    // Headers.
    $cc = array();
    $bcc = array();
    $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take
            // both string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents.
        if (!empty($tempheaders)) {
            // Iterate through the raw headers.
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out.
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew.
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a "From:" header if it's there.
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if (false !== $bracket_pos) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array.
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set.
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // Set "From" name and email.
    // If we don't have a name from the input headers.
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /*
     * If we don't have an email from the input headers, default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist,
     * but there's no easy alternative. Defaulting to admin_email might appear to be
     * another option, but some hosts may refuse to relay mail from an unknown domain.
     * See https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = wp_parse_url(network_home_url(), PHP_URL_HOST);
        if ('www.' === substr($sitename, 0, 4)) {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body.
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses.
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>".
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail().
    $phpmailer->isMail();
    // Set Content-Type and charset.
    // If we don't have a content-type from the input headers.
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type.
    if ('text/html' === $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers.
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers.
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            // Only add custom headers not added automatically by PHPMailer.
            if (!in_array($name, array('MIME-Version', 'X-Mailer'), true)) {
                try {
                    $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
                } catch (PHPMailer\PHPMailer\Exception $e) {
                    continue;
                }
            }
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf('Content-Type: %s; boundary="%s"', $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a PHPMailer\PHPMailer\Exception is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the PHPMailer\PHPMailer\Exception message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 7.2

/**
 * Sends an email, similar to PHP's mail function.
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * The default content type is `text/plain` which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer\PHPMailer\PHPMailer $phpmailer
 *
 * @param string|string[] $to          Array or comma-separated list of email addresses to send message.
 * @param string          $subject     Email subject.
 * @param string          $message     Message contents.
 * @param string|string[] $headers     Optional. Additional headers.
 * @param string|string[] $attachments Optional. Paths to files to attach.
 * @return bool Whether the email was sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out.
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args {
     *     Array of the `wp_mail()` arguments.
     *
     *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
     *     @type string          $subject     Email subject.
     *     @type string          $message     Message contents.
     *     @type string|string[] $headers     Additional headers.
     *     @type string|string[] $attachments Paths to files to attach.
     * }
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    /**
     * Filters whether to preempt sending an email.
     *
     * Returning a non-null value will short-circuit {@see wp_mail()}, returning
     * that value instead. A boolean return value should be used to indicate whether
     * the email was successfully sent.
     *
     * @since 5.7.0
     *
     * @param null|bool $return Short-circuit return value.
     * @param array     $atts {
     *     Array of the `wp_mail()` arguments.
     *
     *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
     *     @type string          $subject     Email subject.
     *     @type string          $message     Message contents.
     *     @type string|string[] $headers     Additional headers.
     *     @type string|string[] $attachments Paths to files to attach.
     * }
     */
    $pre_wp_mail = apply_filters('pre_wp_mail', null, $atts);
    if (null !== $pre_wp_mail) {
        return $pre_wp_mail;
    }
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing.
    if (!$phpmailer instanceof PHPMailer\PHPMailer\PHPMailer) {
        require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
        require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
        require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
        $phpmailer = new PHPMailer\PHPMailer\PHPMailer(true);
        $phpmailer::$validator = static function ($email) {
            return (bool) is_email($email);
        };
    }
    // Headers.
    $cc = array();
    $bcc = array();
    $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take
            // both string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents.
        if (!empty($tempheaders)) {
            // Iterate through the raw headers.
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out.
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew.
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a "From:" header if it's there.
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if (false !== $bracket_pos) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array.
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set.
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    // Set "From" name and email.
    // If we don't have a name from the input headers.
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /*
     * If we don't have an email from the input headers, default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist,
     * but there's no easy alternative. Defaulting to admin_email might appear to be
     * another option, but some hosts may refuse to relay mail from an unknown domain.
     * See https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = wp_parse_url(network_home_url(), PHP_URL_HOST);
        if ('www.' === substr($sitename, 0, 4)) {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body.
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses.
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>".
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail().
    $phpmailer->isMail();
    // Set Content-Type and charset.
    // If we don't have a content-type from the input headers.
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type.
    if ('text/html' === $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers.
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers.
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            // Only add custom headers not added automatically by PHPMailer.
            if (!in_array($name, array('MIME-Version', 'X-Mailer'), true)) {
                try {
                    $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
                } catch (PHPMailer\PHPMailer\Exception $e) {
                    continue;
                }
            }
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf('Content-Type: %s; boundary="%s"', $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a PHPMailer\PHPMailer\Exception is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the PHPMailer\PHPMailer\Exception message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: .10

/**
 * Sends an email, similar to PHP's mail function.
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * The default content type is `text/plain` which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer\PHPMailer\PHPMailer $phpmailer
 *
 * @param string|string[] $to          Array or comma-separated list of email addresses to send message.
 * @param string          $subject     Email subject.
 * @param string          $message     Message contents.
 * @param string|string[] $headers     Optional. Additional headers.
 * @param string|string[] $attachments Optional. Paths to files to attach.
 * @return bool Whether the email was sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out.
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args {
     *     Array of the `wp_mail()` arguments.
     *
     *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
     *     @type string          $subject     Email subject.
     *     @type string          $message     Message contents.
     *     @type string|string[] $headers     Additional headers.
     *     @type string|string[] $attachments Paths to files to attach.
     * }
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    /**
     * Filters whether to preempt sending an email.
     *
     * Returning a non-null value will short-circuit {@see wp_mail()}, returning
     * that value instead. A boolean return value should be used to indicate whether
     * the email was successfully sent.
     *
     * @since 5.7.0
     *
     * @param null|bool $return Short-circuit return value.
     * @param array     $atts {
     *     Array of the `wp_mail()` arguments.
     *
     *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
     *     @type string          $subject     Email subject.
     *     @type string          $message     Message contents.
     *     @type string|string[] $headers     Additional headers.
     *     @type string|string[] $attachments Paths to files to attach.
     * }
     */
    $pre_wp_mail = apply_filters('pre_wp_mail', null, $atts);
    if (null !== $pre_wp_mail) {
        return $pre_wp_mail;
    }
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing.
    if (!$phpmailer instanceof PHPMailer\PHPMailer\PHPMailer) {
        require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
        require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
        require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
        $phpmailer = new PHPMailer\PHPMailer\PHPMailer(true);
        $phpmailer::$validator = static function ($email) {
            return (bool) is_email($email);
        };
    }
    // Headers.
    $cc = array();
    $bcc = array();
    $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take
            // both string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents.
        if (!empty($tempheaders)) {
            // Iterate through the raw headers.
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out.
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew.
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a "From:" header if it's there.
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if (false !== $bracket_pos) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array.
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set.
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // Set "From" name and email.
    // If we don't have a name from the input headers.
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /*
     * If we don't have an email from the input headers, default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist,
     * but there's no easy alternative. Defaulting to admin_email might appear to be
     * another option, but some hosts may refuse to relay mail from an unknown domain.
     * See https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = wp_parse_url(network_home_url(), PHP_URL_HOST);
        if ('www.' === substr($sitename, 0, 4)) {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body.
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses.
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>".
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail().
    $phpmailer->isMail();
    // Set Content-Type and charset.
    // If we don't have a content-type from the input headers.
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type.
    if ('text/html' === $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers.
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers.
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            // Only add custom headers not added automatically by PHPMailer.
            if (!in_array($name, array('MIME-Version', 'X-Mailer'), true)) {
                try {
                    $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
                } catch (PHPMailer\PHPMailer\Exception $e) {
                    continue;
                }
            }
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf('Content-Type: %s; boundary="%s"', $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a PHPMailer\PHPMailer\Exception is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the PHPMailer\PHPMailer\Exception message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 5.7

/**
 * Sends an email, similar to PHP's mail function.
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * The default content type is `text/plain` which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer\PHPMailer\PHPMailer $phpmailer
 *
 * @param string|string[] $to          Array or comma-separated list of email addresses to send message.
 * @param string          $subject     Email subject.
 * @param string          $message     Message contents.
 * @param string|string[] $headers     Optional. Additional headers.
 * @param string|string[] $attachments Optional. Paths to files to attach.
 * @return bool Whether the email was sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out.
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args {
     *     Array of the `wp_mail()` arguments.
     *
     *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
     *     @type string          $subject     Email subject.
     *     @type string          $message     Message contents.
     *     @type string|string[] $headers     Additional headers.
     *     @type string|string[] $attachments Paths to files to attach.
     * }
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    /**
     * Filters whether to preempt sending an email.
     *
     * Returning a non-null value will short-circuit {@see wp_mail()}, returning
     * that value instead. A boolean return value should be used to indicate whether
     * the email was successfully sent.
     *
     * @since 5.7.0
     *
     * @param null|bool $return Short-circuit return value.
     * @param array     $atts {
     *     Array of the `wp_mail()` arguments.
     *
     *     @type string|string[] $to          Array or comma-separated list of email addresses to send message.
     *     @type string          $subject     Email subject.
     *     @type string          $message     Message contents.
     *     @type string|string[] $headers     Additional headers.
     *     @type string|string[] $attachments Paths to files to attach.
     * }
     */
    $pre_wp_mail = apply_filters('pre_wp_mail', null, $atts);
    if (null !== $pre_wp_mail) {
        return $pre_wp_mail;
    }
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing.
    if (!$phpmailer instanceof PHPMailer\PHPMailer\PHPMailer) {
        require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
        require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
        require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
        $phpmailer = new PHPMailer\PHPMailer\PHPMailer(true);
        $phpmailer::$validator = static function ($email) {
            return (bool) is_email($email);
        };
    }
    // Headers.
    $cc = array();
    $bcc = array();
    $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take
            // both string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents.
        if (!empty($tempheaders)) {
            // Iterate through the raw headers.
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out.
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew.
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a "From:" header if it's there.
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if (false !== $bracket_pos) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array.
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set.
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    // Set "From" name and email.
    // If we don't have a name from the input headers.
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /*
     * If we don't have an email from the input headers, default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist,
     * but there's no easy alternative. Defaulting to admin_email might appear to be
     * another option, but some hosts may refuse to relay mail from an unknown domain.
     * See https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = wp_parse_url(network_home_url(), PHP_URL_HOST);
        if ('www.' === substr($sitename, 0, 4)) {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body.
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses.
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>".
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail().
    $phpmailer->isMail();
    // Set Content-Type and charset.
    // If we don't have a content-type from the input headers.
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type.
    if ('text/html' === $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers.
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers.
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            // Only add custom headers not added automatically by PHPMailer.
            if (!in_array($name, array('MIME-Version', 'X-Mailer'), true)) {
                try {
                    $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
                } catch (PHPMailer\PHPMailer\Exception $e) {
                    continue;
                }
            }
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf('Content-Type: %s; boundary="%s"', $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a PHPMailer\PHPMailer\Exception is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the PHPMailer\PHPMailer\Exception message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 6.2

/**
 * Sends an email, similar to PHP's mail function.
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * The default content type is `text/plain` which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer\PHPMailer\PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out.
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing.
    if (!$phpmailer instanceof PHPMailer\PHPMailer\PHPMailer) {
        require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
        require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
        require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
        $phpmailer = new PHPMailer\PHPMailer\PHPMailer(true);
        $phpmailer::$validator = static function ($email) {
            return (bool) is_email($email);
        };
    }
    // Headers.
    $cc = array();
    $bcc = array();
    $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take
            // both string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents.
        if (!empty($tempheaders)) {
            // Iterate through the raw headers.
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out.
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew.
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a "From:" header if it's there.
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if (false !== $bracket_pos) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array.
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set.
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    // Set "From" name and email.
    // If we don't have a name from the input headers.
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /*
     * If we don't have an email from the input headers, default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist,
     * but there's no easy alternative. Defaulting to admin_email might appear to be
     * another option, but some hosts may refuse to relay mail from an unknown domain.
     * See https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = wp_parse_url(network_home_url(), PHP_URL_HOST);
        if ('www.' === substr($sitename, 0, 4)) {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body.
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses.
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>".
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail().
    $phpmailer->isMail();
    // Set Content-Type and charset.
    // If we don't have a content-type from the input headers.
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type.
    if ('text/html' === $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers.
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers.
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            // Only add custom headers not added automatically by PHPMailer.
            if (!in_array($name, array('MIME-Version', 'X-Mailer'), true)) {
                try {
                    $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
                } catch (PHPMailer\PHPMailer\Exception $e) {
                    continue;
                }
            }
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf('Content-Type: %s; boundary="%s"', $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a PHPMailer\PHPMailer\Exception is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the PHPMailer\PHPMailer\Exception message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: .10

/**
 * Sends an email, similar to PHP's mail function.
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * The default content type is `text/plain` which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer\PHPMailer\PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out.
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing.
    if (!$phpmailer instanceof PHPMailer\PHPMailer\PHPMailer) {
        require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
        require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
        require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
        $phpmailer = new PHPMailer\PHPMailer\PHPMailer(true);
        $phpmailer::$validator = static function ($email) {
            return (bool) is_email($email);
        };
    }
    // Headers.
    $cc = array();
    $bcc = array();
    $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take
            // both string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents.
        if (!empty($tempheaders)) {
            // Iterate through the raw headers.
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out.
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew.
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a "From:" header if it's there.
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if (false !== $bracket_pos) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array.
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set.
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // Set "From" name and email.
    // If we don't have a name from the input headers.
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /*
     * If we don't have an email from the input headers, default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist,
     * but there's no easy alternative. Defaulting to admin_email might appear to be
     * another option, but some hosts may refuse to relay mail from an unknown domain.
     * See https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = wp_parse_url(network_home_url(), PHP_URL_HOST);
        if ('www.' === substr($sitename, 0, 4)) {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body.
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses.
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>".
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail().
    $phpmailer->isMail();
    // Set Content-Type and charset.
    // If we don't have a content-type from the input headers.
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type.
    if ('text/html' === $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers.
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers.
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            // Only add custom headers not added automatically by PHPMailer.
            if (!in_array($name, array('MIME-Version', 'X-Mailer'), true)) {
                try {
                    $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
                } catch (PHPMailer\PHPMailer\Exception $e) {
                    continue;
                }
            }
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf('Content-Type: %s; boundary="%s"', $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a PHPMailer\PHPMailer\Exception is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the PHPMailer\PHPMailer\Exception message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 5.2

/**
 * Sends an email, similar to PHP's mail function.
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * The default content type is `text/plain` which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer\PHPMailer\PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out.
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing.
    if (!$phpmailer instanceof PHPMailer\PHPMailer\PHPMailer) {
        require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
        require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
        require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
        $phpmailer = new PHPMailer\PHPMailer\PHPMailer(true);
        $phpmailer::$validator = static function ($email) {
            return (bool) is_email($email);
        };
    }
    // Headers.
    $cc = array();
    $bcc = array();
    $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take
            // both string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents.
        if (!empty($tempheaders)) {
            // Iterate through the raw headers.
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out.
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew.
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a "From:" header if it's there.
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if (false !== $bracket_pos) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array.
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set.
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    // Set "From" name and email.
    // If we don't have a name from the input headers.
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /*
     * If we don't have an email from the input headers, default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist,
     * but there's no easy alternative. Defaulting to admin_email might appear to be
     * another option, but some hosts may refuse to relay mail from an unknown domain.
     * See https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = wp_parse_url(network_home_url(), PHP_URL_HOST);
        if ('www.' === substr($sitename, 0, 4)) {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body.
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses.
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>".
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail().
    $phpmailer->isMail();
    // Set Content-Type and charset.
    // If we don't have a content-type from the input headers.
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type.
    if ('text/html' === $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers.
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers.
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            // Only add custom headers not added automatically by PHPMailer.
            if (!in_array($name, array('MIME-Version', 'X-Mailer'), true)) {
                try {
                    $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
                } catch (PHPMailer\PHPMailer\Exception $e) {
                    continue;
                }
            }
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf('Content-Type: %s; boundary="%s"', $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a PHPMailer\PHPMailer\Exception is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the PHPMailer\PHPMailer\Exception message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: .11

/**
 * Sends an email, similar to PHP's mail function.
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * The default content type is `text/plain` which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer\PHPMailer\PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out.
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing.
    if (!$phpmailer instanceof PHPMailer\PHPMailer\PHPMailer) {
        require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
        require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
        require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
        $phpmailer = new PHPMailer\PHPMailer\PHPMailer(true);
        $phpmailer::$validator = static function ($email) {
            return (bool) is_email($email);
        };
    }
    // Headers.
    $cc = array();
    $bcc = array();
    $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take
            // both string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents.
        if (!empty($tempheaders)) {
            // Iterate through the raw headers.
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out.
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew.
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a "From:" header if it's there.
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if (false !== $bracket_pos) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array.
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set.
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // Set "From" name and email.
    // If we don't have a name from the input headers.
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /*
     * If we don't have an email from the input headers, default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist,
     * but there's no easy alternative. Defaulting to admin_email might appear to be
     * another option, but some hosts may refuse to relay mail from an unknown domain.
     * See https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = wp_parse_url(network_home_url(), PHP_URL_HOST);
        if ('www.' === substr($sitename, 0, 4)) {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body.
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses.
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>".
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail().
    $phpmailer->isMail();
    // Set Content-Type and charset.
    // If we don't have a content-type from the input headers.
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type.
    if ('text/html' === $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers.
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers.
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            // Only add custom headers not added automatically by PHPMailer.
            if (!in_array($name, array('MIME-Version', 'X-Mailer'), true)) {
                try {
                    $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
                } catch (PHPMailer\PHPMailer\Exception $e) {
                    continue;
                }
            }
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf('Content-Type: %s; boundary="%s"', $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a PHPMailer\PHPMailer\Exception is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the PHPMailer\PHPMailer\Exception message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 5.5

/**
 * Sends an email, similar to PHP's mail function.
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * The default content type is `text/plain` which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer\PHPMailer\PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out.
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing.
    if (!$phpmailer instanceof PHPMailer\PHPMailer\PHPMailer) {
        require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
        require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
        require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
        $phpmailer = new PHPMailer\PHPMailer\PHPMailer(true);
        $phpmailer::$validator = static function ($email) {
            return (bool) is_email($email);
        };
    }
    // Headers.
    $cc = array();
    $bcc = array();
    $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take
            // both string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents.
        if (!empty($tempheaders)) {
            // Iterate through the raw headers.
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out.
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew.
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a "From:" header if it's there.
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if (false !== $bracket_pos) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array.
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set.
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    // Set "From" name and email.
    // If we don't have a name from the input headers.
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /*
     * If we don't have an email from the input headers, default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist,
     * but there's no easy alternative. Defaulting to admin_email might appear to be
     * another option, but some hosts may refuse to relay mail from an unknown domain.
     * See https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = wp_parse_url(network_home_url(), PHP_URL_HOST);
        if ('www.' === substr($sitename, 0, 4)) {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body.
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses.
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>".
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail().
    $phpmailer->isMail();
    // Set Content-Type and charset.
    // If we don't have a content-type from the input headers.
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type.
    if ('text/html' === $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers.
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers.
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            // Only add custom headers not added automatically by PHPMailer.
            if (!in_array($name, array('MIME-Version', 'X-Mailer'), true)) {
                try {
                    $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
                } catch (PHPMailer\PHPMailer\Exception $e) {
                    continue;
                }
            }
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf('Content-Type: %s; boundary="%s"', $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (PHPMailer\PHPMailer\Exception $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (PHPMailer\PHPMailer\Exception $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a PHPMailer\PHPMailer\Exception is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the PHPMailer\PHPMailer\Exception message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 4.2

/**
 * Sends an email, similar to PHP's mail function.
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * The default content type is `text/plain` which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out.
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing.
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers.
    $cc = array();
    $bcc = array();
    $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take
            // both string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents.
        if (!empty($tempheaders)) {
            // Iterate through the raw headers.
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out.
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew.
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a "From:" header if it's there.
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if (false !== $bracket_pos) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array.
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set.
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    // Set "From" name and email.
    // If we don't have a name from the input headers.
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /*
     * If we don't have an email from the input headers, default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist,
     * but there's no easy alternative. Defaulting to admin_email might appear to be
     * another option, but some hosts may refuse to relay mail from an unknown domain.
     * See https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body.
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses.
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>".
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail().
    $phpmailer->isMail();
    // Set Content-Type and charset.
    // If we don't have a content-type from the input headers.
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type.
    if ('text/html' == $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers.
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers.
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            // Only add custom headers not added automatically by PHPMailer.
            if (!in_array($name, array('MIME-Version', 'X-Mailer'))) {
                $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
            }
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: .12

/**
 * Sends an email, similar to PHP's mail function.
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * The default content type is `text/plain` which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out.
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing.
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers.
    $cc = array();
    $bcc = array();
    $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take
            // both string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents.
        if (!empty($tempheaders)) {
            // Iterate through the raw headers.
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out.
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew.
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a "From:" header if it's there.
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if (false !== $bracket_pos) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array.
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set.
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // Set "From" name and email.
    // If we don't have a name from the input headers.
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /*
     * If we don't have an email from the input headers, default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist,
     * but there's no easy alternative. Defaulting to admin_email might appear to be
     * another option, but some hosts may refuse to relay mail from an unknown domain.
     * See https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body.
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses.
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>".
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail().
    $phpmailer->isMail();
    // Set Content-Type and charset.
    // If we don't have a content-type from the input headers.
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type.
    if ('text/html' == $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers.
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers.
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            // Only add custom headers not added automatically by PHPMailer.
            if (!in_array($name, array('MIME-Version', 'X-Mailer'))) {
                $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
            }
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 5.4

/**
 * Sends an email, similar to PHP's mail function.
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * The default content type is `text/plain` which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out.
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing.
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers.
    $cc = array();
    $bcc = array();
    $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take
            // both string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents.
        if (!empty($tempheaders)) {
            // Iterate through the raw headers.
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out.
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew.
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a "From:" header if it's there.
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if (false !== $bracket_pos) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array.
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set.
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    // Set "From" name and email.
    // If we don't have a name from the input headers.
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /*
     * If we don't have an email from the input headers, default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist,
     * but there's no easy alternative. Defaulting to admin_email might appear to be
     * another option, but some hosts may refuse to relay mail from an unknown domain.
     * See https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body.
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses.
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>".
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail().
    $phpmailer->isMail();
    // Set Content-Type and charset.
    // If we don't have a content-type from the input headers.
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type.
    if ('text/html' == $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers.
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers.
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            // Only add custom headers not added automatically by PHPMailer.
            if (!in_array($name, array('MIME-Version', 'X-Mailer'))) {
                $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
            }
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 3.2

/**
 * Sends an email, similar to PHP's mail function.
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * The default content type is `text/plain` which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    $cc = array();
    $bcc = array();
    $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->isMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers.
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            // Only add custom headers not added automatically by PHPMailer.
            if (!in_array($name, array('MIME-Version', 'X-Mailer'))) {
                $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
            }
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: .14

/**
 * Sends an email, similar to PHP's mail function.
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * The default content type is `text/plain` which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    $cc = array();
    $bcc = array();
    $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->isMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers.
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            // Only add custom headers not added automatically by PHPMailer.
            if (!in_array($name, array('MIME-Version', 'X-Mailer'))) {
                $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
            }
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 5.3

/**
 * Sends an email, similar to PHP's mail function.
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * The default content type is `text/plain` which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    $cc = array();
    $bcc = array();
    $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->isMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers.
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            // Only add custom headers not added automatically by PHPMailer.
            if (!in_array($name, array('MIME-Version', 'X-Mailer'))) {
                $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
            }
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 2.3

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    $cc = $bcc = $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->isMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: .20

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    $cc = $bcc = $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->isMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 2.2

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    $cc = $bcc = $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->isMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: .17

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    $cc = $bcc = $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->isMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 1.2

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    $cc = $bcc = $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->isMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: .15

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    $cc = $bcc = $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->isMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 0.3

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    $cc = $bcc = $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->isMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: .20

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    $cc = $bcc = $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->isMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 0.2

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    $cc = $bcc = $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->isMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: .18

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    $cc = $bcc = $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->isMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 9.3

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    $cc = $bcc = $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->isMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: .22

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    $cc = $bcc = $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->isMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 4.9

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    $cc = $bcc = $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->isMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 4.8

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    $cc = $bcc = $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->clearAllRecipients();
    $phpmailer->clearAttachments();
    $phpmailer->clearCustomHeaders();
    $phpmailer->clearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    try {
        $phpmailer->setFrom($from_email, $from_name, false);
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /** This filter is documented in wp-includes/pluggable.php */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Set destination addresses, using appropriate methods for handling addresses
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->isMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->isHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->addCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->addAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 4.7

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    $cc = $bcc = $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    $phpmailer->setFrom($from_email, $from_name, false);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Use appropriate methods for handling addresses, rather than treating them as generic headers
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        $mail_error_data['phpmailer_exception_code'] = $e->getCode();
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 6.3

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    $cc = $bcc = $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    $phpmailer->setFrom($from_email, $from_name, false);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Use appropriate methods for handling addresses, rather than treating them as generic headers
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException code, message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error($e->getCode(), $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: .25

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    $cc = $bcc = $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    $phpmailer->setFrom($from_email, $from_name, false);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Use appropriate methods for handling addresses, rather than treating them as generic headers
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException code, message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error($e->getCode(), $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 6.1

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    $cc = $bcc = $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    $phpmailer->setFrom($from_email, $from_name, false);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Use appropriate methods for handling addresses, rather than treating them as generic headers
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException code, message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error($e->getCode(), $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 4.6

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * {@see 'wp_mail_content_type'} filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the {@see 'wp_mail_charset'} filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filters the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    $cc = $bcc = $reply_to = array();
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    case 'reply-to':
                        $reply_to = array_merge((array) $reply_to, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filters the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $from_email = apply_filters('wp_mail_from', $from_email);
    /**
     * Filters the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $from_name = apply_filters('wp_mail_from_name', $from_name);
    $phpmailer->setFrom($from_email, $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Use appropriate methods for handling addresses, rather than treating them as generic headers
    $address_headers = compact('to', 'cc', 'bcc', 'reply_to');
    foreach ($address_headers as $address_header => $addresses) {
        if (empty($addresses)) {
            continue;
        }
        foreach ((array) $addresses as $address) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $address = $matches[2];
                    }
                }
                switch ($address_header) {
                    case 'to':
                        $phpmailer->addAddress($address, $recipient_name);
                        break;
                    case 'cc':
                        $phpmailer->addCc($address, $recipient_name);
                        break;
                    case 'bcc':
                        $phpmailer->addBcc($address, $recipient_name);
                        break;
                    case 'reply_to':
                        $phpmailer->addReplyTo($address, $recipient_name);
                        break;
                }
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filters the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filters the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException code, message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error($e->getCode(), $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 5.4

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException code, message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error($e->getCode(), $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: .30

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException code, message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error($e->getCode(), $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 5.3

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException code, message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error($e->getCode(), $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: .28

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException code, message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error($e->getCode(), $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 4.4

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException code, message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error($e->getCode(), $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: .30

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException code, message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error($e->getCode(), $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 4.3

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException code, message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error($e->getCode(), $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: .29

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException code, message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error($e->getCode(), $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: .20

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException code, message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error($e->getCode(), $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 4.2

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact($to, $subject, $message, $headers, $attachments);
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException code, message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error($e->getCode(), $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: .10

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException code, message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error($e->getCode(), $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 4.4

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        $mail_error_data = compact($to, $subject, $message, $headers, $attachments);
        /**
         * Fires after a phpmailerException is caught.
         *
         * @since 4.4.0
         *
         * @param WP_Error $error A WP_Error object with the phpmailerException code, message, and an array
         *                        containing the mail recipient, subject, message, headers, and attachments.
         */
        do_action('wp_mail_failed', new WP_Error($e->getCode(), $e->getMessage(), $mail_error_data));
        return false;
    }
}

WordPress Version: 3.4

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        return false;
    }
}

WordPress Version: .30

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        return false;
    }
}

WordPress Version: 4.3

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @global PHPMailer $phpmailer
 *
 * @param string|array $to          Array or comma-separated list of email addresses to send message.
 * @param string       $subject     Email subject
 * @param string       $message     Message contents
 * @param string|array $headers     Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        return false;
    }
}

WordPress Version: 2.4

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @uses PHPMailer
 *
 * @param string|array $to Array or comma-separated list of email addresses to send message.
 * @param string $subject Email subject
 * @param string $message Message contents
 * @param string|array $headers Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        return false;
    }
}

WordPress Version: .34

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @uses PHPMailer
 *
 * @param string|array $to Array or comma-separated list of email addresses to send message.
 * @param string $subject Email subject
 * @param string $message Message contents
 * @param string|array $headers Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        return false;
    }
}

WordPress Version: 4.2

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @uses PHPMailer
 *
 * @param string|array $to Array or comma-separated list of email addresses to send message.
 * @param string $subject Email subject
 * @param string $message Message contents
 * @param string|array $headers Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!$phpmailer instanceof PHPMailer) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos($content, '<');
                        if ($bracket_pos !== false) {
                            // Text before the bracketed email is the "From" name.
                            if ($bracket_pos > 0) {
                                $from_name = substr($content, 0, $bracket_pos - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);
                            }
                            $from_email = substr($content, $bracket_pos + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                            // Avoid setting an empty $from_email.
                        } elseif ('' !== trim($content)) {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset_content) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset_content, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset_content));
                            } elseif (false !== stripos($charset_content, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content));
                                $charset = '';
                            }
                            // Avoid setting an empty $content_type.
                        } elseif ('' !== trim($content)) {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        return false;
    }
}

WordPress Version: 1.5

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @uses PHPMailer
 *
 * @param string|array $to Array or comma-separated list of email addresses to send message.
 * @param string $subject Email subject
 * @param string $message Message contents
 * @param string|array $headers Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!is_object($phpmailer) || !is_a($phpmailer, 'PHPMailer')) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        if (strpos($content, '<') !== false) {
                            // So... making my life hard again?
                            $from_name = substr($content, 0, strpos($content, '<') - 1);
                            $from_name = str_replace('"', '', $from_name);
                            $from_name = trim($from_name);
                            $from_email = substr($content, strpos($content, '<') + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                        } else {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset));
                            } elseif (false !== stripos($charset, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset));
                                $charset = '';
                            }
                        } else {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        return false;
    }
}

WordPress Version: .40

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @uses PHPMailer
 *
 * @param string|array $to Array or comma-separated list of email addresses to send message.
 * @param string $subject Email subject
 * @param string $message Message contents
 * @param string|array $headers Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!is_object($phpmailer) || !is_a($phpmailer, 'PHPMailer')) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        if (strpos($content, '<') !== false) {
                            // So... making my life hard again?
                            $from_name = substr($content, 0, strpos($content, '<') - 1);
                            $from_name = str_replace('"', '', $from_name);
                            $from_name = trim($from_name);
                            $from_email = substr($content, strpos($content, '<') + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                        } else {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset));
                            } elseif (false !== stripos($charset, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset));
                                $charset = '';
                            }
                        } else {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        return false;
    }
}

WordPress Version: 1.4

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @uses PHPMailer
 *
 * @param string|array $to Array or comma-separated list of email addresses to send message.
 * @param string $subject Email subject
 * @param string $message Message contents
 * @param string|array $headers Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!is_object($phpmailer) || !is_a($phpmailer, 'PHPMailer')) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        if (strpos($content, '<') !== false) {
                            // So... making my life hard again?
                            $from_name = substr($content, 0, strpos($content, '<') - 1);
                            $from_name = str_replace('"', '', $from_name);
                            $from_name = trim($from_name);
                            $from_email = substr($content, strpos($content, '<') + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                        } else {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset));
                            } elseif (false !== stripos($charset, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset));
                                $charset = '';
                            }
                        } else {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        return false;
    }
}

WordPress Version: .37

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @uses PHPMailer
 *
 * @param string|array $to Array or comma-separated list of email addresses to send message.
 * @param string $subject Email subject
 * @param string $message Message contents
 * @param string|array $headers Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!is_object($phpmailer) || !is_a($phpmailer, 'PHPMailer')) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        if (strpos($content, '<') !== false) {
                            // So... making my life hard again?
                            $from_name = substr($content, 0, strpos($content, '<') - 1);
                            $from_name = str_replace('"', '', $from_name);
                            $from_name = trim($from_name);
                            $from_email = substr($content, strpos($content, '<') + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                        } else {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset));
                            } elseif (false !== stripos($charset, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset));
                                $charset = '';
                            }
                        } else {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        return false;
    }
}

WordPress Version: 4.1

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @uses PHPMailer
 *
 * @param string|array $to Array or comma-separated list of email addresses to send message.
 * @param string $subject Email subject
 * @param string $message Message contents
 * @param string|array $headers Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!is_object($phpmailer) || !is_a($phpmailer, 'PHPMailer')) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        if (strpos($content, '<') !== false) {
                            // So... making my life hard again?
                            $from_name = substr($content, 0, strpos($content, '<') - 1);
                            $from_name = str_replace('"', '', $from_name);
                            $from_name = trim($from_name);
                            $from_email = substr($content, strpos($content, '<') + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                        } else {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset));
                            } elseif (false !== stripos($charset, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset));
                                $charset = '';
                            }
                        } else {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        return false;
    }
}

WordPress Version: 0.4

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @uses PHPMailer
 *
 * @param string|array $to Array or comma-separated list of email addresses to send message.
 * @param string $subject Email subject
 * @param string $message Message contents
 * @param string|array $headers Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!is_object($phpmailer) || !is_a($phpmailer, 'PHPMailer')) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        if (strpos($content, '<') !== false) {
                            // So... making my life hard again?
                            $from_name = substr($content, 0, strpos($content, '<') - 1);
                            $from_name = str_replace('"', '', $from_name);
                            $from_name = trim($from_name);
                            $from_email = substr($content, strpos($content, '<') + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                        } else {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset));
                            } elseif (false !== stripos($charset, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset));
                                $charset = '';
                            }
                        } else {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * http://trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        return false;
    }
}

WordPress Version: .37

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @uses PHPMailer
 *
 * @param string|array $to Array or comma-separated list of email addresses to send message.
 * @param string $subject Email subject
 * @param string $message Message contents
 * @param string|array $headers Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!is_object($phpmailer) || !is_a($phpmailer, 'PHPMailer')) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        if (strpos($content, '<') !== false) {
                            // So... making my life hard again?
                            $from_name = substr($content, 0, strpos($content, '<') - 1);
                            $from_name = str_replace('"', '', $from_name);
                            $from_name = trim($from_name);
                            $from_email = substr($content, strpos($content, '<') + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                        } else {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset));
                            } elseif (false !== stripos($charset, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset));
                                $charset = '';
                            }
                        } else {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * http://trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        return false;
    }
}

WordPress Version: 4.0

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @uses PHPMailer
 *
 * @param string|array $to Array or comma-separated list of email addresses to send message.
 * @param string $subject Email subject
 * @param string $message Message contents
 * @param string|array $headers Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments'));
    if (isset($atts['to'])) {
        $to = $atts['to'];
    }
    if (isset($atts['subject'])) {
        $subject = $atts['subject'];
    }
    if (isset($atts['message'])) {
        $message = $atts['message'];
    }
    if (isset($atts['headers'])) {
        $headers = $atts['headers'];
    }
    if (isset($atts['attachments'])) {
        $attachments = $atts['attachments'];
    }
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!is_object($phpmailer) || !is_a($phpmailer, 'PHPMailer')) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        if (strpos($content, '<') !== false) {
                            // So... making my life hard again?
                            $from_name = substr($content, 0, strpos($content, '<') - 1);
                            $from_name = str_replace('"', '', $from_name);
                            $from_name = trim($from_name);
                            $from_email = substr($content, strpos($content, '<') + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                        } else {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset));
                            } elseif (false !== stripos($charset, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset));
                                $charset = '';
                            }
                        } else {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * http://trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        return false;
    }
}

WordPress Version: 3.9

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @uses PHPMailer
 *
 * @param string|array $to Array or comma-separated list of email addresses to send message.
 * @param string $subject Email subject
 * @param string $message Message contents
 * @param string|array $headers Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    extract(apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments')));
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!is_object($phpmailer) || !is_a($phpmailer, 'PHPMailer')) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        if (strpos($content, '<') !== false) {
                            // So... making my life hard again?
                            $from_name = substr($content, 0, strpos($content, '<') - 1);
                            $from_name = str_replace('"', '', $from_name);
                            $from_name = trim($from_name);
                            $from_email = substr($content, strpos($content, '<') + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                        } else {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset));
                            } elseif (false !== stripos($charset, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset));
                                $charset = '';
                            }
                        } else {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * http://trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        return false;
    }
}

WordPress Version: 3.8

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 * @uses apply_filters() Calls 'wp_mail' hook on an array of all of the parameters.
 * @uses apply_filters() Calls 'wp_mail_from' hook to get the from email address.
 * @uses apply_filters() Calls 'wp_mail_from_name' hook to get the from address name.
 * @uses apply_filters() Calls 'wp_mail_content_type' hook to get the email content type.
 * @uses apply_filters() Calls 'wp_mail_charset' hook to get the email charset
 * @uses do_action_ref_array() Calls 'phpmailer_init' hook on the reference to
 *		phpmailer object.
 * @uses PHPMailer
 *
 * @param string|array $to Array or comma-separated list of email addresses to send message.
 * @param string $subject Email subject
 * @param string $message Message contents
 * @param string|array $headers Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    extract(apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments')));
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!is_object($phpmailer) || !is_a($phpmailer, 'PHPMailer')) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        if (strpos($content, '<') !== false) {
                            // So... making my life hard again?
                            $from_name = substr($content, 0, strpos($content, '<') - 1);
                            $from_name = str_replace('"', '', $from_name);
                            $from_name = trim($from_name);
                            $from_email = substr($content, strpos($content, '<') + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                        } else {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset));
                            } elseif (false !== stripos($charset, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset));
                                $charset = '';
                            }
                        } else {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * http://trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    // Plugin authors can override the potentially troublesome default
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        return false;
    }
}

WordPress Version: 7.5

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 * @uses apply_filters() Calls 'wp_mail' hook on an array of all of the parameters.
 * @uses apply_filters() Calls 'wp_mail_from' hook to get the from email address.
 * @uses apply_filters() Calls 'wp_mail_from_name' hook to get the from address name.
 * @uses apply_filters() Calls 'wp_mail_content_type' hook to get the email content type.
 * @uses apply_filters() Calls 'wp_mail_charset' hook to get the email charset
 * @uses do_action_ref_array() Calls 'phpmailer_init' hook on the reference to
 *		phpmailer object.
 * @uses PHPMailer
 *
 * @param string|array $to Array or comma-separated list of email addresses to send message.
 * @param string $subject Email subject
 * @param string $message Message contents
 * @param string|array $headers Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    extract(apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments')));
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!is_object($phpmailer) || !is_a($phpmailer, 'PHPMailer')) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        if (strpos($content, '<') !== false) {
                            // So... making my life hard again?
                            $from_name = substr($content, 0, strpos($content, '<') - 1);
                            $from_name = str_replace('"', '', $from_name);
                            $from_name = trim($from_name);
                            $from_email = substr($content, strpos($content, '<') + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                        } else {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset));
                            } elseif (false !== stripos($charset, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset));
                                $charset = '';
                            }
                        } else {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAddresses();
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearBCCs();
    $phpmailer->ClearCCs();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * http://trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    // Plugin authors can override the potentially troublesome default
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        return false;
    }
}

WordPress Version: .40

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 * @uses apply_filters() Calls 'wp_mail' hook on an array of all of the parameters.
 * @uses apply_filters() Calls 'wp_mail_from' hook to get the from email address.
 * @uses apply_filters() Calls 'wp_mail_from_name' hook to get the from address name.
 * @uses apply_filters() Calls 'wp_mail_content_type' hook to get the email content type.
 * @uses apply_filters() Calls 'wp_mail_charset' hook to get the email charset
 * @uses do_action_ref_array() Calls 'phpmailer_init' hook on the reference to
 *		phpmailer object.
 * @uses PHPMailer
 *
 * @param string|array $to Array or comma-separated list of email addresses to send message.
 * @param string $subject Email subject
 * @param string $message Message contents
 * @param string|array $headers Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    extract(apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments')));
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!is_object($phpmailer) || !is_a($phpmailer, 'PHPMailer')) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        if (strpos($content, '<') !== false) {
                            // So... making my life hard again?
                            $from_name = substr($content, 0, strpos($content, '<') - 1);
                            $from_name = str_replace('"', '', $from_name);
                            $from_name = trim($from_name);
                            $from_email = substr($content, strpos($content, '<') + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                        } else {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset));
                            } elseif (false !== stripos($charset, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset));
                                $charset = '';
                            }
                        } else {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAddresses();
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearBCCs();
    $phpmailer->ClearCCs();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    $phpmailer->Body = '';
    $phpmailer->AltBody = '';
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * http://trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    // Plugin authors can override the potentially troublesome default
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        return false;
    }
}

WordPress Version: 3.7

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <[email protected]>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 * @uses apply_filters() Calls 'wp_mail' hook on an array of all of the parameters.
 * @uses apply_filters() Calls 'wp_mail_from' hook to get the from email address.
 * @uses apply_filters() Calls 'wp_mail_from_name' hook to get the from address name.
 * @uses apply_filters() Calls 'wp_mail_content_type' hook to get the email content type.
 * @uses apply_filters() Calls 'wp_mail_charset' hook to get the email charset
 * @uses do_action_ref_array() Calls 'phpmailer_init' hook on the reference to
 *		phpmailer object.
 * @uses PHPMailer
 *
 * @param string|array $to Array or comma-separated list of email addresses to send message.
 * @param string $subject Email subject
 * @param string $message Message contents
 * @param string|array $headers Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
{
    // Compact the input, apply the filters, and extract them back out
    extract(apply_filters('wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments')));
    if (!is_array($attachments)) {
        $attachments = explode("\n", str_replace("\r\n", "\n", $attachments));
    }
    global $phpmailer;
    // (Re)create it, if it's gone missing
    if (!is_object($phpmailer) || !is_a($phpmailer, 'PHPMailer')) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    // Headers
    if (empty($headers)) {
        $headers = array();
    } else {
        if (!is_array($headers)) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers));
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();
        // If it's actually got contents
        if (!empty($tempheaders)) {
            // Iterate through the raw headers
            foreach ((array) $tempheaders as $header) {
                if (strpos($header, ':') === false) {
                    if (false !== stripos($header, 'boundary=')) {
                        $parts = preg_split('/boundary=/i', trim($header));
                        $boundary = trim(str_replace(array("'", '"'), '', $parts[1]));
                    }
                    continue;
                }
                // Explode them out
                list($name, $content) = explode(':', trim($header), 2);
                // Cleanup crew
                $name = trim($name);
                $content = trim($content);
                switch (strtolower($name)) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        if (strpos($content, '<') !== false) {
                            // So... making my life hard again?
                            $from_name = substr($content, 0, strpos($content, '<') - 1);
                            $from_name = str_replace('"', '', $from_name);
                            $from_name = trim($from_name);
                            $from_email = substr($content, strpos($content, '<') + 1);
                            $from_email = str_replace('>', '', $from_email);
                            $from_email = trim($from_email);
                        } else {
                            $from_email = trim($content);
                        }
                        break;
                    case 'content-type':
                        if (strpos($content, ';') !== false) {
                            list($type, $charset) = explode(';', $content);
                            $content_type = trim($type);
                            if (false !== stripos($charset, 'charset=')) {
                                $charset = trim(str_replace(array('charset=', '"'), '', $charset));
                            } elseif (false !== stripos($charset, 'boundary=')) {
                                $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset));
                                $charset = '';
                            }
                        } else {
                            $content_type = trim($content);
                        }
                        break;
                    case 'cc':
                        $cc = array_merge((array) $cc, explode(',', $content));
                        break;
                    case 'bcc':
                        $bcc = array_merge((array) $bcc, explode(',', $content));
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim($name)] = trim($content);
                        break;
                }
            }
        }
    }
    // Empty out the values that may be set
    $phpmailer->ClearAddresses();
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearBCCs();
    $phpmailer->ClearCCs();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();
    // From email and name
    // If we don't have a name from the input headers
    if (!isset($from_name)) {
        $from_name = 'WordPress';
    }
    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * http://trac.wordpress.org/ticket/5007.
     */
    if (!isset($from_email)) {
        // Get the site domain and get rid of www.
        $sitename = strtolower($_SERVER['SERVER_NAME']);
        if (substr($sitename, 0, 4) == 'www.') {
            $sitename = substr($sitename, 4);
        }
        $from_email = 'wordpress@' . $sitename;
    }
    // Plugin authors can override the potentially troublesome default
    $phpmailer->From = apply_filters('wp_mail_from', $from_email);
    $phpmailer->FromName = apply_filters('wp_mail_from_name', $from_name);
    // Set destination addresses
    if (!is_array($to)) {
        $to = explode(',', $to);
    }
    foreach ((array) $to as $recipient) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
            $recipient_name = '';
            if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                if (count($matches) == 3) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress($recipient, $recipient_name);
        } catch (phpmailerException $e) {
            continue;
        }
    }
    // Set mail's subject and body
    $phpmailer->Subject = $subject;
    $phpmailer->Body = $message;
    // Add any CC and BCC recipients
    if (!empty($cc)) {
        foreach ((array) $cc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    if (!empty($bcc)) {
        foreach ((array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <[email protected]>"
                $recipient_name = '';
                if (preg_match('/(.*)<(.+)>/', $recipient, $matches)) {
                    if (count($matches) == 3) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc($recipient, $recipient_name);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    // Set to use PHP's mail()
    $phpmailer->IsMail();
    // Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if (!isset($content_type)) {
        $content_type = 'text/plain';
    }
    $content_type = apply_filters('wp_mail_content_type', $content_type);
    $phpmailer->ContentType = $content_type;
    // Set whether it's plaintext, depending on $content_type
    if ('text/html' == $content_type) {
        $phpmailer->IsHTML(true);
    }
    // If we don't have a charset from the input headers
    if (!isset($charset)) {
        $charset = get_bloginfo('charset');
    }
    // Set the content-type and charset
    $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
    // Set custom headers
    if (!empty($headers)) {
        foreach ((array) $headers as $name => $content) {
            $phpmailer->AddCustomHeader(sprintf('%1$s: %2$s', $name, $content));
        }
        if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
            $phpmailer->AddCustomHeader(sprintf("Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary));
        }
    }
    if (!empty($attachments)) {
        foreach ($attachments as $attachment) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch (phpmailerException $e) {
                continue;
            }
        }
    }
    do_action_ref_array('phpmailer_init', array(&$phpmailer));
    // Send!
    try {
        return $phpmailer->Send();
    } catch (phpmailerException $e) {
        return false;
    }
}