@ 2018-07-04T21:28:05Z <?php
class PlancakeEmailParser {
const PLAINTEXT = 1;
const HTML = 2;
/**
*
* @var boolean
*/
private $isImapExtensionAvailable = false;
/**
*
* @var string
*/
private $emailRawContent;
/**
*
* @var associative array
*/
protected $rawFields;
/**
*
* @var array of string (each element is a line)
*/
protected $rawBodyLines;
/**
*
* @param string $emailRawContent
*/
public function __construct($emailRawContent) {
$this->emailRawContent = $emailRawContent;
$this->extractHeadersAndRawBody();
if (function_exists('imap_open')) {
$this->isImapExtensionAvailable = true;
}
}
private function extractHeadersAndRawBody()
{
$lines = preg_split("/(\r?\n|\r)/", $this->emailRawContent);
$currentHeader = '';
$i = 0;
foreach ($lines as $line)
{
if(self::isNewLine($line))
{
// end of headers
$this->rawBodyLines = array_slice($lines, $i);
break;
}
if ($this->isLineStartingWithPrintableChar($line)) // start of new header
{
preg_match('/([^:]+): ?(.*)$/', $line, $matches);
$newHeader = strtolower($matches[1]);
$value = $matches[2];
$this->rawFields[$newHeader] = $value;
$currentHeader = $newHeader;
}
else // more lines related to the current header
{
if ($currentHeader) { // to prevent notice from empty lines
$this->rawFields[$currentHeader] .= substr($line, 1);
}
}
$i++;
}
}
/**
*
* @return string (in UTF-8 format)
* @throws Exception if a subject header is not found
*/
public function getSubject()
{
if (!isset($this->rawFields['subject']))
{
throw new Exception("Couldn't find the subject of the email");
}
$ret = '';
if ($this->isImapExtensionAvailable) {
foreach (imap_mime_header_decode($this->rawFields['subject']) as $h) { // subject can span into several lines
$charset = ($h->charset == 'default') ? 'US-ASCII' : $h->charset;
$ret .= iconv($charset, "UTF-8//TRANSLIT", $h->text);
}
} else {
$ret = utf8_encode(iconv_mime_decode($this->rawFields['subject']));
}
return $ret;
}
/**
*
* @return array
*/
public function getCc()
{
if (!isset($this->rawFields['cc']))
{
return array();
}
return explode(',', $this->rawFields['cc']);
}
/**
*
* @return array
* @throws Exception if a to header is not found or if there are no recipient
*/
public function getTo()
{
if ( (!isset($this->rawFields['to'])) || (!count($this->rawFields['to'])))
{
throw new Exception("Couldn't find the recipients of the email");
}
return explode(',', $this->rawFields['to']);
}
/**
* return string - UTF8 encoded
*
* Example of an email body
*
--0016e65b5ec22721580487cb20fd
Content-Type: text/plain; charset=ISO-8859-1
Hi all. I am new to Android development.
Please help me.
--
My signature
email: myemail@gmail.com
web: http://www.example.com
--0016e65b5ec22721580487cb20fd
Content-Type: text/html; charset=ISO-8859-1
*/
public function getBody($returnType=self::PLAINTEXT)
{
$body = '';
$detectedContentType = false;
$contentTransferEncoding = null;
$charset = 'ASCII';
$waitingForContentStart = true;
if ($returnType == self::HTML)
$contentTypeRegex = '/^Content-Type: ?text\/html/i';
else
$contentTypeRegex = '/^Content-Type: ?text\/plain/i';
// there could be more than one boundary
preg_match_all('/boundary=(.*)/', $this->emailRawContent, $matches);
$boundaries = $matches[1];
//preg_match('!boundary=(.*)$!mi', $this->emailRawContent, $matches); //*Removed 17Feb2017 MC
//preg_match('/boundary=(.*)/', $this->emailRawContent, $matches); //Previous line was not catching boundaries properly
//$boundary = str_replace(array("'", '"'), '', $matches[1]);
// sometimes boundaries are delimited by quotes - we want to remove them
foreach($boundaries as $i => $v) {
$boundaries[$i] = str_replace(array("'", '"'), '', $v);
}
foreach ($this->rawBodyLines as $line) {
if (!$detectedContentType) {
if (preg_match($contentTypeRegex, $line, $matches)) {
$detectedContentType = true;
}
if(preg_match('/charset=(.*)/i', $line, $matches)) {
$charset = strtoupper(trim($matches[1], '"'));
}
} else if ($detectedContentType && $waitingForContentStart) {
if(preg_match('/charset=(.*)/i', $line, $matches)) {
$charset = strtoupper(trim($matches[1], '"'));
}
if ($contentTransferEncoding == null && preg_match('/^Content-Transfer-Encoding: ?(.*)/i', $line, $matches)) {
$contentTransferEncoding = strtoupper($matches[1]); //MC 04Nov16: Added strtoupper
}
if (self::isNewLine($line)) {
$waitingForContentStart = false;
}
} else { // ($detectedContentType && !$waitingForContentStart)
// collecting the actual content until we find the delimiter
// if the delimited is AAAAA, the line will be --AAAAA - that's why we use substr
if (is_array($boundaries)) {
if (in_array(substr($line, 2), $boundaries)) { // found the delimiter
break;
}
} elseif (strpos($line, $boundary)) {
break;
}
$body .= $line . "\n";
}
}
if (!$detectedContentType)
{
// if here, we missed the text/plain content-type (probably it was
// in the header), thus we assume the whole body is what we are after
$body = implode("\n", $this->rawBodyLines);
}
// removing trailing new lines
$body = preg_replace('/((\r?\n)*)$/', '', $body);
if ($contentTransferEncoding == 'BASE64') //MC 04Nov16: changed base64 to BASE64
$body = base64_decode($body, true);
else if ($contentTransferEncoding == 'QUOTED-PRINTABLE') //MC 04Nov16: changed quoted-printable to QUOTED-PRINTABLE
$body = quoted_printable_decode($body);
if($charset != 'UTF-8') {
// FORMAT=FLOWED, despite being popular in emails, it is not
// supported by iconv
$charset = str_replace("FORMAT=FLOWED", "", $charset);
$body = iconv($charset, 'UTF-8//TRANSLIT', $body);
if ($body === FALSE) { // iconv returns FALSE on failure
$body = utf8_encode($body);
}
}
return $body;
}
/**
* @return string - UTF8 encoded
*
*/
public function getPlainBody()
{
return $this->getBody(self::PLAINTEXT);
}
/**
* return string - UTF8 encoded
*/
public function getHTMLBody()
{
return $this->getBody(self::HTML);
}
/**
* N.B.: if the header doesn't exist an empty string is returned
*
* @param string $headerName - the header we want to retrieve
* @return string - the value of the header
*/
public function getHeader($headerName)
{
$headerName = strtolower($headerName);
if (isset($this->rawFields[$headerName]))
{
return $this->rawFields[$headerName];
}
return '';
}
/**
*
* @param string $line
* @return boolean
*/
public static function isNewLine($line)
{
$line = str_replace("\r", '', $line);
$line = str_replace("\n", '', $line);
return (strlen($line) === 0);
}
/**
*
* @param string $line
* @return boolean
*/
private function isLineStartingWithPrintableChar($line)
{
return preg_match('/^[A-Za-z]/', $line);
}
}
$rawEmail = "From 8083199272@mms.att.net Tue Jul 03 19:10:49 2018\nReceived: from stcotaapp-apps-sfm1a.mobile.att.net ([166.216.152.37]:50252 helo=stcceg-mtmta01.wnsnet.attws.com)\n by gator3049.hostgator.com with esmtps (TLSv1:DHE-RSA-AES128-SHA:128)\n (Exim 4.91)\n (envelope-from <8083199272@mms.att.net>)\n id 1faVNh-002Xxu-GQ\n for bosque@firepage.org; Tue, 03 Jul 2018 19:10:49 -0500\nReceived: from alnnms01 ([107.79.70.30])\n by stcceg-mtmta01.wnsnet.attws.com with bizsmtp\n id 69421y01Y0fBW5X01QAe4c; Tue, 03 Jul 2018 19:10:38 -0500\nMessage-ID: <69421y01Y0fBW5X01QAe4c@txt.att.net>\nIn-Reply-To: 1383951446.40200251530663038311.JavaMail.nems@alnnms01\nX-Mms-Message-Type: m-send-req\nX-Mms-Transaction-Id: T16462a1a936\nX-Mms-MMS-Version: 1.2\nTo: bosque@firepage.org\nX-Mms-Message-Class: Personal\nX-Mms-Priority: Normal\nX-Mms-Delivery-Report: No\nX-Mms-Read-Reply: No\nFrom: 8083199272@mms.att.net\nDate: Tue, 3 Jul 2018 19:10:38 -0500 (CDT)\nX-Mms-Sender-Visibility: Show\nContent-Type: multipart/mixed; \n boundary=\"----=_Part_1669496_1731281007.1530663038311\"\nMIME-Version: 1.0\nDKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=mms.att.net;\n s=EMG20171113; t=1530663038;\n bh=+kwzoNYvPgMRHfPJi5CwsNVIk5NlSAOY1AHbjrbjBAI=;\n h=In-Reply-To:To:From:Date;\n b=nMIh249YCq/Er2msND65RSC4HgQpbI3KtVOJ0CvZO3rud6mxY44a17RdeRpwLa3YT\n QPWxVW8QVZtD8/Bc4Tpf2DqGjOsR92pQRP9w79zXSssG1pZ0vgDeLldhF92hkj3n/5\n dG2/1jOaMqO4MvIhyX4U5+dp8EI/2xPbrkAu1Wm9LmJuMCJ3eGckyi7Zfk3x4+P1kx\n W5KEBEOi0FPyHIJD/pTmZJe5n179CUFToz+CKgjtNeFH+kkak8NUUx+GCHgL49030A\n jbw53rDN+Z2g9Ts4bYx63Ywf1zX0ZRo0gwXAFTeTY6KbGgJcXNVfWxVVVY27GGtRO6\n xExmhRGYpR6Tg==\n\n------=_Part_1669496_1731281007.1530663038311\nContent-Type: text/plain; charset=UTF-8\nContent-ID: <text_1530663119159.txt>\nContent-Location: text_1530663119159.txt\nContent-Transfer-Encoding: BASE64\n\nVGVzdCBwYWdlIGltIGRyaXZpbmcgdGVzdCBwYWdl\n------=_Part_1669496_1731281007.1530663038311--\n\n\n";
$emailParser = new PlancakeEmailParser($rawEmail);
echo print_r($emailParser->getPlainBody());
?>
Enable javascript to submit You have javascript disabled. You will not be able to edit any code.
Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).
Version System time (s) User time (s) Memory (MiB) 8.3.4 0.006 0.010 19.25 8.3.3 0.012 0.003 19.01 8.3.2 0.006 0.003 19.40 8.3.1 0.006 0.003 23.52 8.3.0 0.003 0.005 23.65 8.2.17 0.018 0.003 22.96 8.2.16 0.007 0.010 19.52 8.2.15 0.008 0.000 24.18 8.2.14 0.007 0.000 24.66 8.2.13 0.000 0.008 22.33 8.2.12 0.004 0.004 26.35 8.2.11 0.009 0.009 21.23 8.2.10 0.009 0.003 18.14 8.2.9 0.008 0.000 19.34 8.2.8 0.003 0.005 17.97 8.2.7 0.005 0.005 18.15 8.2.6 0.008 0.000 18.17 8.2.5 0.003 0.006 18.10 8.2.4 0.004 0.004 19.24 8.2.3 0.004 0.008 19.35 8.2.2 0.004 0.004 18.11 8.2.1 0.006 0.003 18.23 8.2.0 0.008 0.000 19.45 8.1.27 0.005 0.003 21.95 8.1.26 0.000 0.008 26.35 8.1.25 0.004 0.004 28.09 8.1.24 0.007 0.003 22.54 8.1.23 0.008 0.003 19.23 8.1.22 0.000 0.008 17.79 8.1.21 0.004 0.004 18.77 8.1.20 0.007 0.003 17.60 8.1.19 0.003 0.007 17.50 8.1.18 0.009 0.000 18.10 8.1.17 0.008 0.000 18.91 8.1.16 0.000 0.008 19.00 8.1.15 0.000 0.008 19.05 8.1.14 0.000 0.009 17.82 8.1.13 0.000 0.007 19.11 8.1.12 0.000 0.008 17.63 8.1.11 0.008 0.000 17.66 8.1.10 0.004 0.004 17.63 8.1.9 0.003 0.006 17.65 8.1.8 0.010 0.000 17.60 8.1.7 0.013 0.000 17.64 8.1.6 0.006 0.003 17.66 8.1.5 0.004 0.004 17.75 8.1.4 0.005 0.003 17.64 8.1.3 0.006 0.003 17.90 8.1.2 0.003 0.006 17.88 8.1.1 0.004 0.004 17.76 8.1.0 0.005 0.003 17.71 8.0.30 0.005 0.003 18.90 8.0.29 0.007 0.002 17.00 8.0.28 0.000 0.007 18.55 8.0.27 0.004 0.004 17.30 8.0.26 0.000 0.007 17.27 8.0.25 0.004 0.004 17.24 8.0.24 0.003 0.007 17.29 8.0.23 0.004 0.004 17.25 8.0.22 0.000 0.007 17.16 8.0.21 0.007 0.000 17.11 8.0.20 0.011 0.000 17.18 8.0.19 0.008 0.000 17.22 8.0.18 0.000 0.008 17.17 8.0.17 0.006 0.003 17.22 8.0.16 0.004 0.004 17.23 8.0.15 0.002 0.005 17.16 8.0.14 0.004 0.004 17.11 8.0.13 0.006 0.000 13.70 8.0.12 0.008 0.000 17.20 8.0.11 0.003 0.006 17.13 8.0.10 0.004 0.004 16.98 8.0.9 0.005 0.003 16.97 8.0.8 0.009 0.011 17.21 8.0.7 0.005 0.003 17.22 8.0.6 0.003 0.005 17.04 8.0.5 0.004 0.004 17.04 8.0.3 0.007 0.012 17.37 8.0.2 0.014 0.011 17.40 8.0.1 0.008 0.000 17.19 8.0.0 0.007 0.014 16.97 7.4.33 0.000 0.005 15.55 7.4.32 0.000 0.007 16.80 7.4.30 0.003 0.003 16.71 7.4.29 0.000 0.008 16.89 7.4.28 0.003 0.005 16.75 7.4.27 0.008 0.000 16.89 7.4.26 0.000 0.008 16.78 7.4.25 0.005 0.002 16.79 7.4.24 0.004 0.004 16.90 7.4.23 0.003 0.005 16.65 7.4.22 0.000 0.008 16.93 7.4.21 0.008 0.011 16.85 7.4.20 0.000 0.007 16.61 7.4.16 0.010 0.007 16.89 7.4.14 0.011 0.012 17.86 7.4.13 0.009 0.009 16.83 7.4.12 0.013 0.008 16.88 7.4.11 0.013 0.004 16.80 7.4.10 0.011 0.007 16.96 7.4.9 0.012 0.009 16.70 7.4.8 0.012 0.012 19.39 7.4.7 0.007 0.015 16.85 7.4.6 0.012 0.011 16.73 7.4.5 0.013 0.008 16.82 7.4.4 0.010 0.010 16.75 7.4.3 0.010 0.014 16.79 7.4.2 0.010 0.014 16.73 7.4.1 0.017 0.003 15.74 7.4.0 0.009 0.009 15.65 7.3.33 0.000 0.005 13.62 7.3.32 0.003 0.003 13.64 7.3.31 0.000 0.007 16.70 7.3.30 0.003 0.003 16.65 7.3.29 0.000 0.008 16.65 7.3.28 0.006 0.015 16.70 7.3.26 0.010 0.010 16.80 7.3.24 0.013 0.010 16.84 7.3.23 0.007 0.010 16.53 7.3.21 0.010 0.007 16.58 7.3.20 0.006 0.019 16.55 7.3.19 0.006 0.016 16.63 7.3.18 0.013 0.010 16.73 7.3.17 0.006 0.014 16.67 7.3.16 0.010 0.009 16.73 7.3.15 0.008 0.016 16.54 7.3.14 0.007 0.015 16.61 7.3.13 0.006 0.014 15.67 7.3.12 0.012 0.008 15.89 7.3.11 0.012 0.008 15.86 7.3.10 0.012 0.006 15.81 7.3.9 0.014 0.007 15.90 7.3.8 0.008 0.010 15.97 7.3.7 0.006 0.007 15.97 7.3.6 0.008 0.008 15.96 7.3.5 0.010 0.005 15.90 7.3.4 0.003 0.014 15.77 7.3.3 0.007 0.008 15.79 7.3.2 0.012 0.005 16.75 7.3.1 0.011 0.010 16.69 7.3.0 0.028 0.008 16.76 7.2.33 0.009 0.013 17.08 7.2.32 0.000 0.017 16.83 7.2.31 0.013 0.006 16.99 7.2.30 0.013 0.007 16.93 7.2.29 0.016 0.004 17.06 7.2.28 0.015 0.009 17.02 7.2.27 0.015 0.007 16.95 7.2.26 0.013 0.008 16.06 7.2.25 0.011 0.010 16.24 7.2.24 0.007 0.012 16.31 7.2.23 0.010 0.009 16.17 7.2.22 0.012 0.010 16.19 7.2.21 0.010 0.007 16.33 7.2.20 0.003 0.014 16.14 7.2.19 0.012 0.010 16.09 7.2.18 0.011 0.006 16.20 7.2.17 0.006 0.012 16.27 7.2.16 0.012 0.006 16.15 7.2.15 0.012 0.012 17.09 7.2.14 0.010 0.009 17.15 7.2.13 0.009 0.009 16.98 7.2.12 0.013 0.007 17.07 7.2.11 0.009 0.010 17.10 7.2.10 0.007 0.010 17.09 7.2.9 0.010 0.011 17.15 7.2.8 0.007 0.011 17.15 7.2.7 0.016 0.009 16.55 7.2.6 0.018 0.005 16.54 7.2.5 0.017 0.008 16.50 7.2.4 0.018 0.006 16.59 7.2.3 0.021 0.007 16.53 7.2.2 0.016 0.008 16.41 7.2.1 0.019 0.009 16.43 7.2.0 0.014 0.006 16.52 7.1.33 0.016 0.011 15.89 7.1.32 0.008 0.008 15.94 7.1.31 0.012 0.006 16.10 7.1.30 0.006 0.012 15.97 7.1.29 0.005 0.012 15.88 7.1.28 0.008 0.011 15.89 7.1.27 0.005 0.011 15.96 7.1.26 0.007 0.009 15.86 7.1.25 0.014 0.008 15.80 7.1.24 0.011 0.011 15.83 7.1.23 0.012 0.011 15.89 7.1.22 0.012 0.011 15.91 7.1.21 0.013 0.012 15.98 7.1.20 0.010 0.011 16.02 7.1.19 0.009 0.013 15.85 7.1.18 0.011 0.009 15.90 7.1.17 0.012 0.011 15.37 7.1.16 0.016 0.013 15.33 7.1.15 0.019 0.008 15.48 7.1.14 0.016 0.008 15.29 7.1.13 0.015 0.009 15.25 7.1.12 0.016 0.008 15.31 7.1.11 0.015 0.008 15.29 7.1.10 0.016 0.009 15.44 7.1.9 0.026 0.009 15.41 7.1.8 0.017 0.008 15.32 7.1.7 0.021 0.005 15.42 7.1.6 0.024 0.010 21.31 7.1.5 0.019 0.016 21.51 7.1.4 0.024 0.011 21.36 7.1.3 0.027 0.008 21.36 7.1.2 0.025 0.008 21.34 7.1.1 0.021 0.007 15.30 7.1.0 0.018 0.004 15.32 7.0.33 0.012 0.009 15.54 7.0.32 0.025 0.007 15.65 7.0.31 0.016 0.006 15.60 7.0.30 0.013 0.005 15.52 7.0.29 0.012 0.011 15.49 7.0.28 0.009 0.008 15.40 7.0.27 0.010 0.007 15.38 7.0.26 0.009 0.009 15.62 7.0.25 0.010 0.010 15.66 7.0.24 0.011 0.009 15.54 7.0.23 0.007 0.014 15.53 7.0.22 0.014 0.006 15.66 7.0.21 0.012 0.008 15.55 7.0.20 0.017 0.006 15.53 7.0.19 0.013 0.011 15.61 7.0.18 0.004 0.018 15.49 7.0.17 0.014 0.005 15.63 7.0.16 0.013 0.010 15.59 7.0.15 0.007 0.011 15.58 7.0.14 0.017 0.002 15.67 7.0.13 0.013 0.005 15.45 7.0.12 0.009 0.009 15.58 7.0.11 0.008 0.012 15.54 7.0.10 0.010 0.008 15.62 7.0.9 0.008 0.010 15.68 7.0.8 0.010 0.014 15.65 7.0.7 0.004 0.014 15.54 7.0.6 0.008 0.012 15.68 7.0.5 0.011 0.006 15.69 7.0.4 0.010 0.008 14.62 7.0.3 0.027 0.009 14.67 7.0.2 0.006 0.011 14.65 7.0.1 0.018 0.006 14.70 7.0.0 0.015 0.009 14.75 5.6.40 0.005 0.011 15.55 5.6.39 0.011 0.013 15.64 5.6.38 0.009 0.013 15.30 5.6.37 0.018 0.007 15.36 5.6.36 0.012 0.008 15.35 5.6.35 0.012 0.010 15.33 5.6.34 0.010 0.009 15.56 5.6.33 0.010 0.010 15.34 5.6.32 0.008 0.016 15.42 5.6.31 0.018 0.004 15.55 5.6.30 0.009 0.013 15.35 5.6.29 0.008 0.019 15.38 5.6.28 0.009 0.007 15.54 5.6.27 0.012 0.009 15.48 5.6.26 0.007 0.014 15.53 5.6.25 0.010 0.010 15.45 5.6.24 0.011 0.011 15.35 5.6.23 0.011 0.010 15.29 5.6.22 0.012 0.014 15.49 5.6.21 0.007 0.014 15.36 5.6.20 0.008 0.012 15.38 5.6.19 0.009 0.011 15.35 5.6.18 0.014 0.012 15.28 5.6.17 0.010 0.012 15.44 5.6.16 0.011 0.010 15.36 5.6.15 0.011 0.012 15.35 5.6.14 0.009 0.014 15.29 5.6.13 0.013 0.009 15.58 5.6.12 0.013 0.010 15.36 5.6.11 0.010 0.013 15.54 5.6.10 0.012 0.008 15.37 5.6.9 0.012 0.009 15.70 5.6.8 0.009 0.011 15.23 5.6.7 0.012 0.006 15.39 5.6.6 0.010 0.009 15.40 5.6.5 0.010 0.010 15.45 5.6.4 0.012 0.007 15.27 5.6.3 0.012 0.009 15.31 5.6.2 0.012 0.011 15.37 5.6.1 0.010 0.009 15.50 5.6.0 0.007 0.012 15.44
preferences:dark mode live preview
65.43 ms | 400 KiB | 5 Q