forked from extern/egroupware
* Mail: Resolve ms-tnef attachments if possible, and required backend functionality is assumed to be available
This commit is contained in:
parent
932c78bc6d
commit
50ea60a01c
@ -1486,6 +1486,36 @@ class emailadmin_imapbase
|
|||||||
$headerObject['ATTACHMENTS'][$mime_id]['cid'] = $cid;
|
$headerObject['ATTACHMENTS'][$mime_id]['cid'] = $cid;
|
||||||
$headerObject['ATTACHMENTS'][$mime_id]['partID']=$mime_id;
|
$headerObject['ATTACHMENTS'][$mime_id]['partID']=$mime_id;
|
||||||
if (!isset($headerObject['ATTACHMENTS'][$mime_id]['name']))$headerObject['ATTACHMENTS'][$mime_id]['name']=$part->getName();
|
if (!isset($headerObject['ATTACHMENTS'][$mime_id]['name']))$headerObject['ATTACHMENTS'][$mime_id]['name']=$part->getName();
|
||||||
|
if ($headerObject['ATTACHMENTS'][$mime_id]['name']=='winmail.dat' &&
|
||||||
|
($headerObject['ATTACHMENTS'][$mime_id]['mimeType']=='application/octet-stream' ||
|
||||||
|
$headerObject['ATTACHMENTS'][$mime_id]['mimeType']=='application/ms-tnef'))
|
||||||
|
{
|
||||||
|
$tnefResolved=false;
|
||||||
|
$tnef_data = $this->getAttachment($headerObject['ATTACHMENTS'][$mime_id]['uid'],$headerObject['ATTACHMENTS'][$mime_id]['partID'],0,false);
|
||||||
|
$myTnef = $this->tnef_decoder($tnef_data['attachment']);
|
||||||
|
//error_log(__METHOD__.__LINE__.array2string($myTnef->getParts()));
|
||||||
|
// Note: MimeId starts with 0, almost always, we cannot use that as winmail_id
|
||||||
|
// we need to build Something that meets the needs
|
||||||
|
if ($myTnef)
|
||||||
|
{
|
||||||
|
foreach($myTnef->getParts() as $vmime_id => $part)
|
||||||
|
{
|
||||||
|
$tnefResolved=true;
|
||||||
|
$attachment = $part->getAllDispositionParameters();
|
||||||
|
|
||||||
|
$attachment['mimeType'] = $part->getType();
|
||||||
|
$attachment['uid'] = $headerObject['ATTACHMENTS'][$mime_id]['uid'];
|
||||||
|
$attachment['partID'] = $headerObject['ATTACHMENTS'][$mime_id]['partID'];
|
||||||
|
$attachment['is_winmail'] = $headerObject['ATTACHMENTS'][$mime_id]['uid'].'@'.$headerObject['ATTACHMENTS'][$mime_id]['partID'].'@'.$vmime_id;
|
||||||
|
if (!isset($attachment['name'])||empty($attachment['name'])) $attachment['name'] = $part->getName();
|
||||||
|
$attachment['size'] = $part->getBytes();
|
||||||
|
if (($cid = $part->getContentId())) $attachment['cid'] = $cid;
|
||||||
|
if (empty($attachment['name'])) $attachment['name'] = (isset($attachment['cid'])&&!empty($attachment['cid'])?$attachment['cid']:lang("unknown").'_Uid'.$_uid.'_Part'.$mime_id).'.'.mime_magic::mime2ext($attachment['mimeType']);
|
||||||
|
$headerObject['ATTACHMENTS'][$mime_id.'.'.$vmime_id] = $attachment;
|
||||||
|
}
|
||||||
|
if ($tnefResolved) unset($headerObject['ATTACHMENTS'][$mime_id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
//error_log(__METHOD__.' ('.__LINE__.') '.' PartDisposition:'.$mime_id.'->'.array2string($part->getName()));
|
//error_log(__METHOD__.' ('.__LINE__.') '.' PartDisposition:'.$mime_id.'->'.array2string($part->getName()));
|
||||||
//error_log(__METHOD__.' ('.__LINE__.') '.' PartDisposition:'.$mime_id.'->'.array2string($part->getAllDispositionParameters()));
|
//error_log(__METHOD__.' ('.__LINE__.') '.' PartDisposition:'.$mime_id.'->'.array2string($part->getAllDispositionParameters()));
|
||||||
//error_log(__METHOD__.' ('.__LINE__.') '.' Attachment:'.$mime_id.'->'.array2string($headerObject['ATTACHMENTS'][$mime_id]));
|
//error_log(__METHOD__.' ('.__LINE__.') '.' Attachment:'.$mime_id.'->'.array2string($headerObject['ATTACHMENTS'][$mime_id]));
|
||||||
@ -4788,6 +4818,7 @@ class emailadmin_imapbase
|
|||||||
if (!$_structure || !$_structure->contentTypeMap()) return array();
|
if (!$_structure || !$_structure->contentTypeMap()) return array();
|
||||||
if (!empty($_partID)) $_structure = $_structure->getPart($_partID);
|
if (!empty($_partID)) $_structure = $_structure->getPart($_partID);
|
||||||
$skipParts = array();
|
$skipParts = array();
|
||||||
|
$tnefParts = array();
|
||||||
foreach($_structure->contentTypeMap() as $mime_id => $mime_type)
|
foreach($_structure->contentTypeMap() as $mime_id => $mime_type)
|
||||||
{
|
{
|
||||||
$part = $_structure->getPart($mime_id);
|
$part = $_structure->getPart($mime_id);
|
||||||
@ -4817,6 +4848,7 @@ class emailadmin_imapbase
|
|||||||
// we attempt to fetch "ourselves"
|
// we attempt to fetch "ourselves"
|
||||||
if ($_partID==$part->getMimeId() && $part->getPrimaryType()=='message') continue;
|
if ($_partID==$part->getMimeId() && $part->getPrimaryType()=='message') continue;
|
||||||
$attachment = $part->getAllDispositionParameters();
|
$attachment = $part->getAllDispositionParameters();
|
||||||
|
|
||||||
$attachment['mimeType'] = $mime_type;
|
$attachment['mimeType'] = $mime_type;
|
||||||
$attachment['uid'] = $_uid;
|
$attachment['uid'] = $_uid;
|
||||||
$attachment['partID'] = $mime_id;
|
$attachment['partID'] = $mime_id;
|
||||||
@ -4831,9 +4863,52 @@ class emailadmin_imapbase
|
|||||||
$attachment['size'] = $part->getBytes();
|
$attachment['size'] = $part->getBytes();
|
||||||
if (($cid = $part->getContentId())) $attachment['cid'] = $cid;
|
if (($cid = $part->getContentId())) $attachment['cid'] = $cid;
|
||||||
if (empty($attachment['name'])) $attachment['name'] = (isset($attachment['cid'])&&!empty($attachment['cid'])?$attachment['cid']:lang("unknown").'_Uid'.$_uid.'_Part'.$mime_id).'.'.mime_magic::mime2ext($mime_type);
|
if (empty($attachment['name'])) $attachment['name'] = (isset($attachment['cid'])&&!empty($attachment['cid'])?$attachment['cid']:lang("unknown").'_Uid'.$_uid.'_Part'.$mime_id).'.'.mime_magic::mime2ext($mime_type);
|
||||||
$attachments[] = $attachment;
|
//error_log(__METHOD__.' ('.__LINE__.') '.' Uid:'.$uid.' Part:'.$_partID.'->'.$mime_id.':'.array2string($attachment));
|
||||||
|
//typical winmail.dat attachment is
|
||||||
|
//Array([size] => 1462762[filename] => winmail.dat[mimeType] => application/ms-tnef[uid] => 100[partID] => 2[name] => winmail.dat)
|
||||||
|
if ($resolveTNEF && $attachment['mimeType']=='application/ms-tnef')
|
||||||
|
{
|
||||||
|
$tnefParts[] = $attachment;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$attachments[] = $attachment;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ($resolveTNEF && !empty($tnefParts))
|
||||||
|
{
|
||||||
|
//error_log(__METHOD__.__LINE__.array2string($tnefParts));
|
||||||
|
foreach ($tnefParts as $k => $tnp)
|
||||||
|
{
|
||||||
|
$tnefResolved=false;
|
||||||
|
$tnef_data = $this->getAttachment($tnp['uid'],$tnp['partID'],$k,false);
|
||||||
|
$myTnef = $this->tnef_decoder($tnef_data['attachment']);
|
||||||
|
//error_log(__METHOD__.__LINE__.array2string($myTnef->getParts()));
|
||||||
|
// Note: MimeId starts with 0, almost always, we cannot use that as winmail_id
|
||||||
|
// we need to build Something that meets the needs
|
||||||
|
if ($myTnef)
|
||||||
|
{
|
||||||
|
foreach($myTnef->getParts() as $mime_id => $part)
|
||||||
|
{
|
||||||
|
$tnefResolved=true;
|
||||||
|
$attachment = $part->getAllDispositionParameters();
|
||||||
|
|
||||||
|
$attachment['mimeType'] = $part->getType();
|
||||||
|
$attachment['uid'] = $tnp['uid'];
|
||||||
|
$attachment['partID'] = $tnp['partID'];
|
||||||
|
$attachment['is_winmail'] = $tnp['uid'].'@'.$tnp['partID'].'@'.$mime_id;
|
||||||
|
if (!isset($attachment['name'])||empty($attachment['name'])) $attachment['name'] = $part->getName();
|
||||||
|
$attachment['size'] = $part->getBytes();
|
||||||
|
if (($cid = $part->getContentId())) $attachment['cid'] = $cid;
|
||||||
|
if (empty($attachment['name'])) $attachment['name'] = (isset($attachment['cid'])&&!empty($attachment['cid'])?$attachment['cid']:lang("unknown").'_Uid'.$_uid.'_Part'.$mime_id).'.'.mime_magic::mime2ext($attachment['mimeType']);
|
||||||
|
$attachments[] = $attachment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($tnefResolved===false) $attachments[]=$tnp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//error_log(__METHOD__.__LINE__.array2string($attachments));
|
||||||
return $attachments;
|
return $attachments;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4845,10 +4920,11 @@ class emailadmin_imapbase
|
|||||||
* @return boolean|Horde_Mime_part Multipart/Mixed part decoded attachments |
|
* @return boolean|Horde_Mime_part Multipart/Mixed part decoded attachments |
|
||||||
* return false if there's no attachments or failure
|
* return false if there's no attachments or failure
|
||||||
*/
|
*/
|
||||||
public function tnef_decoder($_uid, $data )
|
public function tnef_decoder( $data )
|
||||||
{
|
{
|
||||||
|
if (class_exists('Horde_Compress',true)==false) return false;
|
||||||
|
|
||||||
$parts_obj = $this->getStructure($_uid);
|
$parts_obj = new Horde_Mime_part;
|
||||||
$parts_obj->setType('multipart/mixed');
|
$parts_obj->setType('multipart/mixed');
|
||||||
|
|
||||||
$tnef_object = Horde_Compress::factory('tnef');
|
$tnef_object = Horde_Compress::factory('tnef');
|
||||||
@ -4862,7 +4938,7 @@ class emailadmin_imapbase
|
|||||||
{
|
{
|
||||||
foreach ($tnef_data as &$data)
|
foreach ($tnef_data as &$data)
|
||||||
{
|
{
|
||||||
$tmp_part = $this->getStructure($_uid);
|
$tmp_part = new Horde_Mime_part;
|
||||||
|
|
||||||
$tmp_part->setName($data['name']);
|
$tmp_part->setName($data['name']);
|
||||||
$tmp_part->setContents($data['stream']);
|
$tmp_part->setContents($data['stream']);
|
||||||
@ -4873,9 +4949,11 @@ class emailadmin_imapbase
|
|||||||
{
|
{
|
||||||
$type = Horde_Mime_Magic::filenameToMIME($data['name']);
|
$type = Horde_Mime_Magic::filenameToMIME($data['name']);
|
||||||
}
|
}
|
||||||
$tmp_part->setType($data['type']);
|
$tmp_part->setType($type);
|
||||||
|
//error_log(__METHOD__.__LINE__.array2string($tmp_part));
|
||||||
$parts_obj->addPart($tmp_part);
|
$parts_obj->addPart($tmp_part);
|
||||||
}
|
}
|
||||||
|
$parts_obj->buildMimeIds();
|
||||||
return $parts_obj;
|
return $parts_obj;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -4894,6 +4972,7 @@ class emailadmin_imapbase
|
|||||||
*/
|
*/
|
||||||
function getAttachment($_uid, $_partID, $_winmail_nr=0, $_returnPart=true, $_stream=false)
|
function getAttachment($_uid, $_partID, $_winmail_nr=0, $_returnPart=true, $_stream=false)
|
||||||
{
|
{
|
||||||
|
//error_log(__METHOD__.__LINE__."Uid:$_uid, PartId:$_partID, WinMailNr:$_winmail_nr, ReturnPart:$_returnPart, Stream:$_stream");
|
||||||
$_folder = ($this->sessionData['mailbox']? $this->sessionData['mailbox'] : $this->icServer->getCurrentMailbox());
|
$_folder = ($this->sessionData['mailbox']? $this->sessionData['mailbox'] : $this->icServer->getCurrentMailbox());
|
||||||
|
|
||||||
$uidsToFetch = new Horde_Imap_Client_Ids();
|
$uidsToFetch = new Horde_Imap_Client_Ids();
|
||||||
@ -4938,27 +5017,57 @@ class emailadmin_imapbase
|
|||||||
}
|
}
|
||||||
$ext = mime_magic::mime2ext($structure_mime);
|
$ext = mime_magic::mime2ext($structure_mime);
|
||||||
if ($ext && stripos($filename,'.')===false && stripos($filename,$ext)===false) $filename = trim($filename).'.'.$ext;
|
if ($ext && stripos($filename,'.')===false && stripos($filename,$ext)===false) $filename = trim($filename).'.'.$ext;
|
||||||
|
//error_log(__METHOD__.__LINE__.'#'.$structure_mime.'#'.$filename);
|
||||||
$attachmentData = array(
|
$attachmentData = array(
|
||||||
'type' => $structure_mime,
|
'type' => $structure_mime,
|
||||||
'filename' => $filename,
|
'filename' => $filename,
|
||||||
'attachment' => $part->getContents(array('stream'=>$_stream))
|
'attachment' => $part->getContents(array('stream'=>$_stream))
|
||||||
);
|
);
|
||||||
/*
|
|
||||||
// try guessing the mimetype, if we get the application/octet-stream
|
// try guessing the mimetype, if we get the application/octet-stream
|
||||||
if (strtolower($attachmentData['type']) == 'application/octet-stream') $attachmentData['type'] = mime_magic::filename2mime($attachmentData['filename']);
|
if (strtolower($attachmentData['type']) == 'application/octet-stream') $attachmentData['type'] = mime_magic::filename2mime($attachmentData['filename']);
|
||||||
# if the attachment holds a winmail number and is a winmail.dat then we have to handle that.
|
# if the attachment holds a winmail number and is a winmail.dat then we have to handle that.
|
||||||
if ( $filename == 'winmail.dat' && $_winmail_nr > 0 &&
|
if ( $filename == 'winmail.dat' && $_winmail_nr)
|
||||||
( $wmattach = $this->decode_winmail( $_uid, $_partID, $_winmail_nr ) ) )
|
|
||||||
{
|
{
|
||||||
$ext = mime_magic::mime2ext($wmattach['type']);
|
//by now _uid is of type array
|
||||||
if ($ext && stripos($wmattach['name'],'.')===false && stripos($wmattach['name'],$ext)===false) $wmattach['name'] = trim($wmattach['name']).'.'.$ext;
|
$tnefResolved=false;
|
||||||
$attachmentData = array(
|
$wantedPart=$_uid[0].'@'.$_partID;
|
||||||
'type' => $wmattach['type'],
|
$myTnef = $this->tnef_decoder($attachmentData['attachment']);
|
||||||
'filename' => $wmattach['name'],
|
//error_log(__METHOD__.__LINE__.array2string($myTnef->getParts()));
|
||||||
'attachment' => $wmattach['attachment'],
|
// Note: MimeId starts with 0, almost always, we cannot use that as winmail_id
|
||||||
);
|
// we need to build Something that meets the needs
|
||||||
|
if ($myTnef)
|
||||||
|
{
|
||||||
|
foreach($myTnef->getParts() as $mime_id => $part)
|
||||||
|
{
|
||||||
|
$tnefResolved=true;
|
||||||
|
$attachment = $part->getAllDispositionParameters();
|
||||||
|
$attachment['mimeType'] = $part->getType();
|
||||||
|
//error_log(__METHOD__.__LINE__.'#'.$mime_id.'#'.$filename.'#'.array2string($attachment));
|
||||||
|
//error_log(__METHOD__.__LINE__." $_winmail_nr == $wantedPart@$mime_id");
|
||||||
|
if ($_winmail_nr == $wantedPart.'@'.$mime_id)
|
||||||
|
{
|
||||||
|
//error_log(__METHOD__.__LINE__.'#'.$structure_mime.'#'.$filename.'#'.array2string($attachment));
|
||||||
|
if (!isset($attachment['filename'])||empty($attachment['filename'])) $attachment['filename'] = $part->getName();
|
||||||
|
if (($cid = $part->getContentId())) $attachment['cid'] = $cid;
|
||||||
|
if (empty($attachment['filename'])) $attachment['filename'] = (isset($attachment['cid'])&&!empty($attachment['cid'])?$attachment['cid']:lang("unknown").'_Uid'.$_uid.'_Part'.$mime_id).'.'.mime_magic::mime2ext($attachment['mimeType']);
|
||||||
|
$wmattach = $attachment;
|
||||||
|
$wmattach['attachment'] = $part->getContents(array('stream'=>$_stream));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($tnefResolved)
|
||||||
|
{
|
||||||
|
$ext = mime_magic::mime2ext($wmattach['mimeType']);
|
||||||
|
if ($ext && stripos($wmattach['filename'],'.')===false && stripos($wmattach['filename'],$ext)===false) $wmattach['filename'] = trim($wmattach['filename']).'.'.$ext;
|
||||||
|
$attachmentData = array(
|
||||||
|
'type' => $wmattach['mimeType'],
|
||||||
|
'filename' => $wmattach['filename'],
|
||||||
|
'attachment' => $wmattach['attachment'],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
return $attachmentData;
|
return $attachmentData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user