Mail-Klasse zum abholen der Mails über pop3

BoTheK

Mitglied
Hallo,
ich habe für ein Projekt eine Klasse geschrieben, die emails über pop3 abholt, und die Nachricht mit Anhängen abholt und ausgibt.

Allerdings habe ich noch probleme mit multipart/alternative - parts. Ich weis leider nicht warum der mir die Ausgabe immer zerhaut.

Kann sich das mal jemand anschauen?
PHP:
<html>
<body>

<?


$boMail = new boMail("username","passwort","INBOX","localhost");


//gibt alle nachrichten des Postfaches in ein Array:
$overall=$boMail->getOverview(); 


echo $boMail->mailsnum." Nachrichten<br>";


echo "<table border='1'><tr><td>Betreff</td><td>Datum</td><td>Absender</td></tr>";
foreach ($overall as $key=>$val) {
	echo "<tr><td><a href='$PHP_SELF?detail=$key'>".$overall[$key]['subject']."</a></td><td>".date("d.m.Y H:m",$overall[$key]['date'])."</td><td>".$overall[$key]['from']."</td></tr>";
}
echo "</table><br>";


if ($detail) {
	// Gibt den Message - Body mit Attachements zurück:
	$msg=$boMail->getDetail($detail); 
}

// schließt Connection:
$boMail->disconnect();


/* -------------------------------------------------------
	KLASSE boMail:
*/
 
 
class boMail {
  	var $box; 				/** mailbox - Reverence 			*/
	var $mailbox; 			/** Mailbox Host & Postfach 		*/
	var $user;      		/** POP oder SMTP - user 			*/
	var $pw;        		/** POP oder SMTP - password 		*/
	var $connected;         /** Is connected?             		*/
	var $mailsnum;          /** Anzahl der Emails im postfach	*/
    var $msgno;          	/** Aktuelle msgno für detail		*/
    var $mail=array();		/** mail - Details            		*/
    var $isHTML=false;      /** ist HTML part vorhanden?        */
    
	var $types=array("text","multipart","message","application","audio","image","video","other");
	var $encodings=array("7BIT","8BIT","BINERY","BASE64","QUOTED-PRINTABLE","OTHER");


	


	function boMail( $user , $pw , $postfach="INBOX" , $host="localhost" , $port="pop3:110")
 	{
		$this->mailbox="{".$host."/".$port."}".$postfach;
		$this->user=$user;
		$this->pw=$pw;
		return $this->connect();
 	}
 	
 	
   	function connect()
 	{
		if ($this->box = @imap_open( $this->mailbox , $this->user , $this->pw )) {
			$this->connected=true;
			$this->mailsnum = imap_num_msg($this->box);
			return 1;
		} else {
			$this->echoError("Konnte keine Verbindung aufbauen!<br>".imap_last_error());
			return 0;
   		}
 	}
 	
 	function disconnect()
 	{
		if ($this->connected) {
			imap_close($this->box);
			$this->connected=fasle;
		}
 	}
 	
 	
 	function getOverview()
 	{
 		
 		if ($overview = imap_fetch_overview ($this->box,$this->mailsnum.":1")) {
			foreach ($overview as $key=>$val) {
				$head=imap_header($this->box,$val->msgno);
				$ret[$val->msgno]["from"]=$head->fromaddress;
				$elements=imap_mime_header_decode($head->subject);
				for($i=0;$i<count($elements);$i++) {
				       $subject=$elements[$i]->text;
				}
				$ret[$val->msgno]["subject"]=$subject;
				$ret[$val->msgno]["date"]=$head->udate;
				$ret[$val->msgno]["size"]=$val->size;
				$flags=$head->Recent.$head->Unseen.$head->Answered.$head->Deleted.$head->Draft.$head->Flagged;
				$ret[$val->msgno]["flags"]=$flags;
				
			}
			return $ret;
 		}//<-if
 	}
 	
 	
 	function getDetail($msgno)
 	{
 		$this->msgno=$msgno;
		$structure = imap_fetchstructure($this->box,$this->msgno);
		$type=$this->types[$structure->type];
		$parts=$structure->parts;
		$this->parseparts($parts,$type,$structure->subtype);

		
 	}
 	
 	
 	function parseparts($parts,$type,$subtype)
	{
		if (!empty($parts)) {
	  		for ($i=(count($parts)-1);$i>=0;$i--) {
	  			if ($parts[$i]->parts) {
					$this->parseparts($parts[$i]->parts , $this->types[$parts[$i]->type] , $parts[$i]->subtype );
	  			}
	  			$filename=$parts[$i]->parameters[0]->value;
				$this->getPart($i+1 , $this->types[($parts[$i]->type)] , $parts[$i]->subtype , $this->encodings[$parts[$i]->encoding] , $filename);
			}
		} else {
			$this->getPart(1 , $type , $subtype , $encoding);
		}
	

	}
	
	
	function getPart($pid,$type,$subtype,$encoding,$filename="")
	{
		if (strtolower($subtype)=="html") $this->isHTML=1;
		$body=imap_fetchbody($this->box,$this->msgno,$pid);
		if ($encoding=="QUOTED-PRINTABLE" || empty($encoding)) $body=quoted_printable_decode($body);
  		if ($type=="text") {
  			if (strtolower($subtype)=="html") {
  				echo html_entity_decode($body);
  			} else if (!$this->isHTML) {
		   		echo nl2br($body); //$this->mail['body'].= imap_fetchbody($this->box,$this->msgno,$pid);
		   		$this->isHTML=0;
		   	}
		} else if ($type=="image") {
		 	echo "<br>BILD: <img src='".$this->mkAttachement($filename,$encoding,$body)."'>";
        } else if ($type=="application") {
        	$f=$this->mkAttachement($filename,$encoding,$body);
		 	echo "<br>APPLICATION: <a href='$f'>$f</a>";
		 } else {
		 	echo "<B><I>Unbekanntes Format </i>$type/$subtype</b><br>";
		}
	}
 	
 	
 	function mkAttachement($filename,$decode,$data)
	{
		$fh=fopen($filename,"w");
		if ($decode=="BASE64") $data=imap_base64($data);
		fwrite($fh,$data);
		fclose($fh);
		return $filename;
	}
	

