<?php

if (version_compare(PHP_VERSION, "5.0.0", "<")) {
    exit("Sorry, this version of PHPMailer will only run on PHP version 5 or greater!\n");
}
class phpmailerException extends Exception
{
    public function errorMessage()
    {
        $errorMsg = "<strong>" . $this->getMessage() . "</strong><br />\n";
        return $errorMsg;
    }
}
class PHPMailer
{
    public $Priority = 3;
    public $CharSet = "iso-8859-1";
    public $ContentType = "text/plain";
    public $Encoding = "8bit";
    public $ErrorInfo = "";
    public $From = "root@localhost";
    public $FromName = "Root User";
    public $Sender = "";
    public $Subject = "";
    public $Body = "";
    public $AltBody = "";
    public $WordWrap = 0;
    public $Mailer = "mail";
    public $Sendmail = "/usr/sbin/sendmail";
    public $PluginDir = "";
    public $ConfirmReadingTo = "";
    public $Hostname = "";
    public $MessageID = "";
    public $Host = "localhost";
    public $Port = 25;
    public $Helo = "";
    public $SMTPSecure = "";
    public $SMTPAuth = false;
    public $Username = "";
    public $Password = "";
    public $Timeout = 10;
    public $SMTPDebug = false;
    public $SMTPKeepAlive = false;
    public $SingleTo = false;
    public $SingleToArray = [];
    public $LE = "\n";
    public $DKIM_selector = "phpmailer";
    public $DKIM_identity = "";
    public $DKIM_domain = "";
    public $DKIM_private = "";
    public $action_function = "";
    public $Version = "5.1";
    private $smtp = NULL;
    private $to = [];
    private $cc = [];
    private $bcc = [];
    private $ReplyTo = [];
    private $all_recipients = [];
    private $attachment = [];
    private $CustomHeader = [];
    private $message_type = "";
    private $boundary = [];
    protected $language = [];
    private $error_count = 0;
    private $sign_cert_file = "";
    private $sign_key_file = "";
    private $sign_key_pass = "";
    private $exceptions = false;
    const STOP_MESSAGE = 0;
    const STOP_CONTINUE = 1;
    const STOP_CRITICAL = 2;
    public function __construct($exceptions = false)
    {
        $this->exceptions = $exceptions;
    }
    public function IsHTML($ishtml = true)
    {
        if ($ishtml) {
            $this->ContentType = "text/html";
        } else {
            $this->ContentType = "text/plain";
        }
    }
    public function IsSMTP()
    {
        $this->Mailer = "smtp";
    }
    public function IsMail()
    {
        $this->Mailer = "mail";
    }
    public function IsSendmail()
    {
        if (!stristr(ini_get("sendmail_path"), "sendmail")) {
            $this->Sendmail = "/var/qmail/bin/sendmail";
        }
        $this->Mailer = "sendmail";
    }
    public function IsQmail()
    {
        if (stristr(ini_get("sendmail_path"), "qmail")) {
            $this->Sendmail = "/var/qmail/bin/sendmail";
        }
        $this->Mailer = "sendmail";
    }
    public function AddAddress($address, $name = "")
    {
        return $this->AddAnAddress("to", $address, $name);
    }
    public function AddCC($address, $name = "")
    {
        return $this->AddAnAddress("cc", $address, $name);
    }
    public function AddBCC($address, $name = "")
    {
        return $this->AddAnAddress("bcc", $address, $name);
    }
    public function AddReplyTo($address, $name = "")
    {
        return $this->AddAnAddress("ReplyTo", $address, $name);
    }
    private function AddAnAddress($kind, $address, $name = "")
    {
        if (!preg_match("/^(to|cc|bcc|ReplyTo)\$/", $kind)) {
            echo "Invalid recipient array: " . kind;
            return false;
        }
        $address = trim($address);
        $name = trim(preg_replace("/[\\r\\n]+/", "", $name));
        if (!self::ValidateAddress($address)) {
            $this->SetError($this->Lang("invalid_address") . ": " . $address);
            if ($this->exceptions) {
                throw new phpmailerException($this->Lang("invalid_address") . ": " . $address);
            }
            echo $this->Lang("invalid_address") . ": " . $address;
            return false;
        }
        if ($kind != "ReplyTo") {
            if (!isset($this->all_recipients[strtolower($address)])) {
                array_push($this->{$kind}, [$address, $name]);
                $this->all_recipients[strtolower($address)] = true;
                return true;
            }
        } else {
            if (!array_key_exists(strtolower($address), $this->ReplyTo)) {
                $this->ReplyTo[strtolower($address)] = [$address, $name];
                return true;
            }
        }
        return false;
    }
    public function SetFrom($address, $name = "", $auto = 1)
    {
        $address = trim($address);
        $name = trim(preg_replace("/[\\r\\n]+/", "", $name));
        if (!self::ValidateAddress($address)) {
            $this->SetError($this->Lang("invalid_address") . ": " . $address);
            if ($this->exceptions) {
                throw new phpmailerException($this->Lang("invalid_address") . ": " . $address);
            }
            echo $this->Lang("invalid_address") . ": " . $address;
            return false;
        }
        $this->From = $address;
        $this->FromName = $name;
        if ($auto) {
            if (empty($this->ReplyTo)) {
                $this->AddAnAddress("ReplyTo", $address, $name);
            }
            if (empty($this->Sender)) {
                $this->Sender = $address;
            }
        }
        return true;
    }
    public static function ValidateAddress($address)
    {
        if (function_exists("filter_var")) {
            if (filter_var($address, FILTER_VALIDATE_EMAIL) === false) {
                return false;
            }
            return true;
        }
        return preg_match("/^(?:[\\w\\!\\#\\\$\\%\\&'\\*\\+\\-\\/\\=\\?\\^\\`\\{\\|\\}\\~]+\\.)*[\\w\\!\\#\\\$\\%\\&'\\*\\+\\-\\/\\=\\?\\^\\`\\{\\|\\}\\~]+@(?:(?:(?:[a-zA-Z0-9_](?:[a-zA-Z0-9_\\-](?!\\.)){0,61}[a-zA-Z0-9_-]?\\.)+[a-zA-Z0-9_](?:[a-zA-Z0-9_\\-](?!\$)){0,61}[a-zA-Z0-9_]?)|(?:\\[(?:(?:[01]?\\d{1,2}|2[0-4]\\d|25[0-5])\\.){3}(?:[01]?\\d{1,2}|2[0-4]\\d|25[0-5])\\]))\$/", $address);
    }
    public function Send()
    {
        try {
            if (count($this->to) + count($this->cc) + count($this->bcc) < 1) {
                throw new phpmailerException($this->Lang("provide_address"), 2);
            }
            if (!empty($this->AltBody)) {
                $this->ContentType = "multipart/alternative";
            }
            $this->error_count = 0;
            $this->SetMessageType();
            $header = $this->CreateHeader();
            $body = $this->CreateBody();
            if (empty($this->Body)) {
                throw new phpmailerException($this->Lang("empty_message"), 2);
            }
            if ($this->DKIM_domain && $this->DKIM_private) {
                $header_dkim = $this->DKIM_Add($header, $this->Subject, $body);
                $header = str_replace("\r\n", "\n", $header_dkim) . $header;
            }
            switch ($this->Mailer) {
                case "sendmail":
                    return $this->SendmailSend($header, $body);
                    break;
                case "smtp":
                    return $this->SmtpSend($header, $body);
                    break;
                default:
                    return $this->MailSend($header, $body);
            }
        } catch (phpmailerException $e) {
            $this->SetError($e->getMessage());
            if ($this->exceptions) {
                throw $e;
            }
            echo $e->getMessage() . "\n";
            return false;
        }
    }
    protected function SendmailSend($header, $body)
    {
        if ($this->Sender != "") {
            $sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
        } else {
            $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail));
        }
        if ($this->SingleTo === true) {
            foreach ($this->SingleToArray as $key => $val) {
                if (!($mail = @popen($sendmail, "w"))) {
                    throw new phpmailerException($this->Lang("execute") . $this->Sendmail, 2);
                }
                fputs($mail, "To: " . $val . "\n");
                fputs($mail, $header);
                fputs($mail, $body);
                $result = pclose($mail);
                $isSent = $result == 0 ? 1 : 0;
                $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body);
                if ($result != 0) {
                    throw new phpmailerException($this->Lang("execute") . $this->Sendmail, 2);
                }
            }
        } else {
            if (!($mail = @popen($sendmail, "w"))) {
                throw new phpmailerException($this->Lang("execute") . $this->Sendmail, 2);
            }
            fputs($mail, $header);
            fputs($mail, $body);
            $result = pclose($mail);
            $isSent = $result == 0 ? 1 : 0;
            $this->doCallback($isSent, $this->to, $this->cc, $this->bcc, $this->Subject, $body);
            if ($result != 0) {
                throw new phpmailerException($this->Lang("execute") . $this->Sendmail, 2);
            }
        }
        return true;
    }
    protected function MailSend($header, $body)
    {
        $toArr = [];
        foreach ($this->to as $t) {
            $toArr[] = $this->AddrFormat($t);
        }
        $to = implode(", ", $toArr);
        $params = sprintf("-oi -f %s", $this->Sender);
        if ($this->Sender != "" && strlen(ini_get("safe_mode")) < 1) {
            $old_from = ini_get("sendmail_from");
            ini_set("sendmail_from", $this->Sender);
            if ($this->SingleTo === true && 1 < count($toArr)) {
                foreach ($toArr as $key => $val) {
                    $rt = @mail($val, @$this->EncodeHeader(@$this->SecureHeader($this->Subject)), $body, $header, $params);
                    $isSent = $rt == 1 ? 1 : 0;
                    $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body);
                }
            } else {
                $rt = @mail($to, @$this->EncodeHeader(@$this->SecureHeader($this->Subject)), $body, $header, $params);
                $isSent = $rt == 1 ? 1 : 0;
                $this->doCallback($isSent, $to, $this->cc, $this->bcc, $this->Subject, $body);
            }
        } else {
            if ($this->SingleTo === true && 1 < count($toArr)) {
                foreach ($toArr as $key => $val) {
                    $rt = @mail($val, @$this->EncodeHeader(@$this->SecureHeader($this->Subject)), $body, $header, $params);
                    $isSent = $rt == 1 ? 1 : 0;
                    $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body);
                }
            } else {
                $rt = @mail($to, @$this->EncodeHeader(@$this->SecureHeader($this->Subject)), $body, $header);
                $isSent = $rt == 1 ? 1 : 0;
                $this->doCallback($isSent, $to, $this->cc, $this->bcc, $this->Subject, $body);
            }
        }
        if (isset($old_from)) {
            ini_set("sendmail_from", $old_from);
        }
        if (!$rt) {
            throw new phpmailerException($this->Lang("instantiate"), 2);
        }
        return true;
    }
    protected function SmtpSend($header, $body)
    {
        require_once $this->PluginDir . "class.smtp.php";
        $bad_rcpt = [];
        if (!$this->SmtpConnect()) {
            throw new phpmailerException($this->Lang("smtp_connect_failed"), 2);
        }
        $smtp_from = $this->Sender == "" ? $this->From : $this->Sender;
        if (!$this->smtp->Mail($smtp_from)) {
            throw new phpmailerException($this->Lang("from_failed") . $smtp_from, 2);
        }
        foreach ($this->to as $to) {
            if (!$this->smtp->Recipient($to[0])) {
                $bad_rcpt[] = $to[0];
                $isSent = 0;
                $this->doCallback($isSent, $to[0], "", "", $this->Subject, $body);
            } else {
                $isSent = 1;
                $this->doCallback($isSent, $to[0], "", "", $this->Subject, $body);
            }
        }
        foreach ($this->cc as $cc) {
            if (!$this->smtp->Recipient($cc[0])) {
                $bad_rcpt[] = $cc[0];
                $isSent = 0;
                $this->doCallback($isSent, "", $cc[0], "", $this->Subject, $body);
            } else {
                $isSent = 1;
                $this->doCallback($isSent, "", $cc[0], "", $this->Subject, $body);
            }
        }
        foreach ($this->bcc as $bcc) {
            if (!$this->smtp->Recipient($bcc[0])) {
                $bad_rcpt[] = $bcc[0];
                $isSent = 0;
                $this->doCallback($isSent, "", "", $bcc[0], $this->Subject, $body);
            } else {
                $isSent = 1;
                $this->doCallback($isSent, "", "", $bcc[0], $this->Subject, $body);
            }
        }
        if (0 < count($bad_rcpt)) {
            $badaddresses = implode(", ", $bad_rcpt);
            throw new phpmailerException($this->Lang("recipients_failed") . $badaddresses);
        }
        if (!$this->smtp->Data($header . $body)) {
            throw new phpmailerException($this->Lang("data_not_accepted"), 2);
        }
        if ($this->SMTPKeepAlive) {
            $this->smtp->Reset();
        }
        return true;
    }
    public function SmtpConnect()
    {
        while (is_null($this->smtp)) {
            $this->smtp = new SMTP();
        }
        $this->smtp->do_debug = $this->SMTPDebug;
        $hosts = explode(";", $this->Host);
        $index = 0;
        $connection = $this->smtp->Connected();
        while ($index < count($hosts) && !$connection) {
            try {
                $hostinfo = [];
                if (preg_match("/^(.+):([0-9]+)\$/", $hosts[$index], $hostinfo)) {
                    list($host, $port) = $hostinfo;
                } else {
                    $host = $hosts[$index];
                    $port = $this->Port;
                }
                $tls = $this->SMTPSecure == "tls";
                $ssl = $this->SMTPSecure == "ssl";
                if ($this->smtp->Connect(($ssl ? "ssl://" : "") . $host, $port, $this->Timeout)) {
                    $hello = $this->Helo != "" ? $this->Helo : $this->ServerHostname();
                    $this->smtp->Hello($hello);
                    if ($tls) {
                        if (!$this->smtp->StartTLS()) {
                            throw new phpmailerException($this->Lang("tls"));
                        }
                        $this->smtp->Hello($hello);
                    }
                    $connection = true;
                    if ($this->SMTPAuth && !$this->smtp->Authenticate($this->Username, $this->Password)) {
                        throw new phpmailerException($this->Lang("authenticate"));
                    }
                }
                $index++;
                if (!$connection) {
                    throw new phpmailerException($this->Lang("connect_host"));
                }
            } catch (phpmailerException $e) {
                $this->smtp->Reset();
                throw $e;
            }
        }
        return true;
    }
    public function SmtpClose()
    {
        if (!is_null($this->smtp) && $this->smtp->Connected()) {
            $this->smtp->Quit();
            $this->smtp->Close();
        }
    }
    public function SetLanguage($langcode = "en", $lang_path = "language/")
    {
        $PHPMAILER_LANG = ["provide_address" => "You must provide at least one recipient email address.", "mailer_not_supported" => " mailer is not supported.", "execute" => "Could not execute: ", "instantiate" => "Could not instantiate mail function.", "authenticate" => "SMTP Error: Could not authenticate.", "from_failed" => "The following From address failed: ", "recipients_failed" => "SMTP Error: The following recipients failed: ", "data_not_accepted" => "SMTP Error: Data not accepted.", "connect_host" => "SMTP Error: Could not connect to SMTP host.", "file_access" => "Could not access file: ", "file_open" => "File Error: Could not open file: ", "encoding" => "Unknown encoding: ", "signing" => "Signing Error: ", "smtp_error" => "SMTP server error: ", "empty_message" => "Message body empty", "invalid_address" => "Invalid address", "variable_set" => "Cannot set or reset variable: "];
        $l = true;
        if ($langcode != "en") {
            $l = (include $lang_path . "phpmailer.lang-" . $langcode . ".php");
        }
        $this->language = $PHPMAILER_LANG;
        return $l;
    }
    public function GetTranslations()
    {
        return $this->language;
    }
    public function AddrAppend($type, $addr)
    {
        $addr_str = $type . ": ";
        $addresses = [];
        foreach ($addr as $a) {
            $addresses[] = $this->AddrFormat($a);
        }
        $addr_str .= implode(", ", $addresses);
        $addr_str .= $this->LE;
        return $addr_str;
    }
    public function AddrFormat($addr)
    {
        if (empty($addr[1])) {
            return $this->SecureHeader($addr[0]);
        }
        return $this->EncodeHeader($this->SecureHeader($addr[1]), "phrase") . " <" . $this->SecureHeader($addr[0]) . ">";
    }
    public function WrapText($message, $length, $qp_mode = false)
    {
        $soft_break = $qp_mode ? sprintf(" =%s", $this->LE) : $this->LE;
        $is_utf8 = strtolower($this->CharSet) == "utf-8";
        $message = $this->FixEOL($message);
        if (substr($message, -1) == $this->LE) {
            $message = substr($message, 0, -1);
        }
        $line = explode($this->LE, $message);
        $message = "";
        for ($i = 0; $i < count($line); $i++) {
            $line_part = explode(" ", $line[$i]);
            $buf = "";
            for ($e = 0; $e < count($line_part); $e++) {
                $word = $line_part[$e];
                if ($qp_mode && $length < strlen($word)) {
                    $space_left = $length - strlen($buf) - 1;
                    if ($e != 0) {
                        if (20 < $space_left) {
                            $len = $space_left;
                            if ($is_utf8) {
                                $len = $this->UTF8CharBoundary($word, $len);
                            } else {
                                if (substr($word, $len - 1, 1) == "=") {
                                    $len--;
                                } else {
                                    if (substr($word, $len - 2, 1) == "=") {
                                        $len -= 2;
                                    }
                                }
                            }
                            $part = substr($word, 0, $len);
                            $word = substr($word, $len);
                            $buf .= " " . $part;
                            $message .= $buf . sprintf("=%s", $this->LE);
                        } else {
                            $message .= $buf . $soft_break;
                        }
                        $buf = "";
                        while (0 < strlen($word)) {
                        }
                    }
                    $len = $length;
                    if ($is_utf8) {
                        $len = $this->UTF8CharBoundary($word, $len);
                    } else {
                        if (substr($word, $len - 1, 1) == "=") {
                            $len--;
                        } else {
                            if (substr($word, $len - 2, 1) == "=") {
                                $len -= 2;
                            }
                        }
                    }
                    $part = substr($word, 0, $len);
                    $word = substr($word, $len);
                    if (0 < strlen($word)) {
                        $message .= $part . sprintf("=%s", $this->LE);
                    } else {
                        $buf = $part;
                    }
                } else {
                    $buf_o = $buf;
                    $buf .= $e == 0 ? $word : " " . $word;
                    if ($length < strlen($buf) && $buf_o != "") {
                        $message .= $buf_o . $soft_break;
                        $buf = $word;
                    }
                }
            }
            $message .= $buf . $this->LE;
        }
        return $message;
    }
    public function UTF8CharBoundary($encodedText, $maxLength)
    {
        $foundSplitPos = false;
        $lookBack = 3;
        while (!$foundSplitPos) {
            $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
            $encodedCharPos = strpos($lastChunk, "=");
            if ($encodedCharPos !== false) {
                $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
                $dec = hexdec($hex);
                if ($dec < 128) {
                    $maxLength = $encodedCharPos == 0 ? $maxLength : $maxLength - ($lookBack - $encodedCharPos);
                    $foundSplitPos = true;
                } else {
                    if (192 <= $dec) {
                        $maxLength = $maxLength - ($lookBack - $encodedCharPos);
                        $foundSplitPos = true;
                    } else {
                        if ($dec < 192) {
                            $lookBack += 3;
                        }
                    }
                }
            } else {
                $foundSplitPos = true;
            }
        }
        return $maxLength;
    }
    public function SetWordWrap()
    {
        if ($this->WordWrap < 1) {
            return NULL;
        }
        switch ($this->message_type) {
            case "alt":
            case "alt_attachments":
                $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap);
                break;
            default:
                $this->Body = $this->WrapText($this->Body, $this->WordWrap);
        }
    }
    public function CreateHeader()
    {
        $result = "";
        $uniq_id = md5(uniqid(time()));
        $this->boundary[1] = "b1_" . $uniq_id;
        $this->boundary[2] = "b2_" . $uniq_id;
        $result .= $this->HeaderLine("Date", self::RFCDate());
        if ($this->Sender == "") {
            $result .= $this->HeaderLine("Return-Path", trim($this->From));
        } else {
            $result .= $this->HeaderLine("Return-Path", trim($this->Sender));
        }
        if ($this->Mailer != "mail") {
            if ($this->SingleTo === true) {
                foreach ($this->to as $t) {
                    $this->SingleToArray[] = $this->AddrFormat($t);
                }
            } else {
                if (0 < count($this->to)) {
                    $result .= $this->AddrAppend("To", $this->to);
                } else {
                    if (count($this->cc) == 0) {
                        $result .= $this->HeaderLine("To", "undisclosed-recipients:;");
                    }
                }
            }
        }
        $from = [];
        $from[0][0] = trim($this->From);
        $from[0][1] = $this->FromName;
        $result .= $this->AddrAppend("From", $from);
        if (0 < count($this->cc)) {
            $result .= $this->AddrAppend("Cc", $this->cc);
        }
        if (($this->Mailer == "sendmail" || $this->Mailer == "mail") && 0 < count($this->bcc)) {
            $result .= $this->AddrAppend("Bcc", $this->bcc);
        }
        if (0 < count($this->ReplyTo)) {
            $result .= $this->AddrAppend("Reply-to", $this->ReplyTo);
        }
        if ($this->Mailer != "mail") {
            $result .= $this->HeaderLine("Subject", $this->EncodeHeader($this->SecureHeader($this->Subject)));
        }
        if ($this->MessageID != "") {
            $result .= $this->HeaderLine("Message-ID", $this->MessageID);
        } else {
            $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE);
        }
        $result .= $this->HeaderLine("X-Priority", $this->Priority);
        $result .= $this->HeaderLine("X-Mailer", "PHPMailer " . $this->Version . " (phpmailer.sourceforge.net)");
        if ($this->ConfirmReadingTo != "") {
            $result .= $this->HeaderLine("Disposition-Notification-To", "<" . trim($this->ConfirmReadingTo) . ">");
        }
        for ($index = 0; $index < count($this->CustomHeader); $index++) {
            $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), $this->EncodeHeader(trim($this->CustomHeader[$index][1])));
        }
        if (!$this->sign_key_file) {
            $result .= $this->HeaderLine("MIME-Version", "1.0");
            $result .= $this->GetMailMIME();
        }
        return $result;
    }
    public function GetMailMIME()
    {
        $result = "";
        switch ($this->message_type) {
            case "plain":
                $result .= $this->HeaderLine("Content-Transfer-Encoding", $this->Encoding);
                $result .= sprintf("Content-Type: %s; charset=\"%s\"", $this->ContentType, $this->CharSet);
                break;
            case "attachments":
            case "alt_attachments":
                if ($this->InlineImageExists()) {
                    $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", "multipart/related", $this->LE, $this->LE, $this->boundary[1], $this->LE);
                } else {
                    $result .= $this->HeaderLine("Content-Type", "multipart/mixed;");
                    $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . "\"");
                }
                break;
            case "alt":
                $result .= $this->HeaderLine("Content-Type", "multipart/alternative;");
                $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . "\"");
                break;
            default:
                if ($this->Mailer != "mail") {
                    $result .= $this->LE . $this->LE;
                }
                return $result;
        }
    }
    public function CreateBody()
    {
        $body = "";
        if ($this->sign_key_file) {
            $body .= $this->GetMailMIME();
        }
        $this->SetWordWrap();
        switch ($this->message_type) {
            case "alt":
                $body .= $this->GetBoundary($this->boundary[1], "", "text/plain", "");
                $body .= $this->EncodeString($this->AltBody, $this->Encoding);
                $body .= $this->LE . $this->LE;
                $body .= $this->GetBoundary($this->boundary[1], "", "text/html", "");
                $body .= $this->EncodeString($this->Body, $this->Encoding);
                $body .= $this->LE . $this->LE;
                $body .= $this->EndBoundary($this->boundary[1]);
                break;
            case "plain":
                $body .= $this->EncodeString($this->Body, $this->Encoding);
                break;
            case "attachments":
                $body .= $this->GetBoundary($this->boundary[1], "", "", "");
                $body .= $this->EncodeString($this->Body, $this->Encoding);
                $body .= $this->LE;
                $body .= $this->AttachAll();
                break;
            case "alt_attachments":
                $body .= sprintf("--%s%s", $this->boundary[1], $this->LE);
                $body .= sprintf("Content-Type: %s;%s\tboundary=\"%s\"%s", "multipart/alternative", $this->LE, $this->boundary[2], $this->LE . $this->LE);
                $body .= $this->GetBoundary($this->boundary[2], "", "text/plain", "") . $this->LE;
                $body .= $this->EncodeString($this->AltBody, $this->Encoding);
                $body .= $this->LE . $this->LE;
                $body .= $this->GetBoundary($this->boundary[2], "", "text/html", "") . $this->LE;
                $body .= $this->EncodeString($this->Body, $this->Encoding);
                $body .= $this->LE . $this->LE;
                $body .= $this->EndBoundary($this->boundary[2]);
                $body .= $this->AttachAll();
                break;
            default:
                if ($this->IsError()) {
                    $body = "";
                } else {
                    if ($this->sign_key_file) {
                        try {
                            $file = tempnam("", "mail");
                            file_put_contents($file, $body);
                            $signed = tempnam("", "signed");
                            if (@openssl_pkcs7_sign($file, $signed, "file://" . $this->sign_cert_file, ["file://" . $this->sign_key_file, $this->sign_key_pass], NULL)) {
                                @unlink($file);
                                @unlink($signed);
                                $body = file_get_contents($signed);
                            } else {
                                @unlink($file);
                                @unlink($signed);
                                throw new phpmailerException($this->Lang("signing") . openssl_error_string());
                            }
                        } catch (phpmailerException $e) {
                            $body = "";
                            if ($this->exceptions) {
                                throw $e;
                            }
                        }
                    }
                }
                return $body;
        }
    }
    private function GetBoundary($boundary, $charSet, $contentType, $encoding)
    {
        $result = "";
        if ($charSet == "") {
            $charSet = $this->CharSet;
        }
        if ($contentType == "") {
            $contentType = $this->ContentType;
        }
        if ($encoding == "") {
            $encoding = $this->Encoding;
        }
        $result .= $this->TextLine("--" . $boundary);
        $result .= sprintf("Content-Type: %s; charset = \"%s\"", $contentType, $charSet);
        $result .= $this->LE;
        $result .= $this->HeaderLine("Content-Transfer-Encoding", $encoding);
        $result .= $this->LE;
        return $result;
    }
    private function EndBoundary($boundary)
    {
        return $this->LE . "--" . $boundary . "--" . $this->LE;
    }
    private function SetMessageType()
    {
        if (count($this->attachment) < 1 && strlen($this->AltBody) < 1) {
            $this->message_type = "plain";
        } else {
            if (0 < count($this->attachment)) {
                $this->message_type = "attachments";
            }
            if (0 < strlen($this->AltBody) && count($this->attachment) < 1) {
                $this->message_type = "alt";
            }
            if (0 < strlen($this->AltBody) && 0 < count($this->attachment)) {
                $this->message_type = "alt_attachments";
            }
        }
    }
    public function HeaderLine($name, $value)
    {
        return $name . ": " . $value . $this->LE;
    }
    public function TextLine($value)
    {
        return $value . $this->LE;
    }
    public function AddAttachment($path, $name = "", $encoding = "base64", $type = "application/octet-stream")
    {
        try {
            if (!@is_file($path)) {
                throw new phpmailerException($this->Lang("file_access") . $path, 1);
            }
            $filename = basename($path);
            if ($name == "") {
                $name = $filename;
            }
            $this->attachment[] = [$path, $filename, $name, $encoding, $type, false, "attachment", 0];
        } catch (phpmailerException $e) {
            @$this->SetError(@$e->getMessage());
            if ($this->exceptions) {
                throw $e;
            }
            echo @$e->getMessage() . "\n";
            if (@$e->getCode() == 2) {
                return false;
            }
            return true;
        }
    }
    public function GetAttachments()
    {
        return $this->attachment;
    }
    private function AttachAll()
    {
        $mime = [];
        $cidUniq = [];
        $incl = [];
        foreach ($this->attachment as $attachment) {
            $bString = $attachment[5];
            if ($bString) {
                $string = $attachment[0];
            } else {
                $path = $attachment[0];
            }
            if (!in_array($attachment[0], $incl)) {
                list($incl[], $filename, $name, $encoding, $type, $disposition, $cid) = $attachment;
                if (!($disposition == "inline" && isset($cidUniq[$cid]))) {
                    $cidUniq[$cid] = true;
                    $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE);
                    $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $this->EncodeHeader($this->SecureHeader($name)), $this->LE);
                    $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE);
                    if ($disposition == "inline") {
                        $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE);
                    }
                    $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $this->EncodeHeader($this->SecureHeader($name)), $this->LE . $this->LE);
                    if ($bString) {
                        $mime[] = $this->EncodeString($string, $encoding);
                        if ($this->IsError()) {
                            return "";
                        }
                        $mime[] = $this->LE . $this->LE;
                    } else {
                        $mime[] = $this->EncodeFile($path, $encoding);
                        if ($this->IsError()) {
                            return "";
                        }
                        $mime[] = $this->LE . $this->LE;
                    }
                }
            }
        }
        $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE);
        return join("", $mime);
    }
    private function EncodeFile($path, $encoding = "base64")
    {
        try {
            if (!is_readable($path)) {
                throw new phpmailerException($this->Lang("file_open") . $path, 1);
            }
            if (function_exists("get_magic_quotes")) {
                function get_magic_quotes()
                {
                    return false;
                }
            }
            if (PHP_VERSION < 6) {
                $magic_quotes = get_magic_quotes_runtime();
                set_magic_quotes_runtime(0);
            }
            $file_buffer = file_get_contents($path);
            $file_buffer = $this->EncodeString($file_buffer, $encoding);
            if (PHP_VERSION < 6) {
                set_magic_quotes_runtime($magic_quotes);
            }
            return $file_buffer;
        } catch (Exception $e) {
            $this->SetError($e->getMessage());
            return "";
        }
    }
    public function EncodeString($str, $encoding = "base64")
    {
        $encoded = "";
        strtolower($encoding);
        switch (strtolower($encoding)) {
            case "base64":
                $encoded = chunk_split(base64_encode($str), 76, $this->LE);
                break;
            case "7bit":
            case "8bit":
                $encoded = $this->FixEOL($str);
                if (substr($encoded, -1 * strlen($this->LE)) != $this->LE) {
                    $encoded .= $this->LE;
                }
                break;
            case "binary":
                $encoded = $str;
                break;
            case "quoted-printable":
                $encoded = $this->EncodeQP($str);
                break;
            default:
                $this->SetError($this->Lang("encoding") . $encoding);
                return $encoded;
        }
    }
    public function EncodeHeader($str, $position = "text")
    {
        $x = 0;
        strtolower($position);
        switch (strtolower($position)) {
            case "phrase":
                if (!preg_match("/[\\200-\\377]/", $str)) {
                    $encoded = addcslashes($str, "\0..\37\\\"");
                    if ($str == $encoded && !preg_match("/[^A-Za-z0-9!#\$%&'*+\\/=?^_`{|}~ -]/", $str)) {
                        return $encoded;
                    }
                    return "\"" . $encoded . "\"";
                }
                $x = preg_match_all("/[^\\040\\041\\043-\\133\\135-\\176]/", $str, $matches);
                break;
            case "comment":
                $x = preg_match_all("/[()\"]/", $str, $matches);
                break;
            case "text":
            default:
                $x += preg_match_all("/[\\000-\\010\\013\\014\\016-\\037\\177-\\377]/", $str, $matches);
                if ($x == 0) {
                    return $str;
                }
                $maxlen = 68 - strlen($this->CharSet);
                if (strlen($str) / 3 < $x) {
                    $encoding = "B";
                    if (function_exists("mb_strlen") && $this->HasMultiBytes($str)) {
                        $encoded = $this->Base64EncodeWrapMB($str);
                    } else {
                        $encoded = base64_encode($str);
                        $maxlen -= $maxlen % 4;
                        $encoded = trim(chunk_split($encoded, $maxlen, "\n"));
                    }
                } else {
                    $encoding = "Q";
                    $encoded = $this->EncodeQ($str, $position);
                    $encoded = $this->WrapText($encoded, $maxlen, true);
                    $encoded = str_replace("=" . $this->LE, "\n", trim($encoded));
                }
                $encoded = preg_replace("/^(.*)\$/m", " =?" . $this->CharSet . "?" . $encoding . "?\\1?=", $encoded);
                $encoded = trim(str_replace("\n", $this->LE, $encoded));
                return $encoded;
        }
    }
    public function HasMultiBytes($str)
    {
        if (function_exists("mb_strlen")) {
            return mb_strlen($str, $this->CharSet) < strlen($str);
        }
        return false;
    }
    public function Base64EncodeWrapMB($str)
    {
        $start = "=?" . $this->CharSet . "?B?";
        $end = "?=";
        $encoded = "";
        $mb_length = mb_strlen($str, $this->CharSet);
        $length = 75 - strlen($start) - strlen($end);
        $ratio = $mb_length / strlen($str);
        $offset = $avgLength = floor($length * $ratio * 0);
        $i = 0;
        while ($i < $mb_length) {
            do {
                $lookBack = 0;
                $offset = $avgLength - $lookBack;
                $chunk = mb_substr($str, $i, $offset, $this->CharSet);
                $chunk = base64_encode($chunk);
                $lookBack++;
            } while ($length >= strlen($chunk));
            $encoded .= $chunk . $this->LE;
            $i += $offset;
        }
        $encoded = substr($encoded, 0, -1 * strlen($this->LE));
        return $encoded;
    }
    public function EncodeQPphp($input = "", $line_max = 76, $space_conv = false)
    {
        $hex = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];
        $lines = preg_split("/(?:\\r\\n|\\r|\\n)/", $input);
        $eol = "\r\n";
        $escape = "=";
        $output = "";
        while (list($line) = each($lines)) {
            $linlen = strlen($line);
            $newline = "";
            for ($i = 0; $i < $linlen; $i++) {
                $c = substr($line, $i, 1);
                $dec = ord($c);
                if ($i == 0 && $dec == 46) {
                    $c = "=2E";
                }
                if ($dec == 32) {
                    if ($i == $linlen - 1) {
                        $c = "=20";
                    } else {
                        if ($space_conv) {
                            $c = "=20";
                        }
                    }
                } else {
                    if ($dec == 61 || $dec < 32 || 126 < $dec) {
                        $h2 = floor($dec / 16);
                        $h1 = floor($dec % 16);
                        $c = $escape . $hex[$h2] . $hex[$h1];
                    }
                }
                if ($line_max <= strlen($newline) + strlen($c)) {
                    $output .= $newline . $escape . $eol;
                    $newline = "";
                    if ($dec == 46) {
                        $c = "=2E";
                    }
                }
                $newline .= $c;
            }
            $output .= $newline . $eol;
        }
        return $output;
    }
    public function EncodeQP($string, $line_max = 76, $space_conv = false)
    {
        if (function_exists("quoted_printable_encode")) {
            return quoted_printable_encode($string);
        }
        $filters = stream_get_filters();
        if (!in_array("convert.*", $filters)) {
            return $this->EncodeQPphp($string, $line_max, $space_conv);
        }
        $fp = fopen("php://temp/", "r+");
        $string = preg_replace("/\\r\\n?/", $this->LE, $string);
        $params = ["line-length" => $line_max, "line-break-chars" => $this->LE];
        $s = stream_filter_append($fp, "convert.quoted-printable-encode", STREAM_FILTER_READ, $params);
        fputs($fp, $string);
        rewind($fp);
        $out = stream_get_contents($fp);
        stream_filter_remove($s);
        $out = preg_replace("/^\\./m", "=2E", $out);
        fclose($fp);
        return $out;
    }
    public function EncodeQ($str, $position = "text")
    {
        $encoded = preg_replace("/[\\r\\n]*/", "", $str);
        strtolower($position);
        switch (strtolower($position)) {
            case "phrase":
                $encoded = preg_replace("/([^A-Za-z0-9!*+\\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
                break;
            case "comment":
                $encoded = preg_replace("/([\\(\\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
                break;
            case "text":
            default:
                $encoded = preg_replace("/([\\000-\\011\\013\\014\\016-\\037\\075\\077\\137\\177-\\377])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
                $encoded = str_replace(" ", "_", $encoded);
                return $encoded;
        }
    }
    public function AddStringAttachment($string, $filename, $encoding = "base64", $type = "application/octet-stream")
    {
        $this->attachment[] = [$string, $filename, basename($filename), $encoding, $type, true, "attachment", 0];
    }
    public function AddEmbeddedImage($path, $cid, $name = "", $encoding = "base64", $type = "application/octet-stream")
    {
        if (!@is_file($path)) {
            $this->SetError($this->Lang("file_access") . $path);
            return false;
        }
        $filename = basename($path);
        if ($name == "") {
            $name = $filename;
        }
        $this->attachment[] = [$path, $filename, $name, $encoding, $type, false, "inline", $cid];
        return true;
    }
    public function InlineImageExists()
    {
        foreach ($this->attachment as $attachment) {
            if ($attachment[6] == "inline") {
                return true;
            }
        }
        return false;
    }
    public function ClearAddresses()
    {
        foreach ($this->to as $to) {
            unset($this->all_recipients[strtolower($to[0])]);
        }
        $this->to = [];
    }
    public function ClearCCs()
    {
        foreach ($this->cc as $cc) {
            unset($this->all_recipients[strtolower($cc[0])]);
        }
        $this->cc = [];
    }
    public function ClearBCCs()
    {
        foreach ($this->bcc as $bcc) {
            unset($this->all_recipients[strtolower($bcc[0])]);
        }
        $this->bcc = [];
    }
    public function ClearReplyTos()
    {
        $this->ReplyTo = [];
    }
    public function ClearAllRecipients()
    {
        $this->to = [];
        $this->cc = [];
        $this->bcc = [];
        $this->all_recipients = [];
    }
    public function ClearAttachments()
    {
        $this->attachment = [];
    }
    public function ClearCustomHeaders()
    {
        $this->CustomHeader = [];
    }
    protected function SetError($msg)
    {
        $this->error_count++;
        if ($this->Mailer == "smtp" && !is_null($this->smtp)) {
            $lasterror = $this->smtp->getError();
            if (!empty($lasterror) && array_key_exists("smtp_msg", $lasterror)) {
                $msg .= "<p>" . $this->Lang("smtp_error") . $lasterror["smtp_msg"] . "</p>\n";
            }
        }
        $this->ErrorInfo = $msg;
    }
    public static function RFCDate()
    {
        $tz = date("Z");
        $tzs = $tz < 0 ? "-" : "+";
        $tz = abs($tz);
        $tz = (int) ($tz / 3600) * 100 + $tz % 3600 / 60;
        $result = sprintf("%s %s%04d", date("D, j M Y H:i:s"), $tzs, $tz);
        return $result;
    }
    private function ServerHostname()
    {
        if (!empty($this->Hostname)) {
            $result = $this->Hostname;
        } else {
            if (isset($_SERVER["SERVER_NAME"])) {
                $result = $_SERVER["SERVER_NAME"];
            } else {
                $result = "localhost.localdomain";
            }
        }
        return $result;
    }
    private function Lang($key)
    {
        if (count($this->language) < 1) {
            $this->SetLanguage("en");
        }
        if (isset($this->language[$key])) {
            return $this->language[$key];
        }
        return "Language string failed to load: " . $key;
    }
    public function IsError()
    {
        return 0 < $this->error_count;
    }
    private function FixEOL($str)
    {
        $str = str_replace("\r\n", "\n", $str);
        $str = str_replace("\r", "\n", $str);
        $str = str_replace("\n", $this->LE, $str);
        return $str;
    }
    public function AddCustomHeader($custom_header)
    {
        $this->CustomHeader[] = explode(":", $custom_header, 2);
    }
    public function MsgHTML($message, $basedir = "")
    {
        preg_match_all("/(src|background)=\"(.*)\"/Ui", $message, $images);
        if (isset($images[2])) {
            foreach ($images[2] as $i => $url) {
                if (!preg_match("#^[A-z]+://#", $url)) {
                    $filename = basename($url);
                    $directory = dirname($url);
                    if ($directory == ".") {
                        $directory = "";
                    } else {
                        $cid = "cid:" . md5($filename);
                        $ext = pathinfo($filename, PATHINFO_EXTENSION);
                        $mimeType = self::_mime_types($ext);
                        if (1 < strlen($basedir) && substr($basedir, -1) != "/") {
                            $basedir .= "/";
                        }
                        if (1 < strlen($directory) && substr($directory, -1) != "/") {
                            $directory .= "/";
                        }
                        if ($this->AddEmbeddedImage($basedir . $directory . $filename, md5($filename), $filename, "base64", $mimeType)) {
                            $message = preg_replace("/" . $images[1][$i] . "=\"" . preg_quote($url, "/") . "\"/Ui", $images[1][$i] . "=\"" . $cid . "\"", $message);
                        }
                    }
                }
            }
        }
        $this->IsHTML(true);
        $this->Body = $message;
        $textMsg = trim(strip_tags(preg_replace("/<(head|title|style|script)[^>]*>.*?<\\/\\1>/s", "", $message)));
        if (!empty($textMsg) && empty($this->AltBody)) {
            $this->AltBody = html_entity_decode($textMsg);
        }
        if (empty($this->AltBody)) {
            $this->AltBody = "To view this email message, open it in a program that understands HTML!\n\n";
        }
    }
    public static function _mime_types($ext = "")
    {
        $mimes = ["hqx" => "application/mac-binhex40", "cpt" => "application/mac-compactpro", "doc" => "application/msword", "bin" => "application/macbinary", "dms" => "application/octet-stream", "lha" => "application/octet-stream", "lzh" => "application/octet-stream", "exe" => "application/octet-stream", "class" => "application/octet-stream", "psd" => "application/octet-stream", "so" => "application/octet-stream", "sea" => "application/octet-stream", "dll" => "application/octet-stream", "oda" => "application/oda", "pdf" => "application/pdf", "ai" => "application/postscript", "eps" => "application/postscript", "ps" => "application/postscript", "smi" => "application/smil", "smil" => "application/smil", "mif" => "application/vnd.mif", "xls" => "application/vnd.ms-excel", "ppt" => "application/vnd.ms-powerpoint", "wbxml" => "application/vnd.wap.wbxml", "wmlc" => "application/vnd.wap.wmlc", "dcr" => "application/x-director", "dir" => "application/x-director", "dxr" => "application/x-director", "dvi" => "application/x-dvi", "gtar" => "application/x-gtar", "php" => "application/x-httpd-php", "php4" => "application/x-httpd-php", "php3" => "application/x-httpd-php", "phtml" => "application/x-httpd-php", "phps" => "application/x-httpd-php-source", "js" => "application/x-javascript", "swf" => "application/x-shockwave-flash", "sit" => "application/x-stuffit", "tar" => "application/x-tar", "tgz" => "application/x-tar", "xhtml" => "application/xhtml+xml", "xht" => "application/xhtml+xml", "zip" => "application/zip", "mid" => "audio/midi", "midi" => "audio/midi", "mpga" => "audio/mpeg", "mp2" => "audio/mpeg", "mp3" => "audio/mpeg", "aif" => "audio/x-aiff", "aiff" => "audio/x-aiff", "aifc" => "audio/x-aiff", "ram" => "audio/x-pn-realaudio", "rm" => "audio/x-pn-realaudio", "rpm" => "audio/x-pn-realaudio-plugin", "ra" => "audio/x-realaudio", "rv" => "video/vnd.rn-realvideo", "wav" => "audio/x-wav", "bmp" => "image/bmp", "gif" => "image/gif", "jpeg" => "image/jpeg", "jpg" => "image/jpeg", "jpe" => "image/jpeg", "png" => "image/png", "tiff" => "image/tiff", "tif" => "image/tiff", "css" => "text/css", "html" => "text/html", "htm" => "text/html", "shtml" => "text/html", "txt" => "text/plain", "text" => "text/plain", "log" => "text/plain", "rtx" => "text/richtext", "rtf" => "text/rtf", "xml" => "text/xml", "xsl" => "text/xml", "mpeg" => "video/mpeg", "mpg" => "video/mpeg", "mpe" => "video/mpeg", "qt" => "video/quicktime", "mov" => "video/quicktime", "avi" => "video/x-msvideo", "movie" => "video/x-sgi-movie", "word" => "application/msword", "xl" => "application/excel", "eml" => "message/rfc822"];
        return !isset($mimes[strtolower($ext)]) ? "application/octet-stream" : $mimes[strtolower($ext)];
    }
    public function set($name, $value = "")
    {
        try {
            if (isset($this->{$name})) {
                $this->{$name} = $value;
            } else {
                throw new phpmailerException($this->Lang("variable_set") . $name, 2);
            }
        } catch (Exception $e) {
            $this->SetError($e->getMessage());
            if ($e->getCode() == 2) {
                return false;
            }
            return true;
        }
    }
    public function SecureHeader($str)
    {
        $str = str_replace("\r", "", $str);
        $str = str_replace("\n", "", $str);
        return trim($str);
    }
    public function Sign($cert_filename, $key_filename, $key_pass)
    {
        $this->sign_cert_file = $cert_filename;
        $this->sign_key_file = $key_filename;
        $this->sign_key_pass = $key_pass;
    }
    public function DKIM_QP($txt)
    {
        $tmp = "";
        $line = "";
        for ($i = 0; $i < strlen($txt); $i++) {
            $ord = ord($txt[$i]);
            if (33 <= $ord && $ord <= 58 || $ord == 60 || 62 <= $ord && $ord <= 126) {
                $line .= $txt[$i];
            } else {
                $line .= "=" . sprintf("%02X", $ord);
            }
        }
        return $line;
    }
    public function DKIM_Sign($s)
    {
        $privKeyStr = file_get_contents($this->DKIM_private);
        if ($this->DKIM_passphrase != "") {
            $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase);
        } else {
            $privKey = $privKeyStr;
        }
        if (openssl_sign($s, $signature, $privKey)) {
            return base64_encode($signature);
        }
    }
    public function DKIM_HeaderC($s)
    {
        $s = preg_replace("/\r\n\\s+/", " ", $s);
        $lines = explode("\r\n", $s);
        foreach ($lines as $key => $line) {
            list($heading, $value) = explode(":", $line, 2);
            $heading = strtolower($heading);
            $value = preg_replace("/\\s+/", " ", $value);
            $lines[$key] = $heading . ":" . trim($value);
        }
        $s = implode("\r\n", $lines);
        return $s;
    }
    public function DKIM_BodyC($body)
    {
        if ($body == "") {
            return "\r\n";
        }
        $body = str_replace("\r\n", "\n", $body);
        $body = str_replace("\n", "\r\n", $body);
        while (substr($body, strlen($body) - 4, 4) == "\r\n\r\n") {
            $body = substr($body, 0, strlen($body) - 2);
        }
        return $body;
    }
    public function DKIM_Add($headers_line, $subject, $body)
    {
        $DKIMsignatureType = "rsa-sha1";
        $DKIMcanonicalization = "relaxed/simple";
        $DKIMquery = "dns/txt";
        $DKIMtime = time();
        $subject_header = "Subject: " . $subject;
        $headers = explode("\r\n", $headers_line);
        foreach ($headers as $header) {
            if (strpos($header, "From:") === 0) {
                $from_header = $header;
            } else {
                if (strpos($header, "To:") === 0) {
                    $to_header = $header;
                }
            }
        }
        $from = str_replace("|", "=7C", $this->DKIM_QP($from_header));
        $to = str_replace("|", "=7C", $this->DKIM_QP($to_header));
        $subject = str_replace("|", "=7C", $this->DKIM_QP($subject_header));
        $body = $this->DKIM_BodyC($body);
        $DKIMlen = strlen($body);
        $DKIMb64 = base64_encode(pack("H*", sha1($body)));
        $ident = $this->DKIM_identity == "" ? "" : " i=" . $this->DKIM_identity . ";";
        $dkimhdrs = "DKIM-Signature: v=1; a=" . $DKIMsignatureType . "; q=" . $DKIMquery . "; l=" . $DKIMlen . "; s=" . $this->DKIM_selector . ";\r\n" . "\tt=" . $DKIMtime . "; c=" . $DKIMcanonicalization . ";\r\n" . "\th=From:To:Subject;\r\n" . "\td=" . $this->DKIM_domain . ";" . $ident . "\r\n" . "\tz=" . $from . "\r\n" . "\t|" . $to . "\r\n" . "\t|" . $subject . ";\r\n" . "\tbh=" . $DKIMb64 . ";\r\n" . "\tb=";
        $toSign = $this->DKIM_HeaderC($from_header . "\r\n" . $to_header . "\r\n" . $subject_header . "\r\n" . $dkimhdrs);
        $signed = $this->DKIM_Sign($toSign);
        return "X-PHPMAILER-DKIM: phpmailer.worxware.com\r\n" . $dkimhdrs . $signed . "\r\n";
    }
    protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body)
    {
        if (!empty($this->action_function) && function_exists($this->action_function)) {
            $params = [$isSent, $to, $cc, $bcc, $subject, $body];
            call_user_func_array($this->action_function, $params);
        }
    }
}

?>