Merge pull request #1541 from moteus/parse_imap_text

Improve mail parse
This commit is contained in:
FusionPBX
2016-04-12 12:39:37 -06:00
3 changed files with 172 additions and 90 deletions

View File

@@ -28,7 +28,6 @@
include "root.php";
require_once "resources/require.php";
require_once "resources/functions/object_to_array.php";
require_once "resources/functions/parse_attachments.php";
require_once "resources/functions/parse_message.php";
require_once "resources/classes/text.php";
@@ -179,33 +178,57 @@ if (sizeof($result) != 0) {
}
unset($fax_subject); //clear so not on cover page
$message = parse_message($connection, $email_id, FT_UID);
//get email body (if any) for cover page
$fax_message = parse_message($connection, $email_id, FT_UID);
if ($fax_message == '') {
$fax_message = '';
//Debug print
print('attachments:' . "\n");
foreach($message['attachments'] as &$attachment){
print(' - ' . $attachment['type'] . ' - ' . $attachment['name'] . ': ' . $attachment['size'] . ' disposition: ' . $attachment['disposition'] . "\n");
}
print('messages:' . "\n");
foreach($message['messages'] as &$msg){
print(' - ' . $msg['type'] . ' - ' . $msg['size'] . "\n");
// print($msg['data']);
// print("\n--------------------------------------------------------\n");
}
foreach($message['messages'] as &$msg){
if(($msg['size'] > 0) && ($msg['type'] == 'text/plain')) {
$fax_message = $msg['data'];
break;
}
}
if ($fax_message != '') {
$fax_message = strip_tags($fax_message);
$fax_message = str_replace("\r\n\r\n","\r\n", $fax_message);
$fax_message = str_replace("\r\n\r\n", "\r\n", $fax_message);
}
// set fax directory (used for pdf creation - cover and/or attachments)
$fax_dir = $_SESSION['switch']['storage']['dir'].'/fax'.(($domain_name != '') ? '/'.$domain_name : null);
//handle attachments (if any)
$attachments = parse_attachments($connection, $email_id, FT_UID);
$attachments = $message['attachments'];
if (sizeof($attachments) > 0) {
$disallowed_file_extensions = explode(',','sh,ssh,so,dll,exe,bat,vbs,zip,rar,z,tar,tbz,tgz,gz');
foreach ($attachments as $attachment['num'] => $attachment) {
$fax_file_extension = pathinfo($attachment['filename'], PATHINFO_EXTENSION);
foreach ($attachments as &$attachment) {
$fax_file_extension = pathinfo($attachment['name'], PATHINFO_EXTENSION);
if (in_array($fax_file_extension, $disallowed_file_extensions) || $fax_file_extension == '') { continue; } //block unauthorized files
if($attachment['disposition'] != 'attachment'){ continue; } //support only attachments
//store attachment in local fax temp folder
$local_filepath = $fax_dir.'/'.$fax_extension.'/temp/'.$attachment['filename'];
file_put_contents($local_filepath, $attachment['attachment']);
$local_filepath = $fax_dir.'/'.$fax_extension.'/temp/'.$attachment['name'];
file_put_contents($local_filepath, $attachment['data']);
//load files array with attachments
$emailed_files['error'][$attachment['num']] = 0;
$emailed_files['size'][$attachment['num']] = $attachment['size'];
$emailed_files['tmp_name'][$attachment['num']] = $attachment['filename'];
$emailed_files['name'][$attachment['num']] = $attachment['filename'];
$emailed_files['error'][] = 0;
$emailed_files['size'][] = $attachment['size'];
$emailed_files['tmp_name'][] = $attachment['name'];
$emailed_files['name'][] = $attachment['name'];
}
}

View File

@@ -1,48 +0,0 @@
<?php
function parse_attachments($connection, $message_number, $option = '') {
$attachments = array();
$structure = imap_fetchstructure($connection, $message_number, $option);
if(isset($structure->parts) && count($structure->parts)) {
for($i = 0; $i < count($structure->parts); $i++) {
if($structure->parts[$i]->ifdparameters) {
foreach($structure->parts[$i]->dparameters as $object) {
if(strtolower($object->attribute) == 'filename') {
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['filename'] = $object->value;
}
}
}
if($structure->parts[$i]->ifparameters) {
foreach($structure->parts[$i]->parameters as $object) {
if(strtolower($object->attribute) == 'name') {
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['name'] = $object->value;
}
}
}
if($attachments[$i]['is_attachment']) {
$attachments[$i]['attachment'] = imap_fetchbody($connection, $message_number, $i+1, $option);
if($structure->parts[$i]->encoding == 3) { // 3 = BASE64
$attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
$attachments[$i]['size'] = strlen($attachments[$i]['attachment']);
}
elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
$attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
$attachments[$i]['size'] = strlen($attachments[$i]['attachment']);
}
}
unset($attachments[$i]['is_attachment']);
}
}
return array_values($attachments); //reindex
}
?>

View File

@@ -1,38 +1,145 @@
<?php
function parse_message($connection, $message_number, $option = '', $to_charset = 'UTF-8') {
function parse_message($connection, $message_number, $option = null, $to_charset = 'UTF-8') {
$result = Array('messages'=>Array(),'attachments'=>Array());
$structure = imap_fetchstructure($connection, $message_number, $option);
if(isset($structure->parts) && count($structure->parts)) {
for($i = 0; $i < count($structure->parts); $i++) {
$msg = '';
$part = $structure->parts[$i];
if($part->type == TYPETEXT){
$msg = imap_fetchbody($connection, $message_number, $i+1, $option);
if($part->encoding == ENCBASE64){
$msg = base64_decode($msg);
}
else if($part->encoding == ENCQUOTEDPRINTABLE){
$msg = quoted_printable_decode($msg);
}
if($msg && $to_charset){
$charset = '';
if(isset($part->parameters) && count($part->parameters)) {
foreach($part->parameters as &$parameter){
if($parameter->attribute == 'CHARSET') {
$charset = $parameter->value;
break;
}
}
}
if($charset){
$msg = mb_convert_encoding($msg, $to_charset, $charset);
}
}
if($msg){
return $msg;
if (isset($structure->parts)) {
$flatten = parse_message_flatten($structure->parts);
}
else {
$flatten = Array(1 => $structure);
}
foreach($flatten as $id => &$part){
switch($part->type) {
case TYPETEXT:
$message = parse_message_decode_text($connection, $part, $message_number, $id, $option, $to_charset);
$result['messages'][] = $message;
break;
case TYPEAPPLICATION: case TYPEAUDIO: case TYPEIMAGE: case TYPEVIDEO: case TYPEOTHER:
$attachment = parse_message_decode_attach($connection, $part, $message_number, $id, $option);
if($attachment){
$result['attachments'][] = $attachment;
}
break;
case TYPEMULTIPART: case TYPEMESSAGE:
break;
}
}
return $result;
}
function parse_message_decode_text($connection, &$part, $message_number, $id, $option, $to_charset){
$msg = parse_message_fetch_body($connection, $part, $message_number, $id, $option);
if($msg && $to_charset){
$charset = '';
if(isset($part->parameters) && count($part->parameters)) {
foreach($part->parameters as &$parameter){
if($parameter->attribute == 'CHARSET') {
$charset = $parameter->value;
break;
}
}
}
if($charset){
$msg = mb_convert_encoding($msg, $to_charset, $charset);
}
$msg = trim($msg);
}
return Array(
'data' => $msg,
'type' => parse_message_get_type($part),
'size' => strlen($msg),
);
}
function parse_message_decode_attach($connection, &$part, $message_number, $id, $option){
$filename = false;
if($part->ifdparameters) {
foreach($part->dparameters as $object) {
if(strtolower($object->attribute) == 'filename') {
$filename = $object->value;
break;
}
}
}
if($part->ifparameters) {
foreach($part->parameters as $object) {
if(strtolower($object->attribute) == 'name') {
$filename = $object->value;
break;
}
}
}
if(!$filename) {
return false;
}
$body = parse_message_fetch_body($connection, $part, $message_number, $id, $option);
return Array(
'data' => $body,
'type' => parse_message_get_type($part),
'name' => $filename,
'size' => strlen($body),
'disposition' => $part->disposition,
);
}
function parse_message_fetch_body($connection, &$part, $message_number, $id, $option){
$body = imap_fetchbody($connection, $message_number, $id, $option);
if($part->encoding == ENCBASE64){
$body = base64_decode($body);
}
else if($part->encoding == ENCQUOTEDPRINTABLE){
$body = quoted_printable_decode($body);
}
return $body;
}
function parse_message_get_type(&$part){
$types = Array(
TYPEMESSAGE => 'message',
TYPEMULTIPART => 'multipart',
TYPEAPPLICATION => 'application',
TYPEAUDIO => 'audio',
TYPEIMAGE => 'image',
TYPETEXT => 'text',
TYPEVIDEO => 'video',
TYPEMODEL => 'model',
TYPEOTHER => 'other',
);
return $types[$part->type] . '/' . strtolower($part->subtype);
}
function parse_message_flatten(&$structure, &$result = array(), $prefix = '', $index = 1, $fullPrefix = true) {
foreach($structure as &$part) {
if(isset($part->parts)) {
if($part->type == TYPEMESSAGE) {
parse_message_flatten($part->parts, $result, $prefix.$index.'.', 0, false);
}
elseif($fullPrefix) {
parse_message_flatten($part->parts, $result, $prefix.$index.'.');
}
else {
parse_message_flatten($part->parts, $result, $prefix);
}
}
else {
$result[$prefix.$index] = $part;
}
$index++;
}
return $result;
}