	function umlaute($text)
	{
		$text=imap_8bit($text);
		$uml=array("=3DE4"=>"ä" , "=3DC4"=>"Ä" , "=3DFC"=>"ü" , "=3DDC"=>"Ü" , "=3DF6"=>"oe" , "=3DD6"=>"Ö" , "=3DDF"=>"ß" , "=3D20"=>" ");
		foreach ($uml as $code=>$u) {
	  		$text=str_replace($code,$u,$text);
	  	}
		return ($text);
	}

 	
  	function echoError($er)
	{
		echo "<div style='background:darkred;color:white'><b>$er</b></div>";
	}
}


?>
</body>
</html>
Sonst funktioniert eigentlich alles.
 
Warum antwortet denn niemand? :-(

OK, das Script ist vieleicht ein wenig lang um es mal schnell zu überprüfen. Aber vieleicht kann mir ja jemand ein paar Tips geben, wie ich mit multiparts umgehe. Bin noch nicht so ganz durchgestiegen wie das mit den multipart - emails funktioniert.
 
Zuletzt bearbeitet:
Hab mal eine Frage dazu. Bei mir funktioniert die Funktion imap_open() nicht. Warum? Mein PHP-Version ist 4.3.2.2. Wird das vielleicht erst später unterstützt?
 
Hast Du allgemein Probleme mit Anhaengen oder nur bei multipart/alternative-Mails?

Als ich mit meinem Webmailer angefangen hab sind mir diese, wenn ich mich recht erinnere, nur von Outlook Express zugeschickt worden.
Alles andere hat nicht solchen "Unsinn" geschickt. ;)
 
Ich hab die Probleme eigentlich nur mit diesen multipart/alternative-Mails. Die kommen von Oulook-express und auch von Tobit Info Server (soweit ich das testen konnte). Die Anhänge funktionieren eigentlich. Hab ich aber noch nicht 100%ig getestet, da ich ersteinmal wenigstens die Nachricht lesen möchte.

Irgendwie habe ich das noch nicht so genau verstanden, wie das mit den verschiedenen Parts funktioniert, bzw. welchen Sinn die ergeben.

Danke
 
Hier mal die beiden Scripts mit denen ich die Mails lese.
Das sind showmails.php und download-attachment.php.

Ich bin jetzt aber nicht sicher ob ich die ausreichend mit multipart/alternative getestet hab.

