Updated to latest version. Resolves issues with non-ISO-8859-1 characters in attachment filenames and headers

release-0.6
svncommit 18 years ago
parent d72d411ee3
commit a8435bdd12

@ -114,6 +114,7 @@ class Mail_mime
{
$this->_setEOL($crlf);
$this->_build_params = array(
'head_encoding' => 'quoted-printable',
'text_encoding' => '7bit',
'html_encoding' => 'quoted-printable',
'7bit_wrap' => 998,
@ -247,13 +248,15 @@ class Mail_mime
* @param string $disposition The content-disposition of this file
* Defaults to attachment.
* Possible values: attachment, inline.
* @param string $charset The character set used in the filename
* of this attachment.
* @return mixed true on success or PEAR_Error object
* @access public
*/
function addAttachment($file, $c_type = 'application/octet-stream',
$name = '', $isfilename = true,
$encoding = 'base64',
$disposition = 'attachment')
$disposition = 'attachment', $charset = '')
{
$filedata = ($isfilename === true) ? $this->_file2str($file)
: $file;
@ -279,6 +282,7 @@ class Mail_mime
'name' => $filename,
'c_type' => $c_type,
'encoding' => $encoding,
'charset' => $charset,
'disposition' => $disposition
);
return true;
@ -433,7 +437,7 @@ class Mail_mime
function &_addHtmlImagePart(&$obj, $value)
{
$params['content_type'] = $value['c_type'] . '; ' .
'name="' . $params['dfilename'] . '"';
'name="' . $value['name'] . '"';
$params['encoding'] = 'base64';
$params['disposition'] = 'inline';
$params['dfilename'] = $value['name'];
@ -454,12 +458,20 @@ class Mail_mime
*/
function &_addAttachmentPart(&$obj, $value)
{
$params['dfilename'] = $value['name'];
$params['encoding'] = $value['encoding'];
if ($value['disposition'] != "inline") {
$fname = array("fname" => $value['name']);
$fname_enc = $this->_encodeHeaders($fname);
$params['dfilename'] = $fname_enc['fname'];
}
if ($value['charset']) {
$params['charset'] = $value['charset'];
}
$params['content_type'] = $value['c_type'] . '; ' .
'name="' . $params['dfilename'] . '"';
$params['encoding'] = $value['encoding'];
$params['disposition'] = isset($value['disposition']) ?
$value['disposition'] : 'attachment';
$params['dfilename'] = $value['name'];
$ret = $obj->addSubpart($value['body'], $params);
return $ret;
}
@ -500,9 +512,14 @@ class Mail_mime
*
* @param array Build parameters that change the way the email
* is built. Should be associative. Can contain:
* head_encoding - What encoding to use for the headers.
* Options: quoted-printable or base64
* Default is quoted-printable
* text_encoding - What encoding to use for plain text
* Options: 7bit, 8bit, base64, or quoted-printable
* Default is 7bit
* html_encoding - What encoding to use for html
* Options: 7bit, 8bit, base64, or quoted-printable
* Default is quoted-printable
* 7bit_wrap - Number of characters before text is
* wrapped in 7bit encoding
@ -742,26 +759,131 @@ class Mail_mime
}
}
/**
* Since the PHP send function requires you to specifiy
* recipients (To: header) separately from the other
* headers, the To: header is not properly encoded.
* To fix this, you can use this public method to
* encode your recipients before sending to the send
* function
*
* @param string $recipients A comma-delimited list of recipients
* @return string Encoded data
* @access public
*/
function encodeRecipients($recipients)
{
$input = array("To" => $recipients);
$retval = $this->_encodeHeaders($input);
return $retval["To"] ;
}
/**
* Encodes a header as per RFC2047
*
* @param string $input The header data to encode
* @return string Encoded data
* @param array $input The header data to encode
* @return array Encoded data
* @access private
*/
function _encodeHeaders($input)
{
foreach ($input as $hdr_name => $hdr_value) {
preg_match_all('/(\w*[\x80-\xFF]+\w*)/', $hdr_value, $matches);
foreach ($matches[1] as $value) {
$replacement = preg_replace('/([\x80-\xFF])/e',
'"=" .
strtoupper(dechex(ord("\1")))',
$value);
$hdr_value = str_replace($value, '=?' .
$this->_build_params['head_charset'] .
'?Q?' . $replacement . '?=',
$hdr_value);
if (function_exists('iconv_mime_encode') && preg_match('#[\x80-\xFF]{1}#', $hdr_value)){
$imePref = array();
if ($this->_build_params['head_encoding'] == 'base64'){
$imePrefs['scheme'] = 'B';
}else{
$imePrefs['scheme'] = 'Q';
}
$imePrefs['input-charset'] = $this->_build_params['head_charset'];
$imePrefs['output-charset'] = $this->_build_params['head_charset'];
$hdr_value = iconv_mime_encode($hdr_name, $hdr_value, $imePrefs);
$hdr_value = preg_replace("#^{$hdr_name}\:\ #", "", $hdr_value);
}elseif (preg_match('#[\x80-\xFF]{1}#', $hdr_value)){
//This header contains non ASCII chars and should be encoded.
switch ($this->_build_params['head_encoding']) {
case 'base64':
//Base64 encoding has been selected.
//Generate the header using the specified params and dynamicly
//determine the maximum length of such strings.
//75 is the value specified in the RFC. The -2 is there so
//the later regexp doesn't break any of the translated chars.
$prefix = '=?' . $this->_build_params['head_charset'] . '?B?';
$suffix = '?=';
$maxLength = 75 - strlen($prefix . $suffix) - 2;
$maxLength1stLine = $maxLength - strlen($hdr_name);
//Base64 encode the entire string
$hdr_value = base64_encode($hdr_value);
//This regexp will break base64-encoded text at every
//$maxLength but will not break any encoded letters.
$reg1st = "|.{0,$maxLength1stLine}[^\=][^\=]|";
$reg2nd = "|.{0,$maxLength}[^\=][^\=]|";
break;
case 'quoted-printable':
default:
//quoted-printable encoding has been selected
//Generate the header using the specified params and dynamicly
//determine the maximum length of such strings.
//75 is the value specified in the RFC. The -2 is there so
//the later regexp doesn't break any of the translated chars.
$prefix = '=?' . $this->_build_params['head_charset'] . '?Q?';
$suffix = '?=';
$maxLength = 75 - strlen($prefix . $suffix) - 2;
$maxLength1stLine = $maxLength - strlen($hdr_name);
//Replace all special characters used by the encoder.
$search = array("=", "_", "?", " ");
$replace = array("=3D", "=5F", "=3F", "_");
$hdr_value = str_replace($search, $replace, $hdr_value);
//Replace all extended characters (\x80-xFF) with their
//ASCII values.
$hdr_value = preg_replace(
'#([\x80-\xFF])#e',
'"=" . strtoupper(dechex(ord("\1")))',
$hdr_value
);
//This regexp will break QP-encoded text at every $maxLength
//but will not break any encoded letters.
$reg1st = "|(.{0,$maxLength})[^\=]|";
$reg2nd = "|(.{0,$maxLength})[^\=]|";
break;
}
//Begin with the regexp for the first line.
$reg = $reg1st;
$output = "";
while ($hdr_value) {
//Split translated string at every $maxLength
//But make sure not to break any translated chars.
$found = preg_match($reg, $hdr_value, $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
//$hdr_value variable.
if ($found){
$part = $matches[0];
$hdr_value = substr($hdr_value, strlen($matches[0]));
}else{
$part = $hdr_value;
$hdr_value = "";
}
//RFC 2047 specifies that any split header should be seperated
//by a CRLF SPACE.
if ($output){
$output .= "\r\n ";
}
$output .= $prefix . $part . $suffix;
}
$hdr_value = $output;
}
$input[$hdr_name] = $hdr_value;
}
@ -787,3 +909,4 @@ class Mail_mime
} // End of class
?>

Loading…
Cancel
Save