2008年2月25日

[PHP-users 33326]MIME decodeについて

こんにちは!

現在メールからサポートチケットに投稿する内容を利用しています。

ところが、日本語のメール名がついていると投稿者メールアドレスが、@しか表
示されないのです。

例えば、佐藤聡<ams@xxxxx> から support@xxxxx へ送信する

と、PIPEされて新規投稿する様になっています。しかし、その結果Subjectと本
文は、文字化けしないで正しく表示されます。送信者(投稿者)名は、表示され
ません。また、送信者メールアドレスが@だけに表示されます。

思われるコードは、functions_mime.phpの以下のあたりではないかと思われます。

$output->fromEmail = sprintf('%s@%s', $from[0]->mailbox, $from[0]->host);

$output->fromName = preg_replace('/^"(.*)"$/u', '$1',
$from[0]->personal);

以下にこのFunctionを追加します。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

/**
* Decodes a mail and returns the various parts.
* Original Function by Richard Heyes, Modified to fix some bugs
*/
function decodeMail($input)
{
global $decodeMail_output, $_SWIFT, $charset;

// Declare the additional classes
// parserDebug("MIME: Initiating Classes");
$Mail_mimeDecode = new Mail_mimeDecode($input, SWIFT_CRLF);
$Mail_RFC822 = new Mail_RFC822;

$output = &$decodeMail_output;
// parserDebug("MIME: Got Output");

$decode_params['input'] = $input;
$decode_params['include_bodies'] = true;
$decode_params['decode_bodies'] = true;
$decode_params['decode_headers'] = true;
// parserDebug("MIME: Input Is\n".$input);
// parserDebug("MIME: Decoding...");
$structure = $Mail_mimeDecode->decode($decode_params);
// parserDebug("MIME: Traversing Structure");
$this->decodeMail_traverseStructure($structure);

// Sizes
$output->textSize = jstrlen(@$output->text);
$output->htmlSize = jstrlen(@$output->html);
// parserDebug("MIME: Text Size: ".$output->textSize.", HTML Size:
".$output->htmlSize);

// Headers
$output->headers = $structure->headers;
//////////////////////////////////////
// JcodeConvert($string, 1, 2);
// Above was modified with JcodeConvert.
///////////////////////////////////////

// parserDebug("MIME: Got Headers");

$tofix = array("\(", "\)", "\[", "\]", "\{", "\}");
$fixres = array("(", ")", "[", "]", "{", "}");

// From name/email
if (!empty($output->headers['from'])) {

///////////////////////////////////////////////////////////

// $from = $Mail_RFC822->parseAddressList(str_replace($tofix,
$fixres,
mb_convert_encoding(mb_decode_mimeheader(($output->headers['from'])),"UTF-8","AUTO")),
null, null, false);

// This was modified to change the incoming email to right encoding
///////////////////////////////////////////////////////////////////

$from = $Mail_RFC822->parseAddressList(str_replace($tofix, $fixres,
$output->headers['from']), null, null, false);
// Above is the original.

$output->fromEmail = sprintf('%s@%s', $from[0]->mailbox, $from[0]->host);
// $output->fromName = preg_replace('/^"(.*)"$/', '\1',
$from[0]->personal);
// Above is the original.
$output->fromName = preg_replace('/^"(.*)"$/u', '$1',
$from[0]->personal);
// Above /u was added to treat them as UTF-8 characters.
// Changed from \1 to $1
}
// parserDebug("MIME: Parsed From");

// Reply to
if (!empty($output->headers['reply-to'])) {
// $replyto = $Mail_RFC822->parseAddressList(str_replace($tofix,
$fixres, $output->headers['reply-to']), null, null, false);
// Original is above.

$replyto = $Mail_RFC822->parseAddressList(str_replace($tofix,
$fixres,
mb_convert_encoding(($output->headers['reply-to']),"UTF-8","AUTO")),
null, null, false);
// Above was replaced for PIPE issue.
// 2008.2.8
////////////////////////////////////////

$output->replytoEmail = sprintf('%s@%s', $replyto[0]->mailbox,
$replyto[0]->host);
$output->replytoName = preg_replace('/^"(.*)"$/u', '$1',
$replyto[0]->personal);
// Above /u was added to treat them as UTF-8 characters.
// \1 was changed to $1.
}
// parserDebug("MIME: Parsed Reply To");

// To name/email
if (!empty($output->headers['to'])) {

$to = $Mail_RFC822->parseAddressList(str_replace($tofix, $fixres,
mb_convert_encoding(mb_decode_mimeheader(($output->headers['to'])),"UTF-8","AUTO")),
null, null, false);

// Above was replaced to properly encode the incoming email.
////////////////////////////////////////////////////////////

// $to = $Mail_RFC822->parseAddressList(str_replace($tofix, $fixres,
$output->headers['to']), null, null, false);

// Above was replaced with one above.
////////////////////////////////////////////

