/**
  * Encode a given string to produce an encoded string.
  *
  * @param string  $string
  * @param int     $firstLineOffset if first line needs to be shorter
  * @param int     $maxLineLength   0 indicates the default length for this encoding
  *
  * @return string
  *
  * @throws RuntimeException
  */
 public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0)
 {
     if ($this->charset !== 'utf-8') {
         throw new RuntimeException(sprintf('Charset "%s" not supported. NativeQpContentEncoder only supports "utf-8"', $this->charset));
     }
     return $this->_standardize(quoted_printable_encode($string));
 }
Пример #2
0
 /**
  * Send an email with the UTF-8 character set
  * @param  string $to
  * @param  string $subject
  * @param  string $body     The HTML body part
  * @param  string $text     The plaintext body part (optional)
  * @return bool
  */
 protected function _utf8mail($to, $subject, $body, $text = null)
 {
     $f3 = \Base::instance();
     // Add basic headers
     $headers = 'MIME-Version: 1.0' . "\r\n";
     $headers .= 'To: ' . $to . "\r\n";
     $headers .= 'From: ' . $f3->get("mail.from") . "\r\n";
     // Build multipart message if necessary
     if ($text) {
         // Generate message breaking hash
         $hash = md5(date("r"));
         $headers .= "Content-type: multipart/alternative; boundary=\"{$hash}\"\r\n";
         // Normalize line endings
         $body = str_replace("\r\n", "\n", $body);
         $body = str_replace("\n", "\r\n", $body);
         $text = str_replace("\r\n", "\n", $text);
         $text = str_replace("\n", "\r\n", $text);
         // Build final message
         $msg = "--{$hash}\r\n";
         $msg .= "Content-type: text/plain; charset=utf-8\r\n";
         $msg .= "Content-Transfer-Encoding: quoted-printable\r\n";
         $msg .= "\r\n" . quoted_printable_encode($text) . "\r\n";
         $msg .= "--{$hash}\r\n";
         $msg .= "Content-type: text/html; charset=utf-8\r\n";
         $msg .= "Content-Transfer-Encoding: quoted-printable\r\n";
         $msg .= "\r\n" . quoted_printable_encode($body) . "\r\n";
         $msg .= "--{$hash}\r\n";
         $body = $msg;
     } else {
         $headers .= "Content-type: text/html; charset=utf-8\r\n";
     }
     return mail($to, $subject, $body, $headers);
 }
Пример #3
0
 public function sendmail($to, $from, $subject = "", $body = "", $mailtype, $cc = "", $bcc = "", $additional_headers = "")
 {
     $mail_from = $this->get_address($this->strip_comment($from));
     $body = preg_replace("/(^|(\r\n))(\\.)/", ".", $body);
     //$body = mb_encode_mimeheader($body, "utf-8", "B");
     $body = quoted_printable_encode($body);
     @($header .= "MIME-Version:1.0\r\n");
     if ($mailtype == "HTML") {
         $header .= "Content-Type:text/html; charset=utf-8\r\n";
         //$header .= "Content-Transfer-Encoding: base64\r\n";
         $header .= "Content-Transfer-Encoding: quoted-printable\r\n";
     }
     $header .= "To: " . $to . "\r\n";
     if ($cc != "") {
         $header .= "Cc: " . $cc . "\r\n";
     }
     //$header .= "From: $from<".$from.">\r\n";
     $header .= "From: {$this->custom_from_name} <" . $this->custom_from_address . ">\r\n";
     $header .= "Subject: " . "=?UTF-8?B?" . base64_encode($subject) . "?=" . "\r\n";
     $header .= $additional_headers;
     $header .= "Date: " . date("r") . "\r\n";
     $header .= "X-Mailer:By Redhat (PHP/" . phpversion() . ")\r\n";
     list($msec, $sec) = explode(" ", microtime());
     $header .= "Message-ID: <" . date("YmdHis", $sec) . "." . $msec * 1000000 . "." . $mail_from . ">\r\n";
     $TO = explode(",", $this->strip_comment($to));
     if ($cc != "") {
         $TO = array_merge($TO, explode(",", $this->strip_comment($cc)));
     }
     if ($bcc != "") {
         $TO = array_merge($TO, explode(",", $this->strip_comment($bcc)));
     }
     $sent = TRUE;
     $sent_address = array();
     foreach ($TO as $rcpt_to) {
         $rcpt_to = $this->get_address($rcpt_to);
         $address_hash_sum = sha1($rcpt_to);
         if (isset($sent_addresses[$address_hash_sum])) {
             $this->log_write("Warning: Already sent to {$rcpt_to}\n");
             continue;
         }
         if (!$this->smtp_sockopen($rcpt_to)) {
             $this->log_write("Error: Cannot send email to " . $rcpt_to . "\n");
             $sent = FALSE;
             continue;
         }
         if ($this->smtp_send($this->host_name, $mail_from, $rcpt_to, $header, $body)) {
             $this->log_write("E-mail has been sent to <" . $rcpt_to . ">\n");
             $sent_addresses[$address_hash_sum] = 1;
         } else {
             $this->log_write("Error: Cannot send email to <" . $rcpt_to . ">\n");
             $sent = TRUE;
             //忽略离职
         }
         fclose($this->sock);
         $this->log_write("Disconnected from remote host\n");
     }
     return $sent;
 }