showmails.php
PHP:
<?php
function checkbody($body,$struct,$mailbox)
{
	if ($struct->subtype!="PLAIN")
		{
			if ($struct->parts[0]->encoding==3)
				{
					$body=base64_decode($body);
				}
			if ($struct->parts[0]->encoding==4)
				{
					$body=quoted_printable_decode($body);
				}
		}
	else
		{
			if ($struct->encoding==3)
				{
					$body=base64_decode($body);
				}
			if ($struct->encoding==4)
				{
					$body=quoted_printable_decode($body);
				}
		}
	$body=nl2br(htmlentities($body));
	if ($struct->subtype=="MIXED")
		{
			$body.="\n";
			for ($part=1;$part<count($struct->parts);$part++)
				{
					print_r($struct->parts[$part]);
					if ($struct->parts[$part]->type!=2)
						{
							$body.=imap_qprint("\t");
							$body.='<a href="download-attachment.php?mailbox='.$mailbox.'&amp;msgid='.$_GET['show'].'&amp;part='.$part.'">&lt;&lt;'.$struct->parts[$part]->dparameters[0]->value.'&gt;&gt;</a>';
						}
				}
		}
	return $body;
}
$mbox=imap_open("{".$host."/norsh}".$mailbox,$_SESSION['username'],$_SESSION['password']);
if (isset($_GET['show']))
	{
		$struct=imap_fetchstructure($mbox,$_GET['show']);
		$header=imap_header($mbox,$_GET['show']);
		$body=imap_fetchbody($mbox,$_GET['show'],1);
		$body=checkbody($body,$struct,$mailbox);
		echo $body;
	}