// $to = $Mail_RFC822->parseAddressList(str_replace($tofix, $fixres,
mb_convert_encoding($output->headers['to'],"UTF-8","AUTO")), null, null,
false);
// Now without mb_decode_mimeheader.
// 2008.2.8
/////////////////////////////////////////



if (is_array($output->headers['to'])) {
$output->toEmail = $output->headers['to'][0];
} else {

///////////////////////////////////////////////////
$output->toEmail = sprintf('%s@%s', $to[0]->mailbox, $to[0]->host);
// %s@%s? What did do?
///////////////////////////////// This may have some clue
//////////////////////////////////////////////////////////

}
$output->toName = preg_replace('/^"(.*)"$/u', '$1', $to[0]->personal);
// Above /u was added to treat them as UTF-8 characters.
// \1 was changed to $1

// This has some clue in it.
// preg_replace can cause the @ email name to be broken.
// Study: ^ $ は、最初から最後までのことです。
///////////////////////////////////////////////////////////////
///////////////////////////////// Potential changes are needed here.
//////////////////////////////////////////////////////////////////

}
// parserDebug("MIME: Parsed To");

// In-Reply-To
if (!empty($output->headers['in-reply-to'])) {
// $inreplyto = $Mail_RFC822->parseAddressList(str_replace($tofix,
$fixres, $output->headers['in-reply-to']), null, null, false);
// Above was the original.
/////////////////////////////////////////////////////

$inreplyto = $Mail_RFC822->parseAddressList(str_replace($tofix,
$fixres,
mb_convert_encoding(mb_decode_mimeheader(($output->headers['in-reply-to'])),"UTF-8","AUTO")),
null, null, false);
//////////////////////////////////////////////////////
// Above was replaced.
/////////////////////////////////////////////////////////


$output->inReplyTo = trim($inreplyto[0]->mailbox);
}
// parserDebug("MIME: Parsed In-Reply-To");

// Return address
if (!empty($output->headers['reply-to'])) {
$output->returnAddress = $output->headers['reply-to'];
} elseif (!empty($output->headers['sender'])) {
$output->returnAddress = $output->headers['sender'];
} elseif (!empty($output->headers['from'])) {
$output->returnAddress = $output->headers['from'];
} elseif (!empty($output->headers['return-path'])) {
$output->returnAddress = $output->headers['return-path'];
}
if (!empty($output->returnAddress)) {
// $retAddress = $Mail_RFC822->parseAddressList(str_replace($tofix,
$fixres, $output->returnAddress), null, null, false);
// Above was original.
/////////////////////////////////////////////

$retAddress = $Mail_RFC822->parseAddressList(str_replace($tofix,
$fixres,
mb_convert_encoding(mb_decode_mimeheader($output->returnAddress),"UTF-8","AUTO")),
null, null, false);
//////////////////////////////////////////////////////////
// Above was replaced.
////////////////////////////////////////////////////////////



$output->returnAddressEmail = sprintf('%s@%s',
$retAddress[0]->mailbox, $retAddress[0]->host);
$output->returnAddressName = preg_replace('/^"(.*)"$/u', '$1',
$retAddress[0]->personal);
// Above /u was added to treat them as UTF-8 characters.
// \1 was replaced with $1
}
// parserDebug("MIME: Calculated the Return Address:
".$output->returnAddress);

// Recipient addresses
$shiftcount = 0;
foreach (array('to', 'cc', 'x-rcpt-to') as $header) {
if (!empty($output->headers[$header]) &&
!is_array($output->headers['to'])) {
// $to = $Mail_RFC822->parseAddressList(str_replace($tofix, $fixres,
$output->headers[$header]), null, null, false);
///////////////////////////////////////
// Above was original.
///////////////////////////////////

$to = $Mail_RFC822->parseAddressList(str_replace($tofix, $fixres,
mb_convert_encoding(mb_decode_mimeheader(($output->headers[$header])),"UTF-8","AUTO")),
null, null, false);

$loopcount = count($to);
if ($loopcount > 10)
{
$loopcount = 10;
}
for ($i=0; $i<$loopcount; $i++) {
if ($to[$i]) {
$recipientemail = sprintf('%s@%s', $to[$i]->mailbox, $to[$i]->host);
if ($this->isValidEmail($recipientemail))
{
$recipients[] = $recipientemail;
}
}
}
} else {
// Most probably this email has multiple to's
if ($this->isValidEmail($output->headers['to'][0]))
{
$recipients[] = $output->headers['to'][0];
}
}
$shiftcount++;

if ($shiftcount > 50)
{
break;
}
}

$output->recipientAddresses = $recipients;

// THe following was replaced
///////////////////////////////////

$output->subject =
mb_convert_encoding(mb_decode_mimeheader(($output->headers["subject"])),"UTF-8","AUTO");

/// Above was represented to all the changings.
////////////////////////////////

// $output->subject = $output->headers["subject"];
// Above is the original

//$charset = $structure->ctype_parameters['charset'];

// $subjectUtf8 = $output->headers["subject"];
// Above is the original.
////////////////////////////////////////////

