I
I
imater2013-01-30 10:34:06
Zend Framework
imater, 2013-01-30 10:34:06

How to parse this attached email in PHP and save the files attached there?

In my script, using Zend mail, a letter is parsed in which a letter is attached in the “message/rfc822” format.
How to parse this attached email in PHP and save the attached files to the specified location?
My script:

ini_set('memory_limit', '-1');<br>
require_once('Zend/Mail/Storage/Pop3.php');<br><br>
$mail = new Zend_Mail_Storage_Pop3(array('host' => 'mail.42tree.ru',<br>
                     'user'=> '[email protected]',<br>
                     'password' => '***'));<br><br>
echo $mail->countMessages() . " messages found<br>";<br><br>
$i=1;<br>
$s=1;<br><br>
$message = $mail[$_GET['id']]; // id = указан в адресной строке, это номер письма<br><br>
$title = decode_mime_string( $message->subject ); // заголовок<br><br>
echo "title = ".$title."<br>";<br><br>
$part = $message;<br><br>
function transformHTML($str) { //украшаем HTML формат.<br>
   if ((strpos($str,"<HTML") < 0) || (strpos($str,"<html")    < 0)) {<br>
  		$makeHeader = "<html><head><meta http-equiv=\"Content-Type\"    content=\"text/html; charset=iso-8859-1\"></head>\n";<br>
   	if ((strpos($str,"<BODY") < 0) || (strpos($str,"<body")    < 0)) {<br>
   		$makeBody = "\n<body>\n";<br>
   		$str = $makeHeader . $makeBody . $str ."\n</body></html>";<br>
   	} else {<br>
   		$str = $makeHeader . $str ."\n</html>";<br>
   	}<br>
   } else {<br>
   	$str = "<meta http-equiv=\"Content-Type\" content=\"text/html;    charset=iso-8859-1\">\n". $str;<br>
   }<br>
   	return $str;<br>
 }<br><br><br>
