From be5133a6f3ec4da11f0a6f972700bf4b256d410c Mon Sep 17 00:00:00 2001 From: alecpl Date: Mon, 8 Mar 2010 07:28:20 +0000 Subject: - Mail_Mime 1.6.1 --- program/lib/Mail/mime.php | 312 ++++++++-------------------------------------- 1 file changed, 52 insertions(+), 260 deletions(-) (limited to 'program/lib/Mail/mime.php') diff --git a/program/lib/Mail/mime.php b/program/lib/Mail/mime.php index d6d63d68f..c08c7cfcb 100644 --- a/program/lib/Mail/mime.php +++ b/program/lib/Mail/mime.php @@ -388,6 +388,7 @@ class Mail_mime * or base64) instead * @param string $f_encoding Encoding for attachment filename (Content-Disposition) * See $n_encoding description + * @param string $description Content-Description header * * @return mixed True on success or PEAR_Error object * @access public @@ -402,7 +403,8 @@ class Mail_mime $language = '', $location = '', $n_encoding = null, - $f_encoding = null + $f_encoding = null, + $description = '' ) { $bodyfile = null; @@ -440,6 +442,7 @@ class Mail_mime 'language' => $language, 'location' => $location, 'disposition' => $disposition, + 'description' => $description, 'name_encoding' => $n_encoding, 'filename_encoding' => $f_encoding ); @@ -668,6 +671,9 @@ class Mail_mime if (!empty($value['filename_encoding'])) { $params['filename_encoding'] = $value['filename_encoding']; } + if (!empty($value['description'])) { + $params['description'] = $value['description']; + } $ret = $obj->addSubpart($value['body'], $params); return $ret; @@ -865,11 +871,13 @@ class Mail_mime } } + $this->_checkParams(); + $null = null; $attachments = count($this->_parts) ? true : false; $html_images = count($this->_html_images) ? true : false; $html = strlen($this->_htmlbody) ? true : false; - $text = (!$html && strlen($this->_txtbody)) ? true : false; + $text = (!$html && strlen($this->_txtbody)) ? true : false; switch (true) { case $text && !$attachments: @@ -1233,265 +1241,9 @@ class Mail_mime */ function encodeHeader($name, $value, $charset, $encoding) { - // Structured headers - $comma_headers = array( - 'from', 'to', 'cc', 'bcc', 'sender', 'reply-to', - 'resent-from', 'resent-to', 'resent-cc', 'resent-bcc', - 'resent-sender', 'resent-reply-to', - 'return-receipt-to', 'disposition-notification-to', + return Mail_mimePart::encodeHeader( + $name, $value, $charset, $encoding, $this->_build_params['eol'] ); - $other_headers = array( - 'references', 'in-reply-to', 'message-id', 'resent-message-id', - ); - - $name = strtolower($name); - $eol = $this->_build_params['eol']; - - if (in_array($name, $comma_headers)) { - $separator = ','; - } else if (in_array($name, $other_headers)) { - $separator = ' '; - } - - if (!$charset) { - $charset = 'ISO-8859-1'; - } - - // Structured header (make sure addr-spec inside is not encoded) - if (!empty($separator)) { - $parts = $this->_explodeQuotedString($separator, $value); - $value = ''; - - foreach ($parts as $part) { - $part = preg_replace('/\r?\n[\s\t]*/', $eol . ' ', $part); - $part = trim($part); - - if (!$part) { - continue; - } - if ($value) { - $value .= $separator==',' ? $separator.' ' : ' '; - } else { - $value = $name . ': '; - } - - // let's find phrase (name) and/or addr-spec - if (preg_match('/^<\S+@\S+>$/', $part)) { - $value .= $part; - } else if (preg_match('/^\S+@\S+$/', $part)) { - // address without brackets and without name - $value .= $part; - } else if (preg_match('/<*\S+@\S+>*$/', $part, $matches)) { - // address with name (handle name) - $address = $matches[0]; - $word = str_replace($address, '', $part); - $word = trim($word); - // check if phrase requires quoting - if ($word) { - // non-ASCII: require encoding - if (preg_match('#([\x80-\xFF]){1}#', $word)) { - if ($word[0] == '"' && $word[strlen($word)-1] == '"') { - // de-quote quoted-string, encoding changes - // string to atom - $search = array("\\\"", "\\\\"); - $replace = array("\"", "\\"); - $word = str_replace($search, $replace, $word); - $word = substr($word, 1, -1); - } - // find length of last line - if (($pos = strrpos($value, $eol)) !== false) { - $last_len = strlen($value) - $pos; - } else { - $last_len = strlen($value); - } - $word = $this->_encodeString( - $word, $charset, $encoding, $last_len - ); - } else if (($word[0] != '"' || $word[strlen($word)-1] != '"') - && preg_match('/[\(\)\<\>\\\.\[\]@,;:"]/', $word) - ) { - // ASCII: quote string if needed - $word = '"'.addcslashes($word, '\\"').'"'; - } - } - $value .= $word.' '.$address; - } else { - // addr-spec not found, don't encode (?) - $value .= $part; - } - - // RFC2822 recommends 78 characters limit, use 76 from RFC2047 - $value = wordwrap($value, 76, $eol . ' '); - } - - // remove header name prefix (there could be EOL too) - $value = preg_replace( - '/^'.$name.':('.preg_quote($eol, '/').')* /', '', $value - ); - - } else { - // Unstructured header - // non-ASCII: require encoding - if (preg_match('#([\x80-\xFF]){1}#', $value)) { - if ($value[0] == '"' && $value[strlen($value)-1] == '"') { - // de-quote quoted-string, encoding changes - // string to atom - $search = array("\\\"", "\\\\"); - $replace = array("\"", "\\"); - $value = str_replace($search, $replace, $value); - $value = substr($value, 1, -1); - } - $value = $this->_encodeString( - $value, $charset, $encoding, strlen($name) + 2 - ); - } else if (strlen($name.': '.$value) > 78) { - // ASCII: check if header line isn't too long and use folding - $value = preg_replace('/\r?\n[\s\t]*/', $eol . ' ', $value); - $tmp = wordwrap($name.': '.$value, 78, $eol . ' '); - $value = preg_replace('/^'.$name.':\s*/', '', $tmp); - // hard limit 998 (RFC2822) - $value = wordwrap($value, 998, $eol . ' ', true); - } - } - - return $value; - } - - /** - * Encodes a header value as per RFC2047 - * - * @param string $value The header data to encode - * @param string $charset Character set name - * @param string $encoding Encoding name (base64 or quoted-printable) - * @param int $prefix_len Prefix length - * - * @return string Encoded header data - * @access private - */ - function _encodeString($value, $charset, $encoding, $prefix_len=0) - { - if ($encoding == 'base64') { - // Base64 encode the entire string - $value = base64_encode($value); - - // Generate the header using the specified params and dynamicly - // determine the maximum length of such strings. - // 75 is the value specified in the RFC. - $prefix = '=?' . $charset . '?B?'; - $suffix = '?='; - $maxLength = 75 - strlen($prefix . $suffix) - 2; - $maxLength1stLine = $maxLength - $prefix_len; - - // We can cut base4 every 4 characters, so the real max - // we can get must be rounded down. - $maxLength = $maxLength - ($maxLength % 4); - $maxLength1stLine = $maxLength1stLine - ($maxLength1stLine % 4); - - $cutpoint = $maxLength1stLine; - $value_out = $value; - $output = ''; - while ($value_out) { - // Split translated string at every $maxLength - $part = substr($value_out, 0, $cutpoint); - $value_out = substr($value_out, $cutpoint); - $cutpoint = $maxLength; - // RFC 2047 specifies that any split header should - // be seperated by a CRLF SPACE. - if ($output) { - $output .= $this->_build_params['eol'] . ' '; - } - $output .= $prefix . $part . $suffix; - } - $value = $output; - } else { - // quoted-printable encoding has been selected - $value = Mail_mimePart::encodeQP($value); - - // Generate the header using the specified params and dynamicly - // determine the maximum length of such strings. - // 75 is the value specified in the RFC. - $prefix = '=?' . $charset . '?Q?'; - $suffix = '?='; - $maxLength = 75 - strlen($prefix . $suffix) - 3; - $maxLength1stLine = $maxLength - $prefix_len; - $maxLength = $maxLength - 1; - - // This regexp will break QP-encoded text at every $maxLength - // but will not break any encoded letters. - $reg1st = "|(.{0,$maxLength1stLine}[^\=][^\=])|"; - $reg2nd = "|(.{0,$maxLength}[^\=][^\=])|"; - - $value_out = $value; - $realMax = $maxLength1stLine + strlen($prefix . $suffix); - if (strlen($value_out) >= $realMax) { - // Begin with the regexp for the first line. - $reg = $reg1st; - $output = ''; - while ($value_out) { - // Split translated string at every $maxLength - // But make sure not to break any translated chars. - $found = preg_match($reg, $value_out, $matches); - - // After this first line, we need to use a different - // regexp for the first line. - $reg = $reg2nd; - - // Save the found part and encapsulate it in the - // prefix & suffix. Then remove the part from the - // $value_out variable. - if ($found) { - $part = $matches[0]; - $len = strlen($matches[0]); - $value_out = substr($value_out, $len); - } else { - $part = $value_out; - $value_out = ""; - } - - // RFC 2047 specifies that any split header should - // be seperated by a CRLF SPACE - if ($output) { - $output .= $this->_build_params['eol'] . ' '; - } - $output .= $prefix . $part . $suffix; - } - $value_out = $output; - } else { - $value_out = $prefix . $value_out . $suffix; - } - $value = $value_out; - } - - return $value; - } - - /** - * Explode quoted string - * - * @param string $delimiter Delimiter expression string for preg_match() - * @param string $string Input string - * - * @return array String tokens array - * @access private - */ - function _explodeQuotedString($delimiter, $string) - { - $result = array(); - $strlen = strlen($string); - - for ($q=$p=$i=0; $i < $strlen; $i++) { - if ($string[$i] == "\"" - && (empty($string[$i-1]) || $string[$i-1] != "\\") - ) { - $q = $q ? false : true; - } else if (!$q && preg_match("/$delimiter/", $string[$i])) { - $result[] = substr($string, $p, $i - $p); - $p = $i + 1; - } - } - - $result[] = substr($string, $p); - return $result; } /** @@ -1556,6 +1308,8 @@ class Mail_mime return $headers; } + $this->_checkParams(); + $eol = !empty($this->_build_params['eol']) ? $this->_build_params['eol'] : "\r\n"; @@ -1590,4 +1344,42 @@ class Mail_mime return $headers; } + /** + * Validate and set build parameters + * + * @return void + * @access private + */ + function _checkParams() + { + $encodings = array('7bit', '8bit', 'base64', 'quoted-printable'); + + $this->_build_params['text_encoding'] + = strtolower($this->_build_params['text_encoding']); + $this->_build_params['html_encoding'] + = strtolower($this->_build_params['html_encoding']); + + if (!in_array($this->_build_params['text_encoding'], $encodings)) { + $this->_build_params['text_encoding'] = '7bit'; + } + if (!in_array($this->_build_params['html_encoding'], $encodings)) { + $this->_build_params['html_encoding'] = '7bit'; + } + + // text body + if ($this->_build_params['text_encoding'] == '7bit' + && !preg_match('/ascii/i', $this->_build_params['text_charset']) + && preg_match('/[^\x00-\x7F]/', $this->_txtbody) + ) { + $this->_build_params['text_encoding'] = 'quoted-printable'; + } + // html body + if ($this->_build_params['html_encoding'] == '7bit' + && !preg_match('/ascii/i', $this->_build_params['html_charset']) + && preg_match('/[^\x00-\x7F]/', $this->_htmlbody) + ) { + $this->_build_params['html_encoding'] = 'quoted-printable'; + } + } + } // End of class -- cgit v1.2.3