$subjectUtf8 =
mb_convert_encoding(mb_decode_mimeheader(($output->headers["subject"])),"UTF-8","AUTO");

if ($_SWIFT["settings"]["pr_conversion"] == 1 &&
extension_loaded("mbstring"))
{
if (empty($charset))
{
$_emailcharset = mb_detect_encoding($output->headers["subject"]);
} else {
$_emailcharset = $charset;
}

if (!empty($_emailcharset))
{

/////////////////////////////////////////////
//// The following was domified for PIPE.
///////////////////////////////////////////

//


//$subjectUtf8 = @mb_convert_encoding($subjectUtf8,
$_SWIFT["language"]["charset"], $_emailcharset);
//$_fromName = @mb_convert_encoding($output->fromName,
$_SWIFT["language"]["charset"], $_emailcharset);
//$_replytoName = @mb_convert_encoding($output->replytoName,
$_SWIFT["language"]["charset"], $_emailcharset);
//$_toName = @mb_convert_encoding($output->toName,
$_SWIFT["language"]["charset"], $_emailcharset);

//////////////



$subjectUtf8 = @mb_convert_encoding($subjectUtf8, "UTF-8",
$_emailcharset);
$_fromName = @mb_convert_encoding($output->fromName, "UTF-8",
$_emailcharset);
$_replytoName = @mb_convert_encoding($output->replytoName, "UTF-8",
$_emailcharset);
$_toName = @mb_convert_encoding($output->toName, "UTF-8",
$_emailcharset);



///////////////////////////////
/// Above was modified for PIPE test.
///////////////////////////////////

$output->fromName = iif(empty($_fromName), $output->fromName,
$_fromName);


$output->replytoName = iif(empty($_replytoName),
$output->replytoName, $_replytoName);



$output->toName = iif(empty($_toName), $output->toName, $_toName);

if (empty($subjectUtf8))
{
$subjectUtf8 = $output->headers["subject"];


}
}

} else if ($_SWIFT["language"]["charset"] == "UTF-8") {
if (!extension_loaded('mbstring') && function_exists("utf8_encode")) {
if (strtolower($charset) != "utf-8") {
$subjectUtf8 = utf8_encode($subjectUtf8);
$output->fromName = utf8_encode($output->fromName);
$output->replytoName = utf8_encode($output->replytoName);
$output->toName = utf8_encode($output->toName);
}
} else if (extension_loaded("mbstring")) {
$subjectUtf8 = @mb_convert_encoding($subjectUtf8, "UTF-8", $charset);
$_fromName = @mb_convert_encoding($output->fromName, "UTF-8", $charset);
$_replytoName = @mb_convert_encoding($output->replytoName, "UTF-8",
$charset);
$_toName = @mb_convert_encoding($output->toName, "UTF-8", $charset);
$output->fromName = iif(empty($_fromName), $output->fromName,
$_fromName);
$output->replytoName = iif(empty($_replytoName),
$output->replytoName, $_replytoName);
$output->toName = iif(empty($_toName), $output->toName, $_toName);
if (empty($subjectUtf8))
{
$subjectUtf8 = $output->headers["subject"];



}
}
}
$output->subject = $subjectUtf8;
// THis was original.

// $output->subject = @mb_convert_encoding($subjectUtf8,"UTF-8","AUTO");
////////////////////////////////////////////////////////////////////
/////////////////// Above was changed for test


// parserDebug("MIME: Got the Subject: ".$output->subject);

return $output;
}


ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

これの日本語対応をしたいと思いますが、どのようにすればよいのか教えて下さ
いますか?

環境:

アパッチバージョン 2.0.63
PHPバージョン 5.2.5
MySQLバージョン 5.0.45-community
基本設計概念 x86_64
操作システム Linux

mbstring
Multibyte Support enabled
Multibyte string engine libmbfl
Multibyte (japanese) regex support enabled
Multibyte regex (oniguruma) version 4.4.4
Multibyte regex (oniguruma) backtrack check On

mbstring extension makes use of "streamable kanji code filter and
converter", which is distributed under the GNU Lesser General Public
License version 2.1.

Directive Local Value Master Value
mbstring.detect_order no value no value
mbstring.encoding_translation Off Off
mbstring.func_overload 0 0
mbstring.http_input pass pass
mbstring.http_output pass pass
mbstring.internal_encoding ISO-8859-1 no value
mbstring.language neutral neutral
mbstring.script_encoding no value no value
mbstring.strict_detection Off Off
mbstring.substitute_character no value no value

使用しているファイル:

http://andvision.net/support/include/functions_mime.php
http://andvision.net/support/include/MIME/mimeDecode.php
http://andvision.net/support/include/MIME/RFC822.php

よろしくお願いします。

アブラハム・リー
_______________________________________________
PHP-users mailing list PHP-users@xxxxx
http://ml.php.gr.jp/mailman/listinfo/php-users
PHP初心者のためのページ - 質問する前にはこちらをお読みください
http://oldwww.php.gr.jp/php/novice.php3

投稿者 xml-rpc : 2008年2月25日 16:04
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/70349
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。