function txt_to_html($dataTxt)  //превращаем текстовый формат в html для отображения<br>
{<br>
   $msgBody = ereg_replace("\n","<br>",$dataTxt);<br>
   $msgBody = preg_replace("/([^\w\/])(www\.[a-z0-9\-]+\.[a-z0-9\-]+)/i","$1http://$2",    $msgBody);<br>
   $msgBody = preg_replace("/([\w]+:\/\/[\w-?&;#~=\.\/\@]+[\w\/])/i","<A    TARGET=\"_blank\" HREF=\"$1\">$1</A>", $msgBody);<br>
   $msgBody = preg_replace("/([\w-?&;#~=\.\/]+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?))/i","<A    HREF=\"mailto:$1\">$1</A>",$msgBody);<br>
   return $msgBody;<br>
}<br><br>
function DisplayMessage($part) //главная функция которая отображает<br>
{<br>
$answer = "";<br>
  echo $part->contentType."<br>";<br>
  $type = explode(";",$part->contentType);<br><br>
  if($type[0]=="message/rfc822")<br>
    {<br>
    /*<br>
                <b>УМА НЕ ПРИЛОЖУ, КАК ПАРСИТЬ ЭТО СООБЩЕНИЕ И РАЗОБРАТЬ ЕГО ВЛОЖЕНИЯ</b><br>
                */<br>
    }<br><br>
  if($type[0]=="text/html") <br>
    {<br>
    $answer = ( decode_mime_string( base64_decode($part->getContent()) ) );<br>
//	    if(eregi("KOI8", $type[1]) OR true ) { $answer = iconv('KOI8-R', 'UTF-8', $answer); }<br>
//	    $answer = transformHTML($answer);<br>
    $answer = quoted_printable_decode ( decode_mime_string( ($part->getContent()) ) );<br>
      if(eregi("KOI8", $type[1]) ) { $answer = iconv('KOI8-R', 'UTF-8', $answer); }<br>
    }<br><br>
  if($type[0]=="text/plain") <br>
    {<br>
    //base64_decode<br>
    $answer = txt_to_html( quoted_printable_decode( decode_mime_string( ($part->getContent()) ) ) );<br>
      if(eregi("koi8", $type[1]) ) { $answer = iconv('KOI8-R', 'UTF-8', $answer); }<br>
      if(eregi("windows-1251", $type[1])) { $answer = iconv('windows-1251', 'UTF-8', $answer); }<br>
    }<br><br>
  if( ($type[0]=="image/jpeg") || ($type[0]=="image/png") )<br>
    {<br>
      $typename = $type[1];<br>
      $typename = decode_mime_string( $typename );<br>
      $filename = trim(ereg_replace('name=|"','',$typename));<br>
      $file = "upload/".$filename;<br>
      $content = base64_decode($part->getContent());<br>
      file_put_contents($file,$content);<br>
      $answer = "<br><img src='../mail/".$file."'><br>".$filename."<hr>";<br>
    }<br><br>
  if( in_array($type[0],array("application/msword","application/pdf","application/octet-stream")) )<br>
    {<br>
      $typename = $type[1];<br>
      $typename = decode_mime_string( $typename );<br>
      $filename = trim(ereg_replace('name=|"','',$typename));<br>
      $file = "upload/".$filename;<br>
      $content = base64_decode($part->getContent());<br>
      file_put_contents($file,$content);<br>
      $answer = "<br><a href='../mail/".$file."'>".$filename."</a>";<br>
    }<br><br><br>
  return $answer."<br>";<br>
}<br><br>
$j=1;<br><br>
$counts = $message->countParts();<br>
echo $message->contentType."<hr>";<br><br>
for($ii=1; $ii<=$counts; $ii++) //перебираем все вложения одного письма<br>
  {<br>
  echo $ii."<br>";<br>
  $part = $message->getPart($ii);<br>
  if($part->isMultipart())  //если вложение тоже имеет вложения, парсим внутри<br>
    {<br>
    for($jj=1; $jj<=$part->countParts(); $jj++)<br>
      {<br>
      $part2 = $part->getPart($jj);<br>
        if($part2->isMultipart())  //обрабатываем третий уровень вложенности, возможно это бесполезно<br>
          {<br>
          for($jk=1; $jk<=$part2->countParts(); $jk++)<br>
            {<br>
            $part3 = $part2->getPart($jk);<br>
            echo DisplayMessage($part3);<br>
            }<br>
          }<br>
      echo DisplayMessage($part2);<br>
      }<br>
    }<br>
//	if($ii=3) print_r($part->countParts());<br>
  echo DisplayMessage($part);<br>
  }<br><br>

Answer the question

In order to leave comments, you need to log in

2 answer(s)
I
imater, 2013-01-31
@imater

Thanks to fort93t , solution: You can force
ZF to parse a string like this:

$message = new Zend_Mail_Message(array(
    'raw' => $messageAsString,
));

Works great! +1

M
merlin-vrn, 2013-01-30
@merlin-vrn

This is an email message attached as an attachment to an email message. For example, when you send something "as an attachment", this attachment is obtained like this.
If I understood the documentation correctly, Zend has a RecursiveIterator that should, bypassing the MIME tree, call your code for each part, including recursively entering this nested message and processing it. The data can be contained in the text part or in attachments of this embedded message.
Since you are trying to parse email messages, then it is imperative for you to read and understand this very RFC 822 (unexpectedly, right?) Or better, the modern incarnation of this standard, RFC 5322, the format is described in detail there. Even though Zend is supposed to do the parsing for you, you need to understand what exactly it does.
In short, the format of an email message is as follows: first, the headers (Content-Type, Subject, From, To, ...), separated by \r\n, then after \r\n\rn (empty line) comes the body of the message, which can consist of a text block, and if the message has a multipart/* MIME type, then attachments follow, separated by the string specified in the Content-Type; the structure is recursive, that is, each attachment looks exactly like a message - headers and body, which can also consist of parts.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question