-
-
Save vyatri/939427 to your computer and use it in GitHub Desktop.
<?php | |
/** | |
* Model of an Attachment | |
*/ | |
class MimeMailParser_attachment { | |
/** | |
* @var $filename Filename | |
*/ | |
public $filename; | |
/** | |
* @var $content_type Mime Type | |
*/ | |
public $content_type; | |
/** | |
* @var $content File Content | |
*/ | |
private $content; | |
/** | |
* @var $extension Filename extension | |
*/ | |
private $extension; | |
/** | |
* @var $content_disposition Content-Disposition (attachment or inline) | |
*/ | |
public $content_disposition; | |
/** | |
* @var $headers An Array of the attachment headers | |
*/ | |
public $headers; | |
private $stream; | |
public function __construct($filename, $content_type, $stream, $content_disposition = 'attachment', $headers = array()) { | |
$this->filename = $filename; | |
$this->content_type = $content_type; | |
$this->stream = $stream; | |
$this->content = null; | |
$this->content_disposition = $content_disposition; | |
$this->headers = $headers; | |
} | |
/** | |
* retrieve the attachment filename | |
* @return String | |
*/ | |
public function getFilename() { | |
return $this->filename; | |
} | |
/** | |
* Retrieve the Attachment Content-Type | |
* @return String | |
*/ | |
public function getContentType() { | |
return $this->content_type; | |
} | |
/** | |
* Retrieve the Attachment Content-Disposition | |
* @return String | |
*/ | |
public function getContentDisposition() { | |
return $this->content_disposition; | |
} | |
/** | |
* Retrieve the Attachment Headers | |
* @return String | |
*/ | |
public function getHeaders() { | |
return $this->headers; | |
} | |
/** | |
* Retrieve the file extension | |
* @return String | |
*/ | |
public function getFileExtension() { | |
if (!$this->extension) { | |
$ext = substr(strrchr($this->filename, '.'), 1); | |
if ($ext == 'gz') { | |
// special case, tar.gz | |
// todo: other special cases? | |
$ext = preg_match("/\.tar\.gz$/i", $ext) ? 'tar.gz' : 'gz'; | |
} | |
$this->extension = $ext; | |
} | |
return $this->extension; | |
} | |
/** | |
* Read the contents a few bytes at a time until completed | |
* Once read to completion, it always returns false | |
* @return String | |
* @param $bytes Int[optional] | |
*/ | |
public function read($bytes = 2082) { | |
return feof($this->stream) ? false : fread($this->stream, $bytes); | |
} | |
/** | |
* Retrieve the file content in one go | |
* Once you retreive the content you cannot use MimeMailParser_attachment::read() | |
* @return String | |
*/ | |
public function getContent() { | |
if ($this->content === null) { | |
fseek($this->stream, 0); | |
while(($buf = $this->read()) !== false) { | |
$this->content .= $buf; | |
} | |
} | |
return $this->content; | |
} | |
/** | |
* Allow the properties | |
* MimeMailParser_attachment::$name, | |
* MimeMailParser_attachment::$extension | |
* to be retrieved as public properties | |
* @param $name Object | |
*/ | |
public function __get($name) { | |
if ($name == 'content') { | |
return $this->getContent(); | |
} else if ($name == 'extension') { | |
return $this->getFileExtension(); | |
} | |
return null; | |
} | |
} | |
?> |
<?php | |
require_once('attachment.class.php'); | |
/** | |
* Fast Mime Mail parser Class using PHP's MailParse Extension | |
* @author [email protected] | |
* @url http://www.fijiwebdesign.com/ | |
* @license http://creativecommons.org/licenses/by-sa/3.0/us/ | |
* @version $Id$ | |
*/ | |
class MimeMailParser { | |
/** | |
* PHP MimeParser Resource ID | |
*/ | |
public $resource; | |
/** | |
* A file pointer to email | |
*/ | |
public $stream; | |
/** | |
* A text of an email | |
*/ | |
public $data; | |
/** | |
* Stream Resources for Attachments | |
*/ | |
public $attachment_streams; | |
/** | |
* Inialize some stuff | |
* @return | |
*/ | |
public function __construct() { | |
$this->attachment_streams = array(); | |
} | |
/** | |
* Free the held resouces | |
* @return void | |
*/ | |
public function __destruct() { | |
// clear the email file resource | |
if (is_resource($this->stream)) { | |
fclose($this->stream); | |
} | |
// clear the MailParse resource | |
if (is_resource($this->resource)) { | |
mailparse_msg_free($this->resource); | |
} | |
// remove attachment resources | |
foreach($this->attachment_streams as $stream) { | |
fclose($stream); | |
} | |
} | |
/** | |
* Set the file path we use to get the email text | |
* @return Object MimeMailParser Instance | |
* @param $mail_path Object | |
*/ | |
public function setPath($path) { | |
// should parse message incrementally from file | |
$this->resource = mailparse_msg_parse_file($path); | |
$this->stream = fopen($path, 'r'); | |
$this->parse(); | |
return $this; | |
} | |
/** | |
* Set the Stream resource we use to get the email text | |
* @return Object MimeMailParser Instance | |
* @param $stream Resource | |
*/ | |
public function setStream($stream) { | |
// streams have to be cached to file first | |
if (get_resource_type($stream) == 'stream') { | |
$tmp_fp = tmpfile(); | |
if ($tmp_fp) { | |
while(!feof($stream)) { | |
fwrite($tmp_fp, fread($stream, 2028)); | |
} | |
fseek($tmp_fp, 0); | |
$this->stream =& $tmp_fp; | |
} else { | |
throw new Exception('Could not create temporary files for attachments. Your tmp directory may be unwritable by PHP.'); | |
return false; | |
} | |
fclose($stream); | |
} else { | |
$this->stream = $stream; | |
} | |
$this->resource = mailparse_msg_create(); | |
// parses the message incrementally low memory usage but slower | |
while(!feof($this->stream)) { | |
mailparse_msg_parse($this->resource, fread($this->stream, 2082)); | |
} | |
$this->parse(); | |
return $this; | |
} | |
/** | |
* Set the email text | |
* @return Object MimeMailParser Instance | |
* @param $data String | |
*/ | |
public function setText($data) { | |
$this->resource = mailparse_msg_create(); | |
// does not parse incrementally, fast memory hog might explode | |
mailparse_msg_parse($this->resource, $data); | |
$this->data = $data; | |
$this->parse(); | |
return $this; | |
} | |
/** | |
* Parse the Message into parts | |
* @return void | |
* @private | |
*/ | |
private function parse() { | |
$structure = mailparse_msg_get_structure($this->resource); | |
$this->parts = array(); | |
foreach($structure as $part_id) { | |
$part = mailparse_msg_get_part($this->resource, $part_id); | |
$this->parts[$part_id] = mailparse_msg_get_part_data($part); | |
} | |
} | |
/** | |
* Retrieve the Email Headers | |
* @return Array | |
*/ | |
public function getHeaders() { | |
if (isset($this->parts[1])) { | |
return $this->getPartHeaders($this->parts[1]); | |
} else { | |
throw new Exception('MimeMailParser::setPath() or MimeMailParser::setText() must be called before retrieving email headers.'); | |
} | |
return false; | |
} | |
/** | |
* Retrieve the raw Email Headers | |
* @return string | |
*/ | |
public function getHeadersRaw() { | |
if (isset($this->parts[1])) { | |
return $this->getPartHeaderRaw($this->parts[1]); | |
} else { | |
throw new Exception('MimeMailParser::setPath() or MimeMailParser::setText() must be called before retrieving email headers.'); | |
} | |
return false; | |
} | |
/** | |
* Retrieve a specific Email Header | |
* @return String | |
* @param $name String Header name | |
*/ | |
public function getHeader($name) { | |
if (isset($this->parts[1])) { | |
$headers = $this->getPartHeaders($this->parts[1]); | |
if (isset($headers[$name])) { | |
return $headers[$name]; | |
} | |
} else { | |
throw new Exception('MimeMailParser::setPath() or MimeMailParser::setText() must be called before retrieving email headers.'); | |
} | |
return false; | |
} | |
/** | |
* Returns the email message body in the specified format | |
* @return Mixed String Body or False if not found | |
* @param $type Object[optional] | |
*/ | |
public function getMessageBody($type = 'text') { | |
$body = false; | |
$mime_types = array( | |
'text'=> 'text/plain', | |
'html'=> 'text/html' | |
); | |
if (in_array($type, array_keys($mime_types))) { | |
foreach($this->parts as $part) { | |
if ($this->getPartContentType($part) == $mime_types[$type]) { | |
$headers = $this->getPartHeaders($part); | |
$body = $this->decode($this->getPartBody($part), array_key_exists('content-transfer-encoding', $headers) ? $headers['content-transfer-encoding'] : ''); | |
} | |
} | |
} else { | |
throw new Exception('Invalid type specified for MimeMailParser::getMessageBody. "type" can either be text or html.'); | |
} | |
return $body; | |
} | |
/** | |
* get the headers for the message body part. | |
* @return Array | |
* @param $type Object[optional] | |
*/ | |
public function getMessageBodyHeaders($type = 'text') { | |
$headers = false; | |
$mime_types = array( | |
'text'=> 'text/plain', | |
'html'=> 'text/html' | |
); | |
if (in_array($type, array_keys($mime_types))) { | |
foreach($this->parts as $part) { | |
if ($this->getPartContentType($part) == $mime_types[$type]) { | |
$headers = $this->getPartHeaders($part); | |
} | |
} | |
} else { | |
throw new Exception('Invalid type specified for MimeMailParser::getMessageBody. "type" can either be text or html.'); | |
} | |
return $headers; | |
} | |
/** | |
* Returns the attachments contents in order of appearance | |
* @return Array | |
* @param $type Object[optional] | |
*/ | |
public function getAttachments() { | |
$attachments = array(); | |
$dispositions = array("attachment","inline"); | |
foreach($this->parts as $part) { | |
$disposition = $this->getPartContentDisposition($part); | |
if (in_array($disposition, $dispositions)) { | |
$attachments[] = new MimeMailParser_attachment( | |
$part['disposition-filename'], | |
$this->getPartContentType($part), | |
$this->getAttachmentStream($part), | |
$disposition, | |
$this->getPartHeaders($part) | |
); | |
} | |
} | |
return $attachments; | |
} | |
/** | |
* Return the Headers for a MIME part | |
* @return Array | |
* @param $part Array | |
*/ | |
private function getPartHeaders($part) { | |
if (isset($part['headers'])) { | |
return $part['headers']; | |
} | |
return false; | |
} | |
/** | |
* Return a Specific Header for a MIME part | |
* @return Array | |
* @param $part Array | |
* @param $header String Header Name | |
*/ | |
private function getPartHeader($part, $header) { | |
if (isset($part['headers'][$header])) { | |
return $part['headers'][$header]; | |
} | |
return false; | |
} | |
/** | |
* Return the ContentType of the MIME part | |
* @return String | |
* @param $part Array | |
*/ | |
private function getPartContentType($part) { | |
if (isset($part['content-type'])) { | |
return $part['content-type']; | |
} | |
return false; | |
} | |
/** | |
* Return the Content Disposition | |
* @return String | |
* @param $part Array | |
*/ | |
private function getPartContentDisposition($part) { | |
if (isset($part['content-disposition'])) { | |
return $part['content-disposition']; | |
} | |
return false; | |
} | |
/** | |
* Retrieve the raw Header of a MIME part | |
* @return String | |
* @param $part Object | |
*/ | |
private function getPartHeaderRaw(&$part) { | |
$header = ''; | |
if ($this->stream) { | |
$header = $this->getPartHeaderFromFile($part); | |
} else if ($this->data) { | |
$header = $this->getPartHeaderFromText($part); | |
} else { | |
throw new Exception('MimeMailParser::setPath() or MimeMailParser::setText() must be called before retrieving email parts.'); | |
} | |
return $header; | |
} | |
/** | |
* Retrieve the Body of a MIME part | |
* @return String | |
* @param $part Object | |
*/ | |
private function getPartBody(&$part) { | |
$body = ''; | |
if ($this->stream) { | |
$body = $this->getPartBodyFromFile($part); | |
} else if ($this->data) { | |
$body = $this->getPartBodyFromText($part); | |
} else { | |
throw new Exception('MimeMailParser::setPath() or MimeMailParser::setText() must be called before retrieving email parts.'); | |
} | |
return $body; | |
} | |
/** | |
* Retrieve the Header from a MIME part from file | |
* @return String Mime Header Part | |
* @param $part Array | |
*/ | |
private function getPartHeaderFromFile(&$part) { | |
$start = $part['starting-pos']; | |
$end = $part['starting-pos-body']; | |
fseek($this->stream, $start, SEEK_SET); | |
$header = fread($this->stream, $end-$start); | |
return $header; | |
} | |
/** | |
* Retrieve the Body from a MIME part from file | |
* @return String Mime Body Part | |
* @param $part Array | |
*/ | |
private function getPartBodyFromFile(&$part) { | |
$start = $part['starting-pos-body']; | |
$end = $part['ending-pos-body']; | |
fseek($this->stream, $start, SEEK_SET); | |
$body = fread($this->stream, $end-$start); | |
return $body; | |
} | |
/** | |
* Retrieve the Header from a MIME part from text | |
* @return String Mime Header Part | |
* @param $part Array | |
*/ | |
private function getPartHeaderFromText(&$part) { | |
$start = $part['starting-pos']; | |
$end = $part['starting-pos-body']; | |
$header = substr($this->data, $start, $end-$start); | |
return $header; | |
} | |
/** | |
* Retrieve the Body from a MIME part from text | |
* @return String Mime Body Part | |
* @param $part Array | |
*/ | |
private function getPartBodyFromText(&$part) { | |
$start = $part['starting-pos-body']; | |
$end = $part['ending-pos-body']; | |
$body = substr($this->data, $start, $end-$start); | |
return $body; | |
} | |
/** | |
* Read the attachment Body and save temporary file resource | |
* @return String Mime Body Part | |
* @param $part Array | |
*/ | |
private function getAttachmentStream(&$part) { | |
$temp_fp = tmpfile(); | |
array_key_exists('content-transfer-encoding', $part['headers']) ? $encoding = $part['headers']['content-transfer-encoding'] : $encoding = ''; | |
if ($temp_fp) { | |
if ($this->stream) { | |
$start = $part['starting-pos-body']; | |
$end = $part['ending-pos-body']; | |
fseek($this->stream, $start, SEEK_SET); | |
$len = $end-$start; | |
$written = 0; | |
$write = 2028; | |
$body = ''; | |
while($written < $len) { | |
if (($written+$write < $len )) { | |
$write = $len - $written; | |
} | |
$part = fread($this->stream, $write); | |
fwrite($temp_fp, $this->decode($part, $encoding)); | |
$written += $write; | |
} | |
} else if ($this->data) { | |
$attachment = $this->decode($this->getPartBodyFromText($part), $encoding); | |
fwrite($temp_fp, $attachment, strlen($attachment)); | |
} | |
fseek($temp_fp, 0, SEEK_SET); | |
} else { | |
throw new Exception('Could not create temporary files for attachments. Your tmp directory may be unwritable by PHP.'); | |
return false; | |
} | |
return $temp_fp; | |
} | |
/** | |
* Decode the string depending on encoding type. | |
* @return String the decoded string. | |
* @param $encodedString The string in its original encoded state. | |
* @param $encodingType The encoding type from the Content-Transfer-Encoding header of the part. | |
*/ | |
private function decode($encodedString, $encodingType) { | |
if (strtolower($encodingType) == 'base64') { | |
return base64_decode($encodedString); | |
} else if (strtolower($encodingType) == 'quoted-printable') { | |
return quoted_printable_decode($encodedString); | |
} else { | |
return $encodedString; | |
} | |
} | |
} | |
?> |
<?php | |
require_once('MimeMailParser.class.php'); | |
$path = 'path/to/mail.txt'; | |
$Parser = new MimeMailParser(); | |
$Parser->setPath($path); | |
$to = $Parser->getHeader('to'); | |
$from = $Parser->getHeader('from'); | |
$subject = $Parser->getHeader('subject'); | |
$text = $Parser->getMessageBody('text'); | |
$html = $Parser->getMessageBody('html'); | |
$attachments = $Parser->getAttachments(); | |
// attachment processing | |
$save_dir = '/path/to/save/attachments/'; | |
foreach($attachments as $attachment) { | |
// get the attachment name | |
$filename = $attachment->filename; | |
// write the file to the directory you want to save it in | |
if ($fp = fopen($save_dir.$filename, 'w')) { | |
while($bytes = $attachment->read()) { | |
fwrite($fp, $bytes); | |
} | |
fclose($fp); | |
} | |
} | |
?> |
@topedge - you seem to not have http://php.net/mailparse installed.
when I echo:
$from = $Parser->getHeader('from');
it echos out the name
of the email sender, but I want to get the email address
of the email sender, this also happens to:
$to = $Parser->getHeader('to');
How can I get the email address
and not the names?
ty
@BEHZ4D, I would try getHeaders()
or getHeadersRaw()
to see if the data is in there. Perhaps mailparse has trouble with email addresses.
nice work
It was very useful
thanks vyatri
Hi,
I need to get the whole content of the email, as to make a back-up.
Is there any way to accomplish this?
I thought that $Parser->resource could gave me the content but it's not like that
How can I replace within $html the cid url for embedded images with real url from the $save_dir
Call to undefined function mailparse_msg_parse_file() in /home/..../public_html/MimeMailParser.class.php on line 68