Пример #4
0
 /**
  * Test decoding of header values
  * Uses rcube_mime::decode_mime_string()
  */
 function test_header_decode_qp()
 {
     $test = array('quoted-printable (1)' => array('in' => '=?utf-8?Q?Certifica=C3=A7=C3=A3??=', 'out' => 'Certifica=C3=A7=C3=A3?'), 'quoted-printable (2)' => array('in' => '=?utf-8?Q?Certifica=?= =?utf-8?Q?C3=A7=C3=A3?=', 'out' => 'Certifica=C3=A7=C3=A3'), 'quoted-printable (3)' => array('in' => '=?utf-8?Q??= =?utf-8?Q??=', 'out' => ''), 'quoted-printable (4)' => array('in' => '=?utf-8?Q??= a =?utf-8?Q??=', 'out' => ' a '), 'quoted-printable (5)' => array('in' => '=?utf-8?Q?a?= =?utf-8?Q?b?=', 'out' => 'ab'), 'quoted-printable (6)' => array('in' => '=?utf-8?Q?   ?= =?utf-8?Q?a?=', 'out' => '   a'), 'quoted-printable (7)' => array('in' => '=?utf-8?Q?___?= =?utf-8?Q?a?=', 'out' => '   a'));
     foreach ($test as $idx => $item) {
         $res = rcube_mime::decode_mime_string($item['in'], 'UTF-8');
         $res = quoted_printable_encode($res);
         $this->assertEquals($item['out'], $res, "Header decoding for: " . $idx);
     }
 }
 /**
  * @test
  */
 public function it_decodes_a_quoted_printable_string_when_encoding_is_set()
 {
     $decoder = new MessageDecoder();
     // Let's use all Latin-1 chars.
     $chars = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ';
     $qp = quoted_printable_encode($chars);
     $decoded = $decoder->decodeBody($qp, ENCQUOTEDPRINTABLE);
     $this->assertEquals($chars, $decoded);
 }
Пример #6
0
 function send($mail)
 {
     $headers = "MIME-Version: 1.0\r\n";
     $headers .= "Content-Type: text/html;charset=utf-8\r\n";
     $headers .= "Content-Transfer-Encoding: quoted-printable\r\n";
     $headers .= "To: {$address}\r\n";
     $headers .= 'From: =?UTF-8?B?' . base64_encode('贴吧签到助手') . "?=\r\n";
     $message = quoted_printable_encode($message);
     return mail($mail->address, '=?UTF-8?B?' . base64_encode($mail->subject) . '?=', $mail->message, $headers);
 }
Пример #7
0
function send_email($to, $subject, $message, $from = '')
{
    $headers = array();
    $headers[] = 'MIME-Version: 1.0';
    $headers[] = 'Content-type: text/html; charset=UTF-8';
    $headers[] = 'Content-Transfer-Encoding: quoted-printable';
    $headers[] = "From: {$from}";
    $email_message = quoted_printable_encode($message);
    return mail($to, $subject, $email_message, implode("\n", $headers), '-f' . $from);
}
Пример #8
0
 /**
  * @ignore
  */
 public function compileBody()
 {
     $tString = "";
     if ($this->transferEncoding === 'base64') {
         $tString .= chunk_split(base64_encode($this->content));
     } elseif ($this->transferEncoding === 'quoted-printable') {
         $tString .= quoted_printable_encode($this->content);
     } else {
         $tString .= $this->content;
     }
     return $tString;
 }
Пример #9
0
 /**
  * Takes a transformed body and turns it into the raw body string needed for the mime encoding.
  *
  * @param $transformedBody
  */
 public final function setTransformedBody($transformedBody)
 {
     $encoding = isset($this->headers["Content-Transfer-Encoding"]) ? $this->headers["Content-Transfer-Encoding"] : "";
     switch ($encoding) {
         case "quoted-printable":
             $this->setRawBody(quoted_printable_encode($transformedBody));
             break;
         case "base64":
             $this->setRawBody(chunk_split(base64_encode($transformedBody), 76));
             break;
         default:
             $this->setRawBody($transformedBody);
     }
 }
Пример #10
0
 private function sendMail($text)
 {
     if ($this->config['enable_mailer'] === true) {
         $sender = $this->config['sender'];
         $receiver = $this->config['receiver'];
         $subject = $this->config['subject'];
         $boundary = $this->mailer->generateBoundary();
         $text = quoted_printable_encode($text);
         $message = "\n--{$boundary}\n";
         $message .= "Content-Type: text/plain; charset=UTF-8\n";
         $message .= "Content-Transfer-Encoding: quoted-printable\n\n";
         $message .= "{$text}\n\n";
         $message .= "--{$boundary}--\n";
         $this->mailer->send($sender, $receiver, $subject, $message, $boundary);
     }
 }