else
	{
		if (isset($_GET['send']))
			{
				$header=imap_fetchheader($mbox,$_GET['send']);
				$body=imap_body($mbox,$_GET['send']);
				$header=str_replace("\r\n","\n",$header);
				$body=str_replace("\r\n","\n",$body);
				$startpos=strpos($header,"To: ")+4;
				$endpos=strpos($header,"\n",$startpos);
				$mailto=substr($header,$startpos,$endpos-$startpos);
				$startpos=strpos($header,"Subject: ")+9;
				$endpos=strpos($header,"\n",$startpos);
				$subject=substr($header,$startpos,$endpos-$startpos);
				$header=str_replace("To: ".$mailto."\n","",$header);
				$header=str_replace("Subject: ".$subject."\n","",$header);
				$email=$header.$body;
				imap_mail($mailto,$subject,"",$email);
				imap_clearflag_full($mbox,$_GET['send'],"\\Draft");
				imap_mail_move($mbox,$_GET['send'],SENTFOLDER);
				imap_expunge($mbox);
				header("Location:webmail.php?mailbox=".$mailbox."&subsite=showmails.php");
			}
		if (isset($_POST['sendmails']))
			{
				$keys=array_keys($_POST);
				for ($count=0;$count<count($keys);$count++)
					{
						if (substr($keys[$count],0,8)=="markmail")
							{
								$header=imap_fetchheader($mbox,$_POST[$keys[$count]]);
								$body=imap_body($mbox,$_POST[$keys[$count]]);
								$header=str_replace("\r\n","\n",$header);
								$body=str_replace("\r\n","\n",$body);
								$startpos=strpos($header,"To: ")+4;
								$endpos=strpos($header,"\n",$startpos);
								$mailto=substr($header,$startpos,$endpos-$startpos);
								$startpos=strpos($header,"Subject: ")+9;
								$endpos=strpos($header,"\n",$startpos);
								$subject=substr($header,$startpos,$endpos-$startpos);
								$header=str_replace("To: ".$mailto."\n","",$header);
								$header=str_replace("Subject: ".$subject."\n","",$header);
								$email=$header.$body;
								imap_mail($mailto,$subject,"",$email);
								imap_clearflag_full($mbox,$_POST[$keys[$count]],"\\Draft");
								imap_mail_move($mbox,$_POST[$keys[$count]],SENTFOLDER);
							}
					}
				imap_expunge($mbox);
				header("Location:webmail.php?mailbox=".$mailbox."&subsite=showmails.php");
			}
		if (isset($_GET['undelete']))
			{
				$header=imap_header($mbox,$_GET['undelete']);
				if ($header->Draft=="X")
					{
						imap_mail_move($mbox,$_GET['undelete'],DRAFTFOLDER);
					}
				elseif (isset($header->date))
					{
						imap_mail_move($mbox,$_GET['undelete'],INBOXFOLDER);
					}
				else
					{
						imap_mail_move($mbox,$_GET['undelete'],SENTFOLDER);
					}
				imap_expunge($mbox);
				header("Location:webmail.php?mailbox=".$mailbox."&subsite=showmails.php");
			}
		if (isset($_POST['undeletemails']))
			{
				$keys=array_keys($_POST);
				for ($count=0;$count<count($keys);$count++)
					{
						if (substr($keys[$count],0,8)=="markmail")
							{
								$header=imap_header($mbox,$_POST[$keys[$count]]);
								if ($header->Draft=="X")
									{
										imap_mail_move($mbox,$_POST[$keys[$count]],DRAFTFOLDER);
									}
								elseif (isset($header->date))
									{
										imap_mail_move($mbox,$_POST[$keys[$count]],INBOXFOLDER);
									}
								else
									{
										imap_mail_move($mbox,$_POST[$keys[$count]],SENTFOLDER);
									}
							}
					}
				imap_expunge($mbox);
				header("Location:webmail.php?mailbox=".$mailbox."&subsite=showmails.php");				
			}
		if (isset($_GET['delete']))
			{
				if ($mailbox!=TRASHFOLDER)
					{
						imap_mail_move($mbox,$_GET['delete'],TRASHFOLDER);
					}
				else
					{
						imap_delete($mbox,$_GET['delete']);
					}
				imap_expunge($mbox);
				header("Location:webmail.php?mailbox=".$mailbox."&subsite=showmails.php");
			}
		if (isset($_POST['deletemails']))
			{
				$keys=array_keys($_POST);
				for ($count=0;$count<count($keys);$count++)
					{
						if (substr($keys[$count],0,8)=="markmail")
							{
								if ($mailbox!=TRASHFOLDER)
									{
										imap_mail_move($mbox,$_POST[$keys[$count]],TRASHFOLDER);
									}
								else
									{
										imap_delete($mbox,$_POST[$keys[$count]]);
									}
							}
					}
				imap_expunge($mbox);
				header("Location:webmail.php?mailbox=".$mailbox."&subsite=showmails.php");
			}
		$mboxinfo=imap_mailboxmsginfo($mbox);
		echo $mboxinfo->Nmsgs.' '.gettext("eMails").'<br>';
		echo $mboxinfo->Recent.' '.gettext("recent").'<br>';
		echo $mboxinfo->Unread.' '.gettext("unread").'<br>';
		echo '<form method="post" action="webmail.php?mailbox='.$mailbox.'&amp;subsite=showmails.php">';
		echo '<table>';
		echo '<tr><th colspan="8">'.$mailbox.'</th></tr>';
		echo '<tr>';
		echo '<th>&nbsp;</th>';
		echo '<th>'.gettext("From").'</th>';
		echo '<th>'.gettext("To").'</th>';
		echo '<th>'.gettext("Subject").'</th>';
		echo '<th>'.gettext("Date").'</th>';
		echo '<th colspan="3">'.gettext("Action").'</th>';
		echo '</tr>';
		for ($msgcount=1;$msgcount<=$mboxinfo->Nmsgs;$msgcount++)
			{
				$header=imap_header($mbox,$msgcount);
/*echo '<tr>';
echo '<td colspan="6">';
var_dump($header);
echo '</td>';
echo '</tr>';*/
				if (($header->Recent=="N") || ($header->Unseen=="U"))
					{
						$style="unread";
					}
				else
					{
						$style="read";
					}
				echo '<tr>';
				echo '<td><input type="checkbox" name="markmail'.trim($header->Msgno).'" value="'.trim($header->Msgno).'"></td>';
				echo '<td class="'.$style.'"><a href="webmail.php?mailbox='.$mailbox.'&amp;subsite=showmails.php&amp;show='.trim($header->Msgno).'">';
				if (isset($header->from[0]->personal))
					{
						echo $header->from[0]->personal.' &lt;'.$header->from[0]->mailbox.'@'.$header->from[0]->host.'&gt;';
					}
				else
					{
						echo $header->from[0]->mailbox.'@'.$header->from[0]->host;
					}
				echo '</a></td>';
				echo '<td class="'.$style.'"><a href="webmail.php?mailbox='.$mailbox.'&amp;subsite=showmails.php&amp;show='.trim($header->Msgno).'">';
				if (isset($header->to[0]->personal))
					{
						echo $header->to[0]->personal.' &lt;'.$header->to[0]->mailbox.'@'.$header->to[0]->host.'&gt;';
					}
				else
					{
						echo $header->to[0]->mailbox.'@'.$header->to[0]->host;
					}
				echo '</a></td>';
				echo '<td class="'.$style.'"><a href="webmail.php?mailbox='.$mailbox.'&amp;subsite=showmails.php&amp;show='.trim($header->Msgno).'">'.$header->subject.'</a></td>';
				if (isset($header->date))
					{
						echo '<td>'.$header->date.'</td>';
					}
				else
					{
						echo '<td>'.$header->MailDate.'</td>';
					}
				if ($mailbox==INBOXFOLDER)
					{
						echo '<td><a href="webmail.php?mailbox='.$mailbox.'&amp;subsite=sendmail.php&amp;replyto='.trim($header->Msgno).'">';
						echo gettext("Reply");
						echo '</a></td>';
					}
				elseif ($mailbox==DRAFTFOLDER)
					{
						echo '<td><a href="webmail.php?mailbox='.$mailbox.'&amp;subsite=sendmail.php&amp;edit='.trim($header->Msgno).'">';
						echo gettext("Edit");
						echo '</a></td>';
					}
				elseif ($mailbox==TRASHFOLDER)
					{
						echo '<td><a href="webmail.php?mailbox='.$mailbox.'&amp;subsite=showmails.php&amp;undelete='.trim($header->Msgno).'">';
						echo gettext("Undelete");
						echo '</a></td>';					
					}
				if (($mailbox==INBOXFOLDER) || ($mailbox==SENTFOLDER))
					{
						echo '<td><a href="webmail.php?mailbox='.$mailbox.'&amp;subsite=sendmail.php&amp;forward='.trim($header->Msgno).'">';
						echo gettext("Forward");
						echo '</a></td>';
					}
				elseif ($mailbox==DRAFTFOLDER)
					{
						echo '<td><a href="webmail.php?mailbox='.$mailbox.'&amp;subsite=showmails.php&amp;send='.trim($header->Msgno).'">';
						echo gettext("Send");
						echo '</a></td>';
					}
				echo '<td><a href="webmail.php?mailbox='.$mailbox.'&amp;subsite=showmails.php&amp;delete='.trim($header->Msgno).'">';
				echo gettext("Delete");
				echo '</a></td>';
				echo '</tr>';
			}
		echo '</table>';
		echo '<input type="submit" name="deletemails" value="';
		echo gettext("Delete selected eMails");
		echo '">';
		if ($mailbox==TRASHFOLDER)
			{
				echo '<input type="submit" name="undeletemails" value="';
				echo gettext("Undelete selected eMails");
				echo '">';
			}
		if ($mailbox==DRAFTFOLDER)
			{
				echo '<input type="submit" name="sendmails" value="';
				echo gettext("Send selected eMails");
				echo '">';
			}
		echo '</form>';
	}
imap_close($mbox);
?>
download-attachment.php
PHP:
<?php
ob_start();
session_start();
require("config.php");
if ((isset($_GET['msgid'])) && (isset($_GET['part'])))
	{
		$mbox=imap_open("{".$host."/norsh}".$mailbox,$_SESSION['username'],$_SESSION['password']);
		$struct=imap_fetchstructure($mbox,$_GET['msgid']);
		$body=imap_fetchbody($mbox,$_GET['msgid'],$_GET['part']+1);
		imap_close($mbox);
		if ($struct->parts[$_GET['part']]->type==0)
			{
				$content_type="text";
			}
		elseif ($struct->parts[$_GET['part']]->type==4)
			{
				$content_type="audio";
			}
		elseif ($struct->parts[$_GET['part']]->type==5)
			{
				$content_type="image";
			}
		//elseif ($struct->parts[$_GET['part']]->type==3)
		else
			{
				$content_type="application";
			}
		$content_type.="/".strtolower($struct->parts[$_GET['part']]->subtype);
		$content_disposition=strtolower($struct->parts[$_GET['part']]->disposition);
		//header("Content-Type: application/octet-stream");
		header("Content-Type: ".$content_type);
		//header("Content-Disposition: attachment; filename=\"".$struct->parts[$_GET['part']]->dparameters[0]->value."\"");
		header("Content-Disposition: ".$content_disposition."; filename=\"".$struct->parts[$_GET['part']]->dparameters[0]->value."\"");
		if ($struct->parts[$_GET['part']]->encoding==3)
			{
				$body=base64_decode($body);
			}
		if ($struct->parts[$_GET['part']]->encoding==4)
			{
				$body=quoted_printable_decode($body);
			}
		echo $body;
	}
ob_end_flush();
?>
 
Erstmal Danke für die schnelle Antwort.
Ich werde mir das alles mal in Ruhe anschauen. Aber ich habe gesehen, daß du nur die Subtypes abfrägst.

der MIME-Type multipart/alternative sagt doch, das es mehrere Parts gibt. Genau wie multipart/mixed. Aber wo liegt dann der Unterschied?
 
Wenn ich mich recht erinnere war multipart/alternative aehnlich wie multipart/mixed. Nur dass der erste Anhang quasi die Mail als HTML war.

Ganz sicher bin ich da aber nicht. Ist schon eine Weile her, dass ich damit rumprobiert hab.
 
Zurück