Пример #11
0
 public function sendmail($to, $subject = "", $body = "", $mailtype, $cc = "", $bcc = "", $additional_headers = "")
 {
     $mail_from = $this->get_address($this->strip_comment($this->email));
     $body = ereg_replace("(^|(\r\n))(\\.)", ".", $body);
     $header .= "MIME-Version:1.0\r\n";
     if ($mailtype == "HTML") {
         $header .= "Content-Type:text/html;charset=" . $this->charset . "\r\n";
         $header .= "Content-Transfer-Encoding: quoted-printable\r\n";
         $body = quoted_printable_encode($body);
     }
     $header .= "To: " . $to . "\r\n";
     if ($cc != "") {
         $header .= "Cc: " . $cc . "\r\n";
     }
     $header .= "From: " . $this->getCharset($this->name) . " <" . $this->email . ">\r\n";
     $header .= "Subject: " . $this->getCharset($subject) . "\r\n";
     $header .= $additional_headers;
     $header .= "Date: " . date("r") . "\r\n";
     list($msec, $sec) = explode(" ", microtime());
     $header .= "Message-ID: <" . date("YmdHis", $sec) . "." . $msec * 1000000 . "." . $this->email . ">\r\n";
     $header .= "Return-Path: <" . $this->email . ">\r\n";
     $TO = explode(",", $this->strip_comment($to));
     if ($cc != "") {
         $TO = array_merge($TO, explode(",", $this->strip_comment($cc)));
     }
     if ($bcc != "") {
         $TO = array_merge($TO, explode(",", $this->strip_comment($bcc)));
     }
     $sent = TRUE;
     foreach ($TO as $rcpt_to) {
         $rcpt_to = $this->get_address($rcpt_to);
         if (!$this->smtp_sockopen($rcpt_to)) {
             $this->log_write("Error: Cannot send email to " . $rcpt_to . "\n");
             $sent = FALSE;
             continue;
         }
         if ($this->smtp_send($this->relay_host, $mail_from, $rcpt_to, $header, $body)) {
             $this->log_write("E-mail has been sent to <" . $rcpt_to . ">\n");
         } else {
             $this->log_write("Error: Cannot send email to <" . $rcpt_to . ">\n");
             $sent = FALSE;
         }
         fclose($this->sock);
         $this->log_write("Disconnected from remote host\n");
     }
     return $sent;
 }
Пример #12
0
function gs_keyval_enc($str)
{
    /*
    return str_replace(' ', '=20',
    	quoted_printable_encode($str, false));
    */
    $str = quoted_printable_encode($str, false);
    # encode trailing spaces:
    do {
        $str = preg_replace('/ ( *)$/', '=20$1', $str, -1, $cnt);
    } while ($cnt > 0);
    # encode leading spaces:
    do {
        $str = preg_replace('/^( *) /', '$1=20', $str, -1, $cnt);
    } while ($cnt > 0);
    return $str;
}
Пример #13
0
function email_encode($String = '', $Caracteres = 'ISO-8859-1')
{
    // Quoted-printed (Q)
    if (function_exists('quoted_printable_encode')) {
        $String = quoted_printable_encode($String);
        $RT = '=?' . $Caracteres . '?Q?' . $String . '?=';
    } else {
        // IMAP 8bit (Q)
        if (function_exists('imap_8bit')) {
            $String = imap_8bit($String);
            $RT = '=?' . $Caracteres . '?Q?' . $String . '?=';
        } else {
            $String = base64_encode($String);
            $RT = '=?' . $Caracteres . '?B?' . $String . '?=';
        }
    }
    return $RT;
}
Пример #14
0
 public static function parse($mimetype, $encoding, $body, $charset = "UTF-8")
 {
     $header = new RFC5322Header();
     $header->setValue("Content-Type", $mimetype);
     $header->get("Content-Type")->addExtra("charset", $charset);
     $header->setValue("Content-Transfer-Encoding", $encoding);
     switch ($encoding) {
         case "7bit":
         case "8bit":
         case "binary":
             // Keine weitere Kodierung gewuenscht!
             break;
         case "base64":
             $body = chunk_split(base64_encode($body), 76, "\r\n");
             break;
         case "quoted-printable":
             $body = quoted_printable_encode($body);
             break;
     }
     return new RFC5322PlainBody($header, $body);
 }
Пример #15
0
 public function send()
 {
     $uid = md5(uniqid(time()));
     $headers = [];
     if ($this->from) {
         $headers[] = 'From: ' . $this->from;
     }
     if ($this->replyTo) {
         $headers[] = 'Reply-To: ' . $this->replyTo;
     }
     $headers[] = 'MIME-Version: 1.0';
     $headers[] = "Content-Type: multipart/mixed; boundary=\"" . $uid . "\"";
     $headers[] = "This is a multi-part message in MIME format.";
     $headers[] = "--{$uid}";
     $headers[] = "Content-type: text/html; charset=UTF-8";
     $headers[] = "Content-Transfer-Encoding: quoted-printable";
     $headers[] = '';
     $headers[] = quoted_printable_encode($this->message);
     $headers[] = '';
     foreach ($this->attachments as $file) {
         $name = basename($file);
         $headers[] = "--{$uid}";
         $headers[] = "Content-type: application/octet-stream; name=\"" . $name . "\"";
         $headers[] = "Content-Transfer-Encoding: base64";
         $headers[] = "Content-Disposition: attachment; filename=\"" . $name . "\"";
         $headers[] = '';
         $headers[] = chunk_split(base64_encode(file_get_contents($file)));
         $headers[] = '';
     }
     $headers[] = "--{$uid}--";
     $success = true;
     foreach ($this->recipients as $to) {
         $body = implode("\r\n", $headers);
         $success = mail($to, $this->subject, '', $body);
         Event::trigger('core.email.send', $to, $this->from, $this->subject, $body, $success);
         $success = $success && $success;
     }
     return $success;
 }
Пример #16
0
 /**
  * Encode plain array to TSV with $encoding.
  *
  * @param  array $data Array data to encode
  * @param  mixed $encoding Encode type
  * @access public
  * @return String Encoded string
  */
 public function encodeTsvrpc(array $data, $encoding = null)
 {
     $encoders = array('U' => function ($value) {
         return urlencode($value);
     }, 'Q' => function ($value) {
         return quoted_printable_encode($value);
     }, 'B' => function ($value) {
         return base64_encode($value);
     });
     if (isset($encoders[$encoding])) {
         $encoder = $encoders[$encoding];
     } else {
         // When $encoding is not in $encoders, nothing to do.
         $encoder = function ($value) {
             return $value;
         };
     }
     $res = array();
     foreach ($data as $k => $v) {
         $res[] = $encoder($k) . "\t" . $encoder($v);
     }
     return implode("\n", $res);
 }
Пример #17
0
 public function renderMessage()
 {
     $html = $this->renderHtml();
     $text = $this->renderText();
     $body = '';
     if ($text != null && $text != '' && $html != null && $html != '') {
         $body .= "------mail-boundary----\r\n";
         $body .= "Content-Type: text/plain\r\n";
         $body .= "Content-Transfer-Encoding: quoted-printable\r\n";
         $body .= quoted_printable_encode($text) . "\r\n";
         $body .= "------mail-boundary----\r\n";
         $body .= "Content-Type: text/html\r\n";
         $body .= "Content-Transfer-Encoding: quoted-printable\r\n";
         $body .= quoted_printable_encode($html) . "\r\n";
         $body .= "------mail-boundary------";
     } else {
         $body .= $html != null ? $html : $text;
     }
     if ($body == null || trim($body) == '') {
         throw new \Exception("No content type templates for mailer view " . $this->view);
     }
     return $body;
 }
Пример #18
0
 /**
  * Renders an unfolded line
  *
  * @return string
  */
 public function toLine()
 {
     // Property-name
     $line = $this->getName();
     $value = $this->value;
     if (false !== strpos($value, "\n")) {
         $this->params['ENCODING'] = 'QUOTED-PRINTABLE';
         $value = quoted_printable_encode($value);
         $value = strtr($value, array("\r" => "", "\n" => ""));
     }
     // Adding params
     foreach ($this->params as $param => $paramValues) {
         if (!is_array($paramValues)) {
             $paramValues = array($paramValues);
         }
         foreach ($paramValues as $k => $v) {
             $paramValues[$k] = $this->escapeParamValue($v);
         }
         $line .= ';' . $param . '=' . implode(',', $paramValues);
     }
     // Property value
     $line .= ':' . $value;
     return $line;
 }
Пример #19
0
<?php

var_dump(quoted_printable_encode());
var_dump(quoted_printable_encode(""));
var_dump(quoted_printable_encode("test"));
var_dump(quoted_printable_encode("test", "more"));
$a = array("str");
var_dump(quoted_printable_encode($a));
var_dump(quoted_printable_encode(1));
var_dump(quoted_printable_encode(NULL));
var_dump(quoted_printable_encode(false));
echo "Done\n";
Пример #20
0
 /**
  * Encode a string in quoted-printable format.
  * According to RFC2045 section 6.7.
  * @access public
  * @param string $string The text to encode
  * @param integer $line_max Number of chars allowed on a line before wrapping
  * @return string
  * @link http://www.php.net/manual/en/function.quoted-printable-decode.php#89417 Adapted from this comment
  */
 public function encodeQP($string, $line_max = 76)
 {
     // Use native function if it's available (>= PHP5.3)
     if (function_exists('quoted_printable_encode')) {
         return quoted_printable_encode($string);
     }
     // Fall back to a pure PHP implementation
     $string = str_replace(array('%20', '%0D%0A.', '%0D%0A', '%'), array(' ', "\r\n=2E", "\r\n", '='), rawurlencode($string));
     return preg_replace('/[^\\r\\n]{' . ($line_max - 3) . '}[^=\\r\\n]{2}/', "\$0=\r\n", $string);
 }
Пример #21
0
 /**
  * Encode string to RFC2045 (6.7) quoted-printable format
  * Uses a PHP5 stream filter to do the encoding about 64x faster than the old version
  * Also results in same content as you started with after decoding
  * @see EncodeQPphp()
  * @access public
  * @param string $string the text to encode
  * @param integer $line_max Number of chars allowed on a line before wrapping
  * @param boolean $space_conv Dummy param for compatibility with existing EncodeQP function
  * @return string
  * @author Marcus Bointon
  */
 public function EncodeQP($string, $line_max = 76, $space_conv = false)
 {
     if (function_exists('quoted_printable_encode')) {
         //Use native function if it's available (>= PHP5.3)
         return quoted_printable_encode($string);
     }
     $filters = stream_get_filters();
     if (!in_array('convert.*', $filters)) {
         //Got convert stream filter?
         return $this->EncodeQPphp($string, $line_max, $space_conv);
         //Fall back to old implementation
     }
     $fp = fopen('php://temp/', 'r+');
     $string = preg_replace('/\\r\\n?/', $this->LE, $string);
     //Normalise line breaks
     $params = array('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);
     //Encode . if it is first char on a line, workaround for bug in Exchange
     fclose($fp);
     return $out;
 }
Пример #22
0
 /**
  * @unused
  *
  * @param string $sEncodeType
  * @param string $sEncodeCharset
  * @param string $sValue
  *
  * @return string
  */
 public static function EncodeHeaderValue($sEncodeType, $sEncodeCharset, $sValue)
 {
     $sValue = \trim($sValue);
     if (0 < \strlen($sValue) && !\MailSo\Base\Utils::IsAscii($sValue)) {
         switch (\strtoupper($sEncodeType)) {
             case 'B':
                 $sValue = '=?' . \strtolower($sEncodeCharset) . '?B?' . \base64_encode($sValue) . '?=';
                 break;
             case 'Q':
                 $sValue = '=?' . \strtolower($sEncodeCharset) . '?Q?' . \str_replace(array('?', ' ', '_'), array('=3F', '_', '=5F'), \quoted_printable_encode($sValue)) . '?=';
                 break;
         }
     }
     return \trim($sValue);
 }
Пример #23
0
 /**
  *	Transmit message
  *	@return bool
  *	@param $message string
  *	@param $log bool
  **/
 function send($message, $log = TRUE)
 {
     if ($this->scheme == 'ssl' && !extension_loaded('openssl')) {
         return FALSE;
     }
     // Message should not be blank
     if (!$message) {
         user_error(self::E_Blank);
     }
     $fw = Base::instance();
     // Retrieve headers
     $headers = $this->headers;
     // Connect to the server
     $socket =& $this->socket;
     $socket = @fsockopen($this->host, $this->port);
     if (!$socket) {
         return FALSE;
     }
     stream_set_blocking($socket, TRUE);
     // Get server's initial response
     $this->dialog(NULL, FALSE);
     // Announce presence
     $reply = $this->dialog('EHLO ' . $fw->get('HOST'), $log);
     if (strtolower($this->scheme) == 'tls') {
         $this->dialog('STARTTLS', $log);
         stream_socket_enable_crypto($socket, TRUE, STREAM_CRYPTO_METHOD_TLS_CLIENT);
         $reply = $this->dialog('EHLO ' . $fw->get('HOST'), $log);
         if (preg_match('/8BITMIME/', $reply)) {
             $headers['Content-Transfer-Encoding'] = '8bit';
         } else {
             $headers['Content-Transfer-Encoding'] = 'quoted-printable';
             $message = quoted_printable_encode($message);
         }
     }
     if ($this->user && $this->pw && preg_match('/AUTH/', $reply)) {
         // Authenticate
         $this->dialog('AUTH LOGIN', $log);
         $this->dialog(base64_encode($this->user), $log);
         $this->dialog(base64_encode($this->pw), $log);
     }
     // Required headers
     $reqd = array('From', 'To', 'Subject');
     foreach ($reqd as $id) {
         if (empty($headers[$id])) {
             user_error(sprintf(self::E_Header, $id));
         }
     }
     $eol = "\r\n";
     $str = '';
     // Stringify headers
     foreach ($headers as $key => $val) {
         if (!in_array($key, $reqd)) {
             $str .= $key . ': ' . $val . $eol;
         }
     }
     // Start message dialog
     $this->dialog('MAIL FROM: ' . strstr($headers['From'], '<'), $log);
     foreach ($fw->split($headers['To'] . (isset($headers['Cc']) ? ';' . $headers['Cc'] : '') . (isset($headers['Bcc']) ? ';' . $headers['Bcc'] : '')) as $dst) {
         $this->dialog('RCPT TO: ' . strstr($dst, '<'), $log);
     }
     $this->dialog('DATA', $log);
     if ($this->attachments) {
         // Replace Content-Type
         $hash = uniqid(NULL, TRUE);
         $type = $headers['Content-Type'];
         $headers['Content-Type'] = 'multipart/mixed; ' . 'boundary="' . $hash . '"';
         // Send mail headers
         $out = '';
         foreach ($headers as $key => $val) {
             if ($key != 'Bcc') {
                 $out .= $key . ': ' . $val . $eol;
             }
         }
         $out .= $eol;
         $out .= 'This is a multi-part message in MIME format' . $eol;
         $out .= $eol;
         $out .= '--' . $hash . $eol;
         $out .= 'Content-Type: ' . $type . $eol;
         $out .= $eol;
         $out .= $message . $eol;
         foreach ($this->attachments as $attachment) {
             if (is_array($attachment)) {
                 list($alias, $file) = each($attachment);
                 $filename = $alias;
                 $attachment = $file;
             } else {
                 $filename = basename($attachment);
             }
             $out .= '--' . $hash . $eol;
             $out .= 'Content-Type: application/octet-stream' . $eol;
             $out .= 'Content-Transfer-Encoding: base64' . $eol;
             $out .= 'Content-Disposition: attachment; ' . 'filename="' . $filename . '"' . $eol;
             $out .= $eol;
             $out .= chunk_split(base64_encode(file_get_contents($attachment))) . $eol;
         }
         $out .= $eol;
         $out .= '--' . $hash . '--' . $eol;
         $out .= '.';
         $this->dialog($out, FALSE);
     } else {
         // Send mail headers
         $out = '';
         foreach ($headers as $key => $val) {
             if ($key != 'Bcc') {
                 $out .= $key . ': ' . $val . $eol;
             }
         }
         $out .= $eol;
         $out .= $message . $eol;
         $out .= '.';
         // Send message
         $this->dialog($out);
     }
     $this->dialog('QUIT', $log);
     if ($socket) {
         fclose($socket);
     }
     return TRUE;
 }
Пример #24
0
 /**
  * Prep Quoted Printable
  *
  * Prepares string for Quoted-Printable Content-Transfer-Encoding
  * Refer to RFC 2045 http://www.ietf.org/rfc/rfc2045.txt
  *
  * @param	string
  * @return	string
  */
 protected function _prep_quoted_printable($str)
 {
     // We are intentionally wrapping so mail servers will encode characters
     // properly and MUAs will behave, so {unwrap} must go!
     $str = str_replace(array('{unwrap}', '{/unwrap}'), '', $str);
     // RFC 2045 specifies CRLF as "\r\n".
     // However, many developers choose to override that and violate
     // the RFC rules due to (apparently) a bug in MS Exchange,
     // which only works with "\n".
     if ($this->crlf === "\r\n") {
         if (is_php('5.3')) {
             return quoted_printable_encode($str);
         } elseif (function_exists('imap_8bit')) {
             return imap_8bit($str);
         }
     }
     // Reduce multiple spaces & remove nulls
     $str = preg_replace(array('| +|', '/\\x00+/'), array(' ', ''), $str);
     // Standardize newlines
     if (strpos($str, "\r") !== FALSE) {
         $str = str_replace(array("\r\n", "\r"), "\n", $str);
     }
     $escape = '=';
     $output = '';
     foreach (explode("\n", $str) as $line) {
         $length = strlen($line);
         $temp = '';
         // Loop through each character in the line to add soft-wrap
         // characters at the end of a line " =\r\n" and add the newly
         // processed line(s) to the output (see comment on $crlf class property)
         for ($i = 0; $i < $length; $i++) {
             // Grab the next character
             $char = $line[$i];
             $ascii = ord($char);
             // Convert spaces and tabs but only if it's the end of the line
             if ($i === $length - 1 && ($ascii === 32 or $ascii === 9)) {
                 $char = $escape . sprintf('%02s', dechex($ascii));
             } elseif ($ascii === 61) {
                 $char = $escape . strtoupper(sprintf('%02s', dechex($ascii)));
                 // =3D
             }
             // If we're at the character limit, add the line to the output,
             // reset our temp variable, and keep on chuggin'
             if (strlen($temp) + strlen($char) >= 76) {
                 $output .= $temp . $escape . $this->crlf;
                 $temp = '';
             }
             // Add the character to our temporary line
             $temp .= $char;
         }
         // Add our completed line to the output
         $output .= $temp . $this->crlf;
     }
     // get rid of extra CRLF tacked onto the end
     return substr($output, 0, strlen($this->crlf) * -1);
 }
Пример #25
0
 /**
  * Returns encoded message.
  * @return string
  */
 public function getEncodedMessage()
 {
     $output = '';
     $boundary = '--------' . Strings::random();
     foreach ($this->headers as $name => $value) {
         $output .= $name . ': ' . $this->getEncodedHeader($name);
         if ($this->parts && $name === 'Content-Type') {
             $output .= ';' . self::EOL . "\tboundary=\"{$boundary}\"";
         }
         $output .= self::EOL;
     }
     $output .= self::EOL;
     $body = (string) $this->body;
     if ($body !== '') {
         switch ($this->getEncoding()) {
             case self::ENCODING_QUOTED_PRINTABLE:
                 $output .= quoted_printable_encode($body);
                 break;
             case self::ENCODING_BASE64:
                 $output .= rtrim(chunk_split(base64_encode($body), self::LINE_LENGTH, self::EOL));
                 break;
             case self::ENCODING_7BIT:
                 $body = preg_replace('#[\\x80-\\xFF]+#', '', $body);
                 // break intentionally omitted
             // break intentionally omitted
             case self::ENCODING_8BIT:
                 $body = str_replace(array("", "\r"), '', $body);
                 $body = str_replace("\n", self::EOL, $body);
                 $output .= $body;
                 break;
             default:
                 throw new Nette\InvalidStateException('Unknown encoding.');
         }
     }
     if ($this->parts) {
         if (substr($output, -strlen(self::EOL)) !== self::EOL) {
             $output .= self::EOL;
         }
         foreach ($this->parts as $part) {
             $output .= '--' . $boundary . self::EOL . $part->getEncodedMessage() . self::EOL;
         }
         $output .= '--' . $boundary . '--';
     }
     return $output;
 }
Пример #26
0
 /**
  * Prep Quoted Printable
  *
  * Prepares string for Quoted-Printable Content-Transfer-Encoding
  * Refer to RFC 2045 http://www.ietf.org/rfc/rfc2045.txt
  *
  * @param	string
  * @return	string
  */
 protected function _prep_quoted_printable($str)
 {
     // ASCII code numbers for "safe" characters that can always be
     // used literally, without encoding, as described in RFC 2049.
     // http://www.ietf.org/rfc/rfc2049.txt
     static $ascii_safe_chars = array(39, 40, 41, 43, 44, 45, 46, 47, 58, 61, 63, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122);
     // We are intentionally wrapping so mail servers will encode characters
     // properly and MUAs will behave, so {unwrap} must go!
     $str = str_replace(array('{unwrap}', '{/unwrap}'), '', $str);
     // RFC 2045 specifies CRLF as "\r\n".
     // However, many developers choose to override that and violate
     // the RFC rules due to (apparently) a bug in MS Exchange,
     // which only works with "\n".
     if ($this->crlf === "\r\n") {
         if (is_php('5.3')) {
             return quoted_printable_encode($str);
         } elseif (function_exists('imap_8bit')) {
             return imap_8bit($str);
         }
     }
     // Reduce multiple spaces & remove nulls
     $str = preg_replace(array('| +|', '/\\x00+/'), array(' ', ''), $str);
     // Standardize newlines
     if (strpos($str, "\r") !== FALSE) {
         $str = str_replace(array("\r\n", "\r"), "\n", $str);
     }
     $escape = '=';
     $output = '';
     foreach (explode("\n", $str) as $line) {
         $length = strlen($line);
         $temp = '';
         // Loop through each character in the line to add soft-wrap
         // characters at the end of a line " =\r\n" and add the newly
         // processed line(s) to the output (see comment on $crlf class property)
         for ($i = 0; $i < $length; $i++) {
             // Grab the next character
             $char = $line[$i];
             $ascii = ord($char);
             // Convert spaces and tabs but only if it's the end of the line
             if ($ascii === 32 or $ascii === 9) {
                 if ($i === $length - 1) {
                     $char = $escape . sprintf('%02s', dechex($ascii));
                 }
             } elseif ($ascii === 61) {
                 $char = $escape . strtoupper(sprintf('%02s', dechex($ascii)));
                 // =3D
             } elseif (!in_array($ascii, $ascii_safe_chars, TRUE)) {
                 $char = $escape . strtoupper(sprintf('%02s', dechex($ascii)));
             }
             // If we're at the character limit, add the line to the output,
             // reset our temp variable, and keep on chuggin'
             if (strlen($temp) + strlen($char) >= 76) {
                 $output .= $temp . $escape . $this->crlf;
                 $temp = '';
             }
             // Add the character to our temporary line
             $temp .= $char;
         }
         // Add our completed line to the output
         $output .= $temp . $this->crlf;
     }
     // get rid of extra CRLF tacked onto the end
     return substr($output, 0, strlen($this->crlf) * -1);
 }
Пример #27
0
 function qp_encode($text)
 {
     if (function_exists('quoted_printable_encode')) {
         return quoted_printable_encode($text);
     } elseif (function_exists('imap_8bit')) {
         return imap_8bit($text);
     } else {
         $arrEncodeSupport = mb_list_encodings();
         if (array_search('Quoted-Printable', $arrEncodeSupport) != FALSE) {
             return mb_convert_encoding($text, 'Quoted-Printable', "JIS");
         } else {
             $crlf = "\r\n";
             $text = trim($text);
             $lines = preg_split("/(\r\n|\n|\r)/s", $text);
             $out = '';
             $temp = '';
             foreach ($lines as $line) {
                 for ($j = 0; $j < strlen($line); $j++) {
                     $char = substr($line, $j, 1);
                     $ascii = ord($char);
                     if ($ascii < 32 || $ascii == 61 || $ascii > 126) {
                         $char = '=' . strtoupper(dechex($ascii));
                     }
                     if (strlen($temp) + strlen($char) >= 76) {
                         $out .= $temp . '=' . $crlf;
                         $temp = '';
                     }
                     $temp .= $char;
                 }
             }
             $out .= $temp;
             return trim($out);
         }
     }
 }
Пример #28
0
 /**
  * validate and shape an email address.
  *
  * @param string    email address (in either "name <account@domain>", "account@domain", "name <account@[ip address]>" or "account@[ip address]" format
  * @param string    header type to add address to (To, Cc, Bcc)
  */
 private function address($email, $type = 'To')
 {
     //! check if it's a valid email address
     if (preg_match("/(.*?)?[\\<]?(([^\\<]+)\\@((\\[?)[a-zA-Z0-9\\-\\.\\:\\_]+([a-zA-Z]+|[0-9]{1,3})(\\]?)))[\\>]?\$/", $email, $m)) {
         //! only localhost allowed not to contain dot
         if (strpos($m[4], '.') === false && $m[4] != 'localhost') {
             throw new EmailException(L('invalid email address') . ': ' . $email);
         }
         //! remove if it's already exists in headers to avoid duplications
         foreach (['To', 'Cc', 'Bcc'] as $rcpt) {
             if (!empty($this->header[$rcpt][$m[2]])) {
                 unset($this->header[$rcpt][$m[2]]);
             }
         }
         //! add to headers
         $this->header[$type][$m[2]] = '=?utf-8?Q?' . quoted_printable_encode(str_replace("\r", '', str_replace("\n", ' ', str_replace('@', ' AT ', !empty($m[1]) ? trim($m[1]) : $m[3])))) . '?= <' . $m[2] . '>';
         return true;
     }
     throw new EmailException(L('invalid email address') . ': ' . $email);
 }
Пример #29
0
 /**
  * Encodes a string in the given encoding.
  *
  * @param	string	$string		string to encode
  * @param	string	$encoding	the charset
  * @return	string	encoded string
  */
 protected static function encode_string($string, $encoding, $newline = null)
 {
     $newline or $newline = \Config::get('email.defaults.newline', "\n");
     switch ($encoding) {
         case 'quoted-printable':
             return quoted_printable_encode($string);
         case '7bit':
         case '8bit':
             return static::prep_newlines(rtrim($string, $newline), $newline);
         case 'base64':
             return chunk_split(base64_encode($string), 76, $newline);
         default:
             throw new \InvalidEmailStringEncoding($encoding . ' is not a supported encoding method.');
     }
 }
Пример #30
0
 /**
  *	Transmit message
  *	@return bool
  *	@param $message string
  *	@param $log bool
  *	@param $mock bool
  **/
 function send($message, $log = TRUE, $mock = FALSE)
 {
     if ($this->scheme == 'ssl' && !extension_loaded('openssl')) {
         return FALSE;
     }
     // Message should not be blank
     if (!$message) {
         user_error(self::E_Blank, E_USER_ERROR);
     }
     $fw = Base::instance();
     // Retrieve headers
     $headers = $this->headers;
     // Connect to the server
     if (!$mock) {
         $socket =& $this->socket;
         $socket = @fsockopen($this->host, $this->port, $errno, $errstr);
         if (!$socket) {
             $fw->error(500, $errstr);
             return FALSE;
         }
         stream_set_blocking($socket, TRUE);
     }
     // Get server's initial response
     $this->dialog(NULL, TRUE, $mock);
     // Announce presence
     $reply = $this->dialog('EHLO ' . $fw->get('HOST'), $log, $mock);
     if (strtolower($this->scheme) == 'tls') {
         $this->dialog('STARTTLS', $log, $mock);
         if (!$mock) {
             stream_socket_enable_crypto($socket, TRUE, STREAM_CRYPTO_METHOD_TLS_CLIENT);
         }
         $reply = $this->dialog('EHLO ' . $fw->get('HOST'), $log, $mock);
     }
     if (preg_match('/8BITMIME/', $reply)) {
         $headers['Content-Transfer-Encoding'] = '8bit';
     } else {
         $headers['Content-Transfer-Encoding'] = 'quoted-printable';
         $message = preg_replace('/^\\.(.+)/m', '..$1', quoted_printable_encode($message));
     }
     if ($this->user && $this->pw && preg_match('/AUTH/', $reply)) {
         // Authenticate
         $this->dialog('AUTH LOGIN', $log, $mock);
         $this->dialog(base64_encode($this->user), $log, $mock);
         $auth_rply = $this->dialog(base64_encode($this->pw), $log, $mock);
         if (!preg_match('/^235\\s.*/', $auth_rply)) {
             $this->dialog('QUIT', $log, $mock);
             if (!$mock && $socket) {
                 fclose($socket);
             }
             return FALSE;
         }
     }
     if (empty($headers['Message-ID'])) {
         $headers['Message-ID'] = '<' . uniqid('', TRUE) . '@' . $this->host . '>';
     }
     if (empty($headers['Date'])) {
         $headers['Date'] = date('r');
     }
     // Required headers
     $reqd = ['From', 'To', 'Subject'];
     foreach ($reqd as $id) {
         if (empty($headers[$id])) {
             user_error(sprintf(self::E_Header, $id), E_USER_ERROR);
         }
     }
     $eol = "\r\n";
     $str = '';
     // Stringify headers
     foreach ($headers as $key => &$val) {
         if (!in_array($key, $reqd) && (!$this->attachments || $key != 'Content-Type' && $key != 'Content-Transfer-Encoding')) {
             $str .= $key . ': ' . $val . $eol;
         }
         if (in_array($key, ['From', 'To', 'Cc', 'Bcc'])) {
             $email = '';
             preg_match_all('/(?:".+?" )?(?:<.+?>|[^ ,]+)/', $val, $matches, PREG_SET_ORDER);
             foreach ($matches as $raw) {
                 $email .= ($email ? ', ' : '') . (preg_match('/<.+?>/', $raw[0]) ? $raw[0] : '<' . $raw[0] . '>');
             }
             $val = $email;
         }
         unset($val);
     }
     // Start message dialog
     $this->dialog('MAIL FROM: ' . strstr($headers['From'], '<'), $log, $mock);
     foreach ($fw->split($headers['To'] . (isset($headers['Cc']) ? ';' . $headers['Cc'] : '') . (isset($headers['Bcc']) ? ';' . $headers['Bcc'] : '')) as $dst) {
         $this->dialog('RCPT TO: ' . strstr($dst, '<'), $log, $mock);
     }
     $this->dialog('DATA', $log, $mock);
     if ($this->attachments) {
         // Replace Content-Type
         $type = $headers['Content-Type'];
         unset($headers['Content-Type']);
         $enc = $headers['Content-Transfer-Encoding'];
         unset($headers['Content-Transfer-Encoding']);
         $hash = uniqid(NULL, TRUE);
         // Send mail headers
         $out = 'Content-Type: multipart/mixed; boundary="' . $hash . '"' . $eol;
         foreach ($headers as $key => $val) {
             if ($key != 'Bcc') {
                 $out .= $key . ': ' . $val . $eol;
             }
         }
         $out .= $eol;
         $out .= 'This is a multi-part message in MIME format' . $eol;
         $out .= $eol;
         $out .= '--' . $hash . $eol;
         $out .= 'Content-Type: ' . $type . $eol;
         $out .= 'Content-Transfer-Encoding: ' . $enc . $eol;
         $out .= $str . $eol;
         $out .= $message . $eol;
         foreach ($this->attachments as $attachment) {
             if (is_array($attachment['filename'])) {
                 list($alias, $file) = each($attachment['filename']);
             } else {
                 $alias = basename($file = $attachment['filename']);
             }
             $out .= '--' . $hash . $eol;
             $out .= 'Content-Type: application/octet-stream' . $eol;
             $out .= 'Content-Transfer-Encoding: base64' . $eol;
             if ($attachment['cid']) {
                 $out .= 'Content-ID: ' . $attachment['cid'] . $eol;
             }
             $out .= 'Content-Disposition: attachment; ' . 'filename="' . $alias . '"' . $eol;
             $out .= $eol;
             $out .= chunk_split(base64_encode(file_get_contents($file))) . $eol;
         }
         $out .= $eol;
         $out .= '--' . $hash . '--' . $eol;
         $out .= '.';
         $this->dialog($out, TRUE, $mock);
     } else {
         // Send mail headers
         $out = '';
         foreach ($headers as $key => $val) {
             if ($key != 'Bcc') {
                 $out .= $key . ': ' . $val . $eol;
             }
         }
         $out .= $eol;
         $out .= $message . $eol;
         $out .= '.';
         // Send message
         $this->dialog($out, TRUE, $mock);
     }
     $this->dialog('QUIT', $log, $mock);
     if (!$mock && $socket) {
         fclose($socket);
     }
     return TRUE;
 }