mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-06-25 12:21:26 +02:00
get display of mails working again, using now Horde_Mime_Part based structure and for images, attachments not yet fully working, should use it too
This commit is contained in:
parent
7c4d696f4b
commit
f975e93677
@ -14,6 +14,8 @@
|
|||||||
* Mail worker class
|
* Mail worker class
|
||||||
* -provides backend functionality for all classes in Mail
|
* -provides backend functionality for all classes in Mail
|
||||||
* -provides classes that may be used by other apps too
|
* -provides classes that may be used by other apps too
|
||||||
|
*
|
||||||
|
* @link https://github.com/horde/horde/blob/master/imp/lib/Contents.php
|
||||||
*/
|
*/
|
||||||
class mail_bo
|
class mail_bo
|
||||||
{
|
{
|
||||||
@ -245,7 +247,7 @@ $_restoreSession=false;
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$account = emailadmin_account::read($_profileID);
|
$account = emailadmin_account::read($_profileID);
|
||||||
if (!empty($account->acc_imap_host))
|
if ($account->acc_imap_host)
|
||||||
{
|
{
|
||||||
return $_profileID;
|
return $_profileID;
|
||||||
}
|
}
|
||||||
@ -538,6 +540,7 @@ $_restoreSession=false;
|
|||||||
*/
|
*/
|
||||||
function closeConnection() {
|
function closeConnection() {
|
||||||
//if ($icServer->_connected) error_log(__METHOD__.__LINE__.' disconnect from Server');
|
//if ($icServer->_connected) error_log(__METHOD__.__LINE__.' disconnect from Server');
|
||||||
|
error_log(__METHOD__."() ".function_backtrace());
|
||||||
$this->icServer->disconnect();
|
$this->icServer->disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -549,6 +552,7 @@ $_restoreSession=false;
|
|||||||
*/
|
*/
|
||||||
function reopen($_foldername)
|
function reopen($_foldername)
|
||||||
{
|
{
|
||||||
|
error_log(__METHOD__."('$_foldername') ".function_backtrace());
|
||||||
// TODO: trying to reduce traffic to the IMAP Server here, introduces problems with fetching the bodies of
|
// TODO: trying to reduce traffic to the IMAP Server here, introduces problems with fetching the bodies of
|
||||||
// eMails when not in "current-Folder" (folder that is selected by UI)
|
// eMails when not in "current-Folder" (folder that is selected by UI)
|
||||||
static $folderOpened;
|
static $folderOpened;
|
||||||
@ -835,6 +839,7 @@ $_restoreSession=false;
|
|||||||
*/
|
*/
|
||||||
function getFolderStatus($_folderName,$ignoreStatusCache=false,$basicInfoOnly=false)
|
function getFolderStatus($_folderName,$ignoreStatusCache=false,$basicInfoOnly=false)
|
||||||
{
|
{
|
||||||
|
error_log(__METHOD__."('$_foldername') ".function_backtrace());
|
||||||
if (self::$debug) error_log(__METHOD__." called with:$_folderName,$ignoreStatusCache,$basicInfoOnly");
|
if (self::$debug) error_log(__METHOD__." called with:$_folderName,$ignoreStatusCache,$basicInfoOnly");
|
||||||
if (!is_string($_folderName) || empty($_folderName)) // something is wrong. Do not proceed
|
if (!is_string($_folderName) || empty($_folderName)) // something is wrong. Do not proceed
|
||||||
{
|
{
|
||||||
@ -3259,123 +3264,175 @@ $_restoreSession=false;
|
|||||||
* get part of the message, if its stucture is indicating its of multipart alternative style
|
* get part of the message, if its stucture is indicating its of multipart alternative style
|
||||||
* a wrapper for multipartmixed
|
* a wrapper for multipartmixed
|
||||||
* @param string/int $_uid the messageuid,
|
* @param string/int $_uid the messageuid,
|
||||||
* @param array $_structure='', if given use structure for parsing
|
* @param Horde_Mime_Part $_structure structure for parsing
|
||||||
* @param string $_htmlMode, how to display a message, html, plain text, ...
|
* @param string $_htmlMode, how to display a message, html, plain text, ...
|
||||||
* @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek
|
* @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek
|
||||||
* @return array containing the desired part
|
* @return array containing the desired part
|
||||||
*/
|
*/
|
||||||
function getMultipartAlternative($_uid, $_structure, $_htmlMode, $_preserveSeen = false)
|
function getMultipartAlternative($_uid, Horde_Mime_Part $_structure, $_htmlMode, $_preserveSeen = false)
|
||||||
{
|
{
|
||||||
// a multipart/alternative has exactly 2 parts (text and html OR text and something else)
|
// a multipart/alternative has exactly 2 parts (text and html OR text and something else)
|
||||||
// sometimes there are 3 parts, when there is an ics/ical attached/included-> we want to show that
|
// sometimes there are 3 parts, when there is an ics/ical attached/included-> we want to show that
|
||||||
// as attachment AND as abstracted ical information (we use our notification style here).
|
// as attachment AND as abstracted ical information (we use our notification style here).
|
||||||
$partText = false;
|
$partText = $partHTML = null;
|
||||||
$partHTML = false;
|
|
||||||
if (self::$debug) _debug_array(array("METHOD"=>__METHOD__,"LINE"=>__LINE__,"STRUCTURE"=>$_structure));
|
if (self::$debug) _debug_array(array("METHOD"=>__METHOD__,"LINE"=>__LINE__,"STRUCTURE"=>$_structure));
|
||||||
foreach($_structure as $mimePart) {
|
|
||||||
if($mimePart->type == 'TEXT' && ($mimePart->subType == 'PLAIN' || $mimePart->subType == 'CALENDAR') && $mimePart->bytes > 0) {
|
foreach($_structure->contentTypeMap() as $mime_id => $mime_type)
|
||||||
if ($mimePart->subType == 'CALENDAR' && $partText === false) $partText = $mimePart; // only if there is no partText set already
|
{
|
||||||
if ($mimePart->subType == 'PLAIN') $partText = $mimePart;
|
//error_log(__METHOD__."($_uid, ".$_structure->getMimeId().") $mime_id: $mime_type");
|
||||||
} elseif($mimePart->type == 'TEXT' && $mimePart->subType == 'HTML' && $mimePart->bytes > 0) {
|
if (self::$debug) echo __METHOD__."($_uid, partID=".$_structure->getMimeId().") $mime_id: $mime_type<br>";
|
||||||
$partHTML = $mimePart;
|
|
||||||
} elseif ($mimePart->type == 'MULTIPART' && ($mimePart->subType == 'RELATED' || $mimePart->subType == 'MIXED') && is_array($mimePart->subParts)) {
|
if (!$mime_id) continue; // ignore multipart/alternative itself
|
||||||
|
|
||||||
|
$mimePart = $_structure->getPart($mime_id);
|
||||||
|
|
||||||
|
switch($mimePart->getPrimaryType())
|
||||||
|
{
|
||||||
|
case 'text':
|
||||||
|
switch($mimePart->getSubType())
|
||||||
|
{
|
||||||
|
case 'calendar': // only if there is no partText set already
|
||||||
|
if ($partText) break;
|
||||||
|
// fall throught
|
||||||
|
case 'plain':
|
||||||
|
if ($mimePart->getBytes() > 0) $partText = $mimePart;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'html':
|
||||||
|
if ($mimePart->getBytes() > 0) $partHTML = $mimePart;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'multipart':
|
||||||
|
switch($mimePart->getSubType())
|
||||||
|
{
|
||||||
|
case 'related':
|
||||||
|
case 'mixed':
|
||||||
|
if (count($mimePart->getParts()) > 1)
|
||||||
|
{
|
||||||
// in a multipart alternative we treat the multipart/related as html part
|
// in a multipart alternative we treat the multipart/related as html part
|
||||||
#$partHTML = array($mimePart);
|
|
||||||
if (self::$debug) error_log(__METHOD__." process MULTIPART/RELATED with array as subparts");
|
if (self::$debug) error_log(__METHOD__." process MULTIPART/RELATED with array as subparts");
|
||||||
$partHTML = $mimePart;
|
$partHTML = $mimePart;
|
||||||
} elseif ($mimePart->type == 'MULTIPART' && $mimePart->subType == 'ALTERNATIVE' && is_array($mimePart->subParts)) {
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'alternative':
|
||||||
|
if (count($mimePart->getParts()) > 1)
|
||||||
|
{
|
||||||
//cascading multipartAlternative structure, assuming only the first one is to be used
|
//cascading multipartAlternative structure, assuming only the first one is to be used
|
||||||
return $this->getMultipartAlternative($_uid,$mimePart->subParts,$_htmlMode, $_preserveSeen);
|
// return $this->getMultipartAlternative($_uid, $mimePart, $_htmlMode, $_preserveSeen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//error_log(__METHOD__.__LINE__.$_htmlMode);
|
}
|
||||||
switch($_htmlMode) {
|
}
|
||||||
|
|
||||||
|
switch($_htmlMode)
|
||||||
|
{
|
||||||
case 'html_only':
|
case 'html_only':
|
||||||
case 'always_display':
|
case 'always_display':
|
||||||
if(is_object($partHTML)) {
|
if ($partHTML)
|
||||||
if($partHTML->subType == 'RELATED') {
|
{
|
||||||
|
switch($partHTML->getSubType())
|
||||||
|
{
|
||||||
|
case 'related':
|
||||||
return $this->getMultipartRelated($_uid, $partHTML, $_htmlMode, $_preserveSeen);
|
return $this->getMultipartRelated($_uid, $partHTML, $_htmlMode, $_preserveSeen);
|
||||||
} elseif($partHTML->subType == 'MIXED') {
|
|
||||||
|
case 'mixed':
|
||||||
return $this->getMultipartMixed($_uid, $partHTML, $_htmlMode, $_preserveSeen);
|
return $this->getMultipartMixed($_uid, $partHTML, $_htmlMode, $_preserveSeen);
|
||||||
} else {
|
|
||||||
|
default:
|
||||||
return $this->getTextPart($_uid, $partHTML, $_htmlMode, $_preserveSeen);
|
return $this->getTextPart($_uid, $partHTML, $_htmlMode, $_preserveSeen);
|
||||||
}
|
}
|
||||||
} elseif(is_object($partText) && $_htmlMode=='always_display') {
|
}
|
||||||
|
elseif ($partText && $_htmlMode=='always_display')
|
||||||
|
{
|
||||||
return $this->getTextPart($_uid, $partText, $_htmlMode, $_preserveSeen);
|
return $this->getTextPart($_uid, $partText, $_htmlMode, $_preserveSeen);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'only_if_no_text':
|
case 'only_if_no_text':
|
||||||
if(is_object($partText)) {
|
if ($partText)
|
||||||
|
{
|
||||||
return $this->getTextPart($_uid, $partText, $_htmlMode, $_preserveSeen);
|
return $this->getTextPart($_uid, $partText, $_htmlMode, $_preserveSeen);
|
||||||
} elseif(is_object($partHTML)) {
|
}
|
||||||
if($partHTML->type) {
|
if ($partHTML)
|
||||||
|
{
|
||||||
|
if ($partHTML->getPrimaryType())
|
||||||
|
{
|
||||||
return $this->getMultipartRelated($_uid, $partHTML, $_htmlMode, $_preserveSeen);
|
return $this->getMultipartRelated($_uid, $partHTML, $_htmlMode, $_preserveSeen);
|
||||||
} else {
|
}
|
||||||
return $this->getTextPart($_uid, $partHTML, 'always_display', $_preserveSeen);
|
return $this->getTextPart($_uid, $partHTML, 'always_display', $_preserveSeen);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if(is_object($partText)) {
|
if ($partText)
|
||||||
|
{
|
||||||
return $this->getTextPart($_uid, $partText, $_htmlMode, $_preserveSeen);
|
return $this->getTextPart($_uid, $partText, $_htmlMode, $_preserveSeen);
|
||||||
} else {
|
}
|
||||||
$bodyPart = array(
|
$bodyPart = array(
|
||||||
'body' => lang("no plain text part found"),
|
'body' => lang("no plain text part found"),
|
||||||
'mimeType' => 'text/plain',
|
'mimeType' => 'text/plain',
|
||||||
'charSet' => self::$displayCharset,
|
'charSet' => self::$displayCharset,
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $bodyPart;
|
return $bodyPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getMultipartMixed
|
* Get part of the message, if its stucture is indicating its of multipart mixed style
|
||||||
* get part of the message, if its stucture is indicating its of multipart mixed style
|
*
|
||||||
* @param string/int $_uid the messageuid,
|
* @param int $_uid the messageuid,
|
||||||
* @param array $_structure='', if given use structure for parsing
|
* @param Horde_Mime_Part $_structure='', if given use structure for parsing
|
||||||
* @param string $_htmlMode, how to display a message, html, plain text, ...
|
* @param string $_htmlMode, how to display a message, html, plain text, ...
|
||||||
* @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek
|
* @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek
|
||||||
* @return array containing the desired part
|
* @return array containing the desired part
|
||||||
*/
|
*/
|
||||||
function getMultipartMixed($_uid, $_structure, $_htmlMode, $_preserveSeen = false)
|
function getMultipartMixed($_uid, Horde_Mime_Part $_structure, $_htmlMode, $_preserveSeen = false)
|
||||||
{
|
{
|
||||||
if (self::$debug) echo __METHOD__."$_uid, $_htmlMode<br>";
|
if (self::$debug) echo __METHOD__."$_uid, $_htmlMode<br>";
|
||||||
$bodyPart = array();
|
$bodyPart = array();
|
||||||
if (self::$debug) _debug_array($_structure);
|
if (self::$debug) _debug_array($_structure);
|
||||||
if (!is_array($_structure)) $_structure = array($_structure);
|
|
||||||
foreach($_structure as $part) {
|
foreach($_structure->contentTypeMap() as $mime_id => $mime_type)
|
||||||
if (self::$debug) echo $part->type."/".$part->subType."<br>";
|
{
|
||||||
switch($part->type) {
|
//error_log(__METHOD__."($_uid, ".$_structure->getMimeId().") $mime_id: $mime_type");
|
||||||
case 'MULTIPART':
|
if (self::$debug) echo __METHOD__."($_uid, partID=".$_structure->getMimeId().") $mime_id: $mime_type<br>";
|
||||||
switch($part->subType) {
|
|
||||||
case 'ALTERNATIVE':
|
if (!$mime_id) continue; // ignore multipart/mixed itself
|
||||||
$bodyPart[] = $this->getMultipartAlternative($_uid, $part->subParts, $_htmlMode, $_preserveSeen);
|
|
||||||
|
$part = $_structure->getPart($mime_id);
|
||||||
|
|
||||||
|
switch($part->getPrimaryType())
|
||||||
|
{
|
||||||
|
case 'multipart':
|
||||||
|
switch($part->getSubType())
|
||||||
|
{
|
||||||
|
case 'alternative':
|
||||||
|
$bodyPart[] = $this->getMultipartAlternative($_uid, $part, $_htmlMode, $_preserveSeen);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'MIXED':
|
case 'mixed':
|
||||||
case 'SIGNED':
|
case 'signed':
|
||||||
$bodyPart = array_merge($bodyPart, $this->getMultipartMixed($_uid, $part->subParts, $_htmlMode, $_preserveSeen));
|
$bodyPart = array_merge($bodyPart, $this->getMultipartMixed($_uid, $part, $_htmlMode, $_preserveSeen));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'RELATED':
|
case 'related':
|
||||||
$bodyPart = array_merge($bodyPart, $this->getMultipartRelated($_uid, $part->subParts, $_htmlMode, $_preserveSeen));
|
$bodyPart = array_merge($bodyPart, $this->getMultipartRelated($_uid, $part, $_htmlMode, $_preserveSeen));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'TEXT':
|
case 'text':
|
||||||
switch($part->subType) {
|
switch($part->getSubType())
|
||||||
case 'PLAIN':
|
{
|
||||||
case 'HTML':
|
case 'plain':
|
||||||
case 'CALENDAR': // inline ics/ical files
|
case 'html':
|
||||||
if($part->disposition != 'ATTACHMENT') {
|
case 'calendar': // inline ics/ical files
|
||||||
|
if($part->getDisposition() != 'attachment')
|
||||||
|
{
|
||||||
$bodyPart[] = $this->getTextPart($_uid, $part, $_htmlMode, $_preserveSeen);
|
$bodyPart[] = $this->getTextPart($_uid, $part, $_htmlMode, $_preserveSeen);
|
||||||
}
|
}
|
||||||
//error_log(__METHOD__.__LINE__.' ->'.$part->type."/".$part->subType.' -> BodyPart:'.array2string($bodyPart[count($bodyPart)-1]));
|
//error_log(__METHOD__.__LINE__.' ->'.$part->type."/".$part->subType.' -> BodyPart:'.array2string($bodyPart[count($bodyPart)-1]));
|
||||||
@ -3383,8 +3440,9 @@ $_restoreSession=false;
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'MESSAGE':
|
case 'message':
|
||||||
if($part->subType == 'delivery-status') {
|
if($part->getSubType() == 'delivery-status')
|
||||||
|
{
|
||||||
$bodyPart[] = $this->getTextPart($_uid, $part, $_htmlMode, $_preserveSeen);
|
$bodyPart[] = $this->getTextPart($_uid, $part, $_htmlMode, $_preserveSeen);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -3392,10 +3450,6 @@ $_restoreSession=false;
|
|||||||
default:
|
default:
|
||||||
// do nothing
|
// do nothing
|
||||||
// the part is a attachment
|
// the part is a attachment
|
||||||
#$bodyPart[] = $this->getMessageBody($_uid, $_htmlMode, $part->partID, $part);
|
|
||||||
#if (!($part->type == 'TEXT' && ($part->subType == 'PLAIN' || $part->subType == 'HTML'))) {
|
|
||||||
# $bodyPart[] = $this->getMessageAttachments($_uid, $part->partID, $part);
|
|
||||||
#}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3407,66 +3461,107 @@ $_restoreSession=false;
|
|||||||
* get part of the message, if its stucture is indicating its of multipart related style
|
* get part of the message, if its stucture is indicating its of multipart related style
|
||||||
* a wrapper for multipartmixed
|
* a wrapper for multipartmixed
|
||||||
* @param string/int $_uid the messageuid,
|
* @param string/int $_uid the messageuid,
|
||||||
* @param array $_structure='', if given use structure for parsing
|
* @param Horde_Mime_Part $_structure, if given use structure for parsing
|
||||||
* @param string $_htmlMode, how to display a message, html, plain text, ...
|
* @param string $_htmlMode, how to display a message, html, plain text, ...
|
||||||
* @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek
|
* @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek
|
||||||
* @return array containing the desired part
|
* @return array containing the desired part
|
||||||
*/
|
*/
|
||||||
function getMultipartRelated($_uid, $_structure, $_htmlMode, $_preserveSeen = false)
|
function getMultipartRelated($_uid, Horde_Mime_Part $_structure, $_htmlMode, $_preserveSeen = false)
|
||||||
{
|
{
|
||||||
return $this->getMultipartMixed($_uid, $_structure, $_htmlMode, $_preserveSeen);
|
return $this->getMultipartMixed($_uid, $_structure, $_htmlMode, $_preserveSeen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getTextPart
|
* Fetch a body part
|
||||||
* get Body from message
|
*
|
||||||
* @param string/int $_uid the messageuid,
|
* @param int $_uid
|
||||||
* @param array $_structure='', if given use structure for parsing
|
* @param string $_partID=null
|
||||||
* @param string $_htmlMode, how to display a message, html, plain text, ...
|
* @param string $_folder=null
|
||||||
|
* @param boolean $_preserveSeen=false
|
||||||
|
* @param boolean $_stream=false true return a stream, false return string
|
||||||
|
* @param string &$_encoding=null on return: transfer encoding of returned part
|
||||||
|
* @return string|resource
|
||||||
|
*/
|
||||||
|
function getBodyPart($_uid, $_partID=null, $_folder=null, $_preserveSeen=false, $_stream=false, &$_encoding=null)
|
||||||
|
{
|
||||||
|
if (self::$debug) error_log( __METHOD__."($_uid, $_partID, $_folder, $_preserveSeen)");
|
||||||
|
|
||||||
|
if (empty($_folder))
|
||||||
|
{
|
||||||
|
$_folder = ($this->sessionData['mailbox']? $this->sessionData['mailbox'] : $this->icServer->getCurrentMailbox());
|
||||||
|
}
|
||||||
|
|
||||||
|
// querying contents of body part
|
||||||
|
$uidsToFetch = new Horde_Imap_Client_Ids();
|
||||||
|
$uidsToFetch->add((array)$_uid);
|
||||||
|
|
||||||
|
$fquery = new Horde_Imap_Client_Fetch_Query();
|
||||||
|
$fquery->bodyPart($_partID, array(
|
||||||
|
'peek' => $_preserveSeen,
|
||||||
|
'decode' => true, // try decode on server, does NOT neccessary work
|
||||||
|
));
|
||||||
|
|
||||||
|
$part = $this->icServer->fetch($_folder, $fquery, array(
|
||||||
|
'ids' => $uidsToFetch,
|
||||||
|
))->first();
|
||||||
|
|
||||||
|
if (!$part) return null;
|
||||||
|
|
||||||
|
$_encoding = $part->getBodyPartDecode($_partID);
|
||||||
|
|
||||||
|
return $part->getBodyPart($_partID, $_stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Body from message
|
||||||
|
*
|
||||||
|
* @param int $_uid the messageuid
|
||||||
|
* @param Horde_Mime_Part $_structure=null, if given use structure for parsing
|
||||||
|
* @param string $_htmlMode how to display a message: 'html_only', 'always_display', 'only_if_no_text' or ''
|
||||||
* @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek
|
* @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek
|
||||||
|
* @param boolean $_stream=false true return a stream, false return string
|
||||||
* @return array containing the desired text part, mimeType and charset
|
* @return array containing the desired text part, mimeType and charset
|
||||||
*/
|
*/
|
||||||
function getTextPart($_uid, $_structure, $_htmlMode = '', $_preserveSeen = false)
|
function getTextPart($_uid, Horde_Mime_Part $_structure, $_htmlMode='', $_preserveSeen=false, $_stream=false)
|
||||||
{
|
{
|
||||||
//error_log(__METHOD__.__LINE__.'->'.$_uid.':'.array2string($_structure).' '.function_backtrace());
|
//error_log(__METHOD__.__LINE__.'->'.$_uid.':'.array2string($_structure).' '.function_backtrace());
|
||||||
$bodyPart = array();
|
$bodyPart = array();
|
||||||
if (self::$debug) _debug_array(array($_structure,function_backtrace()));
|
if (self::$debug) _debug_array(array($_structure,function_backtrace()));
|
||||||
$partID = $_structure->partID;
|
|
||||||
$mimePartBody = $this->icServer->getBodyPart($_uid, $partID, true, $_preserveSeen);
|
$partID = $_structure->getMimeId();
|
||||||
if (PEAR::isError($mimePartBody))
|
|
||||||
|
if($_structure->getSubType() == 'html' && !in_array($_htmlMode, array('html_only', 'always_display', 'only_if_no_text')))
|
||||||
{
|
{
|
||||||
error_log(__METHOD__.__LINE__.' failed:'.$mimePartBody->message);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//_debug_array($mimePartBody);
|
|
||||||
//error_log(__METHOD__.__LINE__.' UID:'.$_uid.' PartID:'.$partID.' HTMLMode:'.$_htmlMode.' ->'.array2string($_structure).' body:'.array2string($mimePartBody));
|
|
||||||
if (empty($mimePartBody)) return array(
|
|
||||||
'body' => '',
|
|
||||||
'mimeType' => ($_structure->type == 'TEXT' && $_structure->subType == 'HTML') ? 'text/html' : 'text/plain',
|
|
||||||
'charSet' => self::$displayCharset,
|
|
||||||
);
|
|
||||||
//_debug_array(preg_replace('/PropertyFile___$/','',$this->decodeMimePart($mimePartBody, $_structure->encoding)));
|
|
||||||
if($_structure->subType == 'HTML' && $_htmlMode!= 'html_only' && $_htmlMode != 'always_display' && $_htmlMode != 'only_if_no_text') {
|
|
||||||
$bodyPart = array(
|
$bodyPart = array(
|
||||||
'error' => 1,
|
'error' => 1,
|
||||||
'body' => lang("displaying html messages is disabled"),
|
'body' => lang("displaying html messages is disabled"),
|
||||||
'mimeType' => 'text/html',
|
'mimeType' => 'text/html',
|
||||||
'charSet' => self::$displayCharset,
|
'charSet' => self::$displayCharset,
|
||||||
);
|
);
|
||||||
} elseif ($_structure->subType == 'PLAIN' && $_htmlMode == 'html_only') {
|
}
|
||||||
|
elseif ($_structure->getSubType() == 'plain' && $_htmlMode == 'html_only')
|
||||||
|
{
|
||||||
$bodyPart = array(
|
$bodyPart = array(
|
||||||
'error' => 1,
|
'error' => 1,
|
||||||
'body' => lang("displaying plain messages is disabled"),
|
'body' => lang("displaying plain messages is disabled"),
|
||||||
'mimeType' => 'text/plain', // make sure we do not return mimeType text/html
|
'mimeType' => 'text/plain', // make sure we do not return mimeType text/html
|
||||||
'charSet' => self::$displayCharset,
|
'charSet' => self::$displayCharset,
|
||||||
);
|
);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// some Servers append PropertyFile___ ; strip that here for display
|
// some Servers append PropertyFile___ ; strip that here for display
|
||||||
|
// RB: not sure what this is: preg_replace('/PropertyFile___$/','',$this->decodeMimePart($mimePartBody, $_structure->encoding, $this->getMimePartCharset($_structure))),
|
||||||
|
$this->fetchPartContents($_uid, $_structure, $_stream, $_preserveSeen);
|
||||||
|
|
||||||
$bodyPart = array(
|
$bodyPart = array(
|
||||||
'body' => preg_replace('/PropertyFile___$/','',$this->decodeMimePart($mimePartBody, $_structure->encoding, $this->getMimePartCharset($_structure))),
|
'body' => $_structure->getContents(array(
|
||||||
'mimeType' => ($_structure->type == 'TEXT' && $_structure->subType == 'HTML') ? 'text/html' : 'text/plain',
|
'stream' => $_stream,
|
||||||
'charSet' => $this->getMimePartCharset($_structure),
|
)),
|
||||||
|
'mimeType' => $_structure->getType() == 'text/html' ? 'text/html' : 'text/plain',
|
||||||
|
'charSet' => $_structure->getCharset(),
|
||||||
);
|
);
|
||||||
|
/* RB: not sure this is still necessary
|
||||||
if ($_structure->type == 'TEXT' && $_structure->subType == 'PLAIN' &&
|
if ($_structure->type == 'TEXT' && $_structure->subType == 'PLAIN' &&
|
||||||
is_array($_structure->parameters) && isset($_structure->parameters['FORMAT']) &&
|
is_array($_structure->parameters) && isset($_structure->parameters['FORMAT']) &&
|
||||||
trim(strtolower($_structure->parameters['FORMAT']))=='flowed'
|
trim(strtolower($_structure->parameters['FORMAT']))=='flowed'
|
||||||
@ -3475,7 +3570,23 @@ $_restoreSession=false;
|
|||||||
if (self::$debug) error_log(__METHOD__.__LINE__." detected TEXT/PLAIN Format:flowed -> removing leading blank ('\r\n ') per line");
|
if (self::$debug) error_log(__METHOD__.__LINE__." detected TEXT/PLAIN Format:flowed -> removing leading blank ('\r\n ') per line");
|
||||||
$bodyPart['body'] = str_replace("\r\n ","\r\n", $bodyPart['body']);
|
$bodyPart['body'] = str_replace("\r\n ","\r\n", $bodyPart['body']);
|
||||||
}
|
}
|
||||||
if ($_structure->subType == 'CALENDAR')
|
*/
|
||||||
|
if ($_structure->getSubType() == 'calendar')
|
||||||
|
{
|
||||||
|
$bodyPart['body'] = $this->getEvent($_structure->getContents(), $_structure->getContentTypeParameter('METHOD'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $bodyPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return inline ical as html
|
||||||
|
*
|
||||||
|
* @param string $ical iCal data
|
||||||
|
* @param string $method iTip method eg. 'REPLY'
|
||||||
|
* @return string text to display instead
|
||||||
|
*/
|
||||||
|
function getEvent($ical, $method=null)
|
||||||
{
|
{
|
||||||
// we get an inline CALENDAR ical/ics, we display it using the calendar notification style
|
// we get an inline CALENDAR ical/ics, we display it using the calendar notification style
|
||||||
$calobj = new calendar_ical;
|
$calobj = new calendar_ical;
|
||||||
@ -3483,8 +3594,8 @@ $_restoreSession=false;
|
|||||||
// timezone stuff
|
// timezone stuff
|
||||||
$tz_diff = $GLOBALS['egw_info']['user']['preferences']['common']['tz_offset'] - $this->common_prefs['tz_offset'];
|
$tz_diff = $GLOBALS['egw_info']['user']['preferences']['common']['tz_offset'] - $this->common_prefs['tz_offset'];
|
||||||
// form an event out of ical
|
// form an event out of ical
|
||||||
$event = $calobj->icaltoegw($bodyPart['body']);
|
$events = $calobj->icaltoegw($ical);
|
||||||
$event= $event[0];
|
$event =& $events[0];
|
||||||
// preset the olddate
|
// preset the olddate
|
||||||
$olddate = $calboupdate->format_date($event['start']+$tz_diff);
|
$olddate = $calboupdate->format_date($event['start']+$tz_diff);
|
||||||
// search egw, if we can find it
|
// search egw, if we can find it
|
||||||
@ -3502,19 +3613,20 @@ $_restoreSession=false;
|
|||||||
// for some strange reason, the title of the old event is not replaced with the new title
|
// for some strange reason, the title of the old event is not replaced with the new title
|
||||||
// if you klick on the ics and import it into egw, so we dont show the title here.
|
// if you klick on the ics and import it into egw, so we dont show the title here.
|
||||||
// so if it is a mere reply, we dont use the new title (more detailed info/work needed here)
|
// so if it is a mere reply, we dont use the new title (more detailed info/work needed here)
|
||||||
if ($_structure->parameters['METHOD']=='REPLY') $event['title'] = $oldevent[$eventid[0]]['title'];
|
if ($method == 'REPLY') $event['title'] = $oldevent[$eventid[0]]['title'];
|
||||||
}
|
}
|
||||||
// we prepare the message
|
// we prepare the message
|
||||||
$details = $calboupdate->_get_event_details($event,$action,$event_arr);
|
$details = $calboupdate->_get_event_details($event,$action,$event_arr);
|
||||||
$details['olddate']=$olddate;
|
$details['olddate']=$olddate;
|
||||||
//_debug_array($_structure);
|
//_debug_array($_structure);
|
||||||
list($subject,$info) = $calboupdate->get_update_message($event,($_structure->parameters['METHOD']=='REPLY'?false:true));
|
list($subject,$info) = $calboupdate->get_update_message($event, $method !='REPLY');
|
||||||
$info = $GLOBALS['egw']->preferences->parse_notify($info,$details);
|
$info = $GLOBALS['egw']->preferences->parse_notify($info,$details);
|
||||||
|
|
||||||
// we set the bodyPart, we only show the event, we dont actually do anything, as we expect the user to
|
// we set the bodyPart, we only show the event, we dont actually do anything, as we expect the user to
|
||||||
// click on the attached ics to update his own eventstore
|
// click on the attached ics to update his own eventstore
|
||||||
$bodyPart['body'] = $subject;
|
$text = $subject;
|
||||||
$bodyPart['body'] .= "\n".$info;
|
$text .= "\n".$info;
|
||||||
$bodyPart['body'] .= "\n\n".lang('Event Details follow').":\n";
|
$text .= "\n\n".lang('Event Details follow').":\n";
|
||||||
foreach($event_arr as $key => $val)
|
foreach($event_arr as $key => $val)
|
||||||
{
|
{
|
||||||
if(strlen($details[$key])) {
|
if(strlen($details[$key])) {
|
||||||
@ -3524,73 +3636,40 @@ $_restoreSession=false;
|
|||||||
case 'link':
|
case 'link':
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$bodyPart['body'] .= sprintf("%-20s %s\n",$val['field'].':',$details[$key]);
|
$text .= sprintf("%-20s %s\n",$val['field'].':',$details[$key]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return $text;
|
||||||
}
|
|
||||||
//_debug_array($bodyPart);
|
|
||||||
return $bodyPart;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getMessageBody
|
* Get Body of message
|
||||||
* get Body from message
|
*
|
||||||
* @param string/int $_uid the messageuid,
|
* @param int $_uid the messageuid,
|
||||||
* @param string $_htmlOptions, how to display a message, html, plain text, ...
|
* @param string $_htmlOptions, how to display a message, html, plain text, ...
|
||||||
* @param string/int $_partID='' , the partID, may be omitted
|
* @param string $_partID=null , the partID, may be omitted
|
||||||
* @param array $_structure='', if given use structure for parsing
|
* @param Horde_Mime_Part $_structure=null if given use structure for parsing
|
||||||
* @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek
|
* @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek
|
||||||
* @return array containing the message body, mimeType and charset
|
* @return array containing the message body, mimeType and charset
|
||||||
*/
|
*/
|
||||||
function getMessageBody($_uid, $_htmlOptions='', $_partID='', $_structure = '', $_preserveSeen = false, $_folder = '')
|
function getMessageBody($_uid, $_htmlOptions='', $_partID=null, Horde_Mime_Part $_structure=null, $_preserveSeen = false, $_folder = '')
|
||||||
{
|
{
|
||||||
if (self::$debug) echo __METHOD__."$_uid, $_htmlOptions, $_partID<br>";
|
if (self::$debug) echo __METHOD__."$_uid, $_htmlOptions, $_partID<br>";
|
||||||
if($_htmlOptions != '') {
|
if($_htmlOptions != '') {
|
||||||
$this->htmlOptions = $_htmlOptions;
|
$this->htmlOptions = $_htmlOptions;
|
||||||
}
|
}
|
||||||
if ($_folder=='')
|
if (empty($_folder))
|
||||||
{
|
{
|
||||||
$_folder = $this->sessionData['mailbox'];
|
$_folder = $this->sessionData['mailbox'];
|
||||||
}
|
}
|
||||||
$uidsToFetch = new Horde_Imap_Client_Ids();
|
if (!isset($_structure))
|
||||||
$uidsToFetch->add((array)$_uid);
|
{
|
||||||
|
$_structure = $this->getStructure($_uid, $_partID, $_folder, $_preserveSeen);
|
||||||
$fquery = new Horde_Imap_Client_Fetch_Query();
|
}
|
||||||
$fquery->fullText(array('peek'=>$_preserveSeen));
|
|
||||||
if ($_partID != '')
|
|
||||||
{
|
|
||||||
$fquery->structure();
|
|
||||||
$fquery->bodyPart($_partID,array('peek'=>$_preserveSeen));
|
|
||||||
}
|
|
||||||
$headersNew = $this->icServer->fetch($_folder, $fquery, array(
|
|
||||||
'ids' => $uidsToFetch,
|
|
||||||
));
|
|
||||||
if (is_object($headersNew)) {
|
|
||||||
foreach($headersNew as $id=>$_headerObject) {
|
|
||||||
//$body = $_headerObject->getFullMsg();
|
|
||||||
if ($_partID != '')
|
|
||||||
{
|
|
||||||
$mailStructureObject = $_headerObject->getStructure();
|
|
||||||
//_debug_array($mailStructureObject->contentTypeMap());
|
|
||||||
foreach ($mailStructureObject->contentTypeMap() as $mime_id => $mime_type)
|
|
||||||
{
|
|
||||||
if ($mime_id==$_partID)
|
|
||||||
{
|
|
||||||
//$body = $_headerObject->getBodyPart($mime_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return array(
|
|
||||||
'body' => lang('The mimeparser can not parse this message.'),
|
|
||||||
'mimeType' => 'text/plain',
|
|
||||||
'charSet' => 'utf-8',
|
|
||||||
);
|
|
||||||
|
|
||||||
|
/*
|
||||||
if ($_preserveSeen==false)
|
if ($_preserveSeen==false)
|
||||||
{
|
{
|
||||||
$summary = egw_cache::getCache(egw_cache::INSTANCE,'email','summaryCache'.trim($GLOBALS['egw_info']['user']['account_id']),$callback=null,$callback_params=array(),$expiration=60*60*1);
|
$summary = egw_cache::getCache(egw_cache::INSTANCE,'email','summaryCache'.trim($GLOBALS['egw_info']['user']['account_id']),$callback=null,$callback_params=array(),$expiration=60*60*1);
|
||||||
@ -3605,53 +3684,86 @@ return array(
|
|||||||
egw_cache::setCache(egw_cache::INSTANCE,'email','summaryCache'.trim($GLOBALS['egw_info']['user']['account_id']),$summary,$expiration=60*60*1);
|
egw_cache::setCache(egw_cache::INSTANCE,'email','summaryCache'.trim($GLOBALS['egw_info']['user']['account_id']),$summary,$expiration=60*60*1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch($structure->type) {
|
*/
|
||||||
case 'VIDEO':
|
switch($_structure->getPrimaryType())
|
||||||
case 'AUDIO': // some servers send audiofiles and imagesfiles directly, without any stuff surround it
|
{
|
||||||
case 'IMAGE': // they are displayed as Attachment NOT INLINE
|
case 'application':
|
||||||
return array(
|
return array(
|
||||||
array(
|
array(
|
||||||
'body' => '',
|
'body' => '',
|
||||||
'mimeType' => $structure->subType,
|
'mimeType' => 'text/plain',
|
||||||
|
'charSet' => 'iso-8859-1',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
case 'multipart':
|
||||||
|
switch($_structure->getSubType())
|
||||||
|
{
|
||||||
|
case 'alternative':
|
||||||
|
$bodyParts = array($this->getMultipartAlternative($_uid, $_structure, $this->htmlOptions, $_preserveSeen));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'nil': // multipart with no Alternative
|
||||||
|
case 'mixed':
|
||||||
|
case 'report':
|
||||||
|
case 'signed':
|
||||||
|
$bodyParts = $this->getMultipartMixed($_uid, $_structure, $this->htmlOptions, $_preserveSeen);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'related':
|
||||||
|
$bodyParts = $this->getMultipartRelated($_uid, $_structure, $this->htmlOptions, $_preserveSeen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return self::normalizeBodyParts($bodyParts);
|
||||||
|
|
||||||
|
case 'video':
|
||||||
|
case 'audio': // some servers send audiofiles and imagesfiles directly, without any stuff surround it
|
||||||
|
case 'image': // they are displayed as Attachment NOT INLINE
|
||||||
|
return array(
|
||||||
|
array(
|
||||||
|
'body' => '',
|
||||||
|
'mimeType' => $_structure->subType,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
break;
|
|
||||||
case 'TEXT':
|
case 'text':
|
||||||
$bodyPart = array();
|
$bodyPart = array();
|
||||||
if ( $structure->disposition != 'ATTACHMENT') {
|
if ($_structure->getDisposition() != 'attachment')
|
||||||
switch($structure->subType) {
|
{
|
||||||
case 'CALENDAR':
|
switch($_structure->getSubType())
|
||||||
|
{
|
||||||
|
case 'calendar':
|
||||||
// this is handeled in getTextPart
|
// this is handeled in getTextPart
|
||||||
case 'HTML':
|
case 'html':
|
||||||
case 'PLAIN':
|
case 'plain':
|
||||||
default:
|
default:
|
||||||
$bodyPart = array($this->getTextPart($_uid, $structure, $this->htmlOptions, $_preserveSeen));
|
$bodyPart = array($this->getTextPart($_uid, $_structure, $this->htmlOptions, $_preserveSeen));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// what if the structure->disposition is attachment ,...
|
// what if the structure->disposition is attachment ,...
|
||||||
}
|
}
|
||||||
return self::normalizeBodyParts($bodyPart);
|
return self::normalizeBodyParts($bodyPart);
|
||||||
break;
|
|
||||||
case 'ATTACHMENT':
|
case 'attachment':
|
||||||
case 'MESSAGE':
|
case 'message':
|
||||||
switch($structure->subType) {
|
switch($_structure->getSubType())
|
||||||
case 'RFC822':
|
{
|
||||||
$newStructure = array_shift($structure->subParts);
|
case 'rfc822':
|
||||||
|
$newStructure = $_structure->getParts();
|
||||||
if (self::$debug) {echo __METHOD__." Message -> RFC -> NewStructure:"; _debug_array($newStructure);}
|
if (self::$debug) {echo __METHOD__." Message -> RFC -> NewStructure:"; _debug_array($newStructure);}
|
||||||
return self::normalizeBodyParts($this->getMessageBody($_uid, $_htmlOptions, $newStructure->partID, $newStructure, $_preserveSeen, $_folder));
|
return self::normalizeBodyParts($this->getMessageBody($_uid, $_htmlOptions, $newStructure->getMimeId(), $newStructure, $_preserveSeen, $_folder));
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (self::$debug) _debug_array($structure);
|
if (self::$debug) _debug_array($_structure);
|
||||||
return array(
|
return array(
|
||||||
array(
|
array(
|
||||||
'body' => lang('The mimeparser can not parse this message.'),
|
'body' => lang('The mimeparser can not parse this message.').$_structure->getType(),
|
||||||
'mimeType' => 'text/plain',
|
'mimeType' => 'text/plain',
|
||||||
'charSet' => 'iso-8859-1',
|
'charSet' => self::$displayCharset,
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3662,6 +3774,9 @@ return array(
|
|||||||
*/
|
*/
|
||||||
static function normalizeBodyParts($_bodyParts)
|
static function normalizeBodyParts($_bodyParts)
|
||||||
{
|
{
|
||||||
|
// RB: dont think this is still necessary
|
||||||
|
return $_bodyParts;
|
||||||
|
|
||||||
if (is_array($_bodyParts))
|
if (is_array($_bodyParts))
|
||||||
{
|
{
|
||||||
foreach($_bodyParts as $singleBodyPart)
|
foreach($_bodyParts as $singleBodyPart)
|
||||||
@ -4165,57 +4280,82 @@ return array(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getMessageAttachments
|
* Get structure of a mail or part of a mail
|
||||||
* parse the structure for attachments, it returns not the attachments itself, but an array of information about the attachment
|
*
|
||||||
* @param string/int $_uid the messageuid,
|
* @param int $_uid
|
||||||
* @param string/int $_partID='' , the partID, may be omitted
|
* @param string $_partID=null
|
||||||
* @param array $_structure='', if given use structure for parsing
|
* @param string $_folder=null
|
||||||
|
* @param boolean $_preserveSeen=false flag to preserve the seenflag by using body.peek
|
||||||
|
* @param Horde_Imap_Client_Fetch_Query $fquery=null default query just structure
|
||||||
|
* @return Horde_Mime_Part
|
||||||
|
*/
|
||||||
|
function getStructure($_uid, $_partID=null, $_folder=null, $_preserveSeen=false)
|
||||||
|
{
|
||||||
|
if (self::$debug) error_log( __METHOD__.":$_uid, $_partID");
|
||||||
|
|
||||||
|
if (empty($_folder))
|
||||||
|
{
|
||||||
|
$_folder = ($this->sessionData['mailbox']? $this->sessionData['mailbox'] : $this->icServer->getCurrentMailbox());
|
||||||
|
}
|
||||||
|
$uidsToFetch = new Horde_Imap_Client_Ids();
|
||||||
|
$uidsToFetch->add((array)$_uid);
|
||||||
|
|
||||||
|
$_fquery = new Horde_Imap_Client_Fetch_Query();
|
||||||
|
// not sure why Klaus add these, seem not necessary
|
||||||
|
// $fquery->envelope();
|
||||||
|
// $fquery->size();
|
||||||
|
$_fquery->structure();
|
||||||
|
if ($_partID) $_fquery->bodyPart($_partID, array('peek' => $_preserveSeen));
|
||||||
|
|
||||||
|
$mail = $this->icServer->fetch($_folder, $_fquery, array(
|
||||||
|
'ids' => $uidsToFetch,
|
||||||
|
))->first();
|
||||||
|
|
||||||
|
return $mail->getStructure();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the structure for attachments
|
||||||
|
*
|
||||||
|
* Returns not the attachments itself, but an array of information about the attachment
|
||||||
|
*
|
||||||
|
* @param int $_uid the messageuid,
|
||||||
|
* @param string $_partID=null , the partID, may be omitted
|
||||||
|
* @param Horde_Mime_Part $_structure=null if given use structure for parsing
|
||||||
* @param boolean $fetchEmbeddedImages=true,
|
* @param boolean $fetchEmbeddedImages=true,
|
||||||
* @param boolean $fetchTextCalendar=false,
|
* @param boolean $fetchTextCalendar=false,
|
||||||
* @param boolean $resolveTNEF=true
|
* @param boolean $resolveTNEF=true
|
||||||
* @return array an array of information about the attachment: array of array(name, size, mimeType, partID, encoding)
|
* @return array an array of information about the attachment: array of array(name, size, mimeType, partID, encoding)
|
||||||
*/
|
*/
|
||||||
function getMessageAttachments($_uid, $_partID='', $_structure='', $fetchEmbeddedImages=true, $fetchTextCalendar=false, $resolveTNEF=true)
|
function getMessageAttachments($_uid, $_partID=null, Horde_Mime_Part $_structure=null, $fetchEmbeddedImages=true, $fetchTextCalendar=false, $resolveTNEF=true)
|
||||||
{
|
{
|
||||||
if (self::$debug) error_log( __METHOD__.":$_uid, $_partID");
|
if (self::$debug) error_log( __METHOD__.":$_uid, $_partID");
|
||||||
$_folder = ($this->sessionData['mailbox']? $this->sessionData['mailbox'] : $this->icServer->getCurrentMailbox());
|
|
||||||
$uidsToFetch = new Horde_Imap_Client_Ids();
|
|
||||||
$uidsToFetch->add((array)$_uid);
|
|
||||||
|
|
||||||
$fquery = new Horde_Imap_Client_Fetch_Query();
|
if (!isset($_structure))
|
||||||
$fquery->envelope();
|
|
||||||
$fquery->size();
|
|
||||||
$fquery->structure();
|
|
||||||
$headersNew = $this->icServer->fetch($_folder, $fquery, array(
|
|
||||||
'ids' => $uidsToFetch,
|
|
||||||
));
|
|
||||||
$count = 0;
|
|
||||||
if (is_object($headersNew)) {
|
|
||||||
if (self::$debug) $starttime = microtime(true);
|
|
||||||
foreach($headersNew->ids() as $id) {
|
|
||||||
$_headerObject = $headersNew->get($id);
|
|
||||||
$uid = $headerObject['UID']= ($_headerObject->getUid()?$_headerObject->getUid():$id);
|
|
||||||
//error_log(__METHOD__.__LINE__.array2string($_headerObject));
|
|
||||||
$headerObject['SIZE'] = $_headerObject->getSize();
|
|
||||||
$mailStructureObject = $_headerObject->getStructure();
|
|
||||||
$headerObject['ATTACHMENTS']=null;
|
|
||||||
foreach ($mailStructureObject->contentTypeMap() as $mime_id => $mime_type)
|
|
||||||
{
|
{
|
||||||
$part = $mailStructureObject->getPart($mime_id);
|
$_structure = $this->getStructure($_uid, $_partID);
|
||||||
if ($part->getDisposition()=='attachment')
|
}
|
||||||
|
|
||||||
|
foreach($_structure->contentTypeMap() as $mime_id => $mime_type)
|
||||||
{
|
{
|
||||||
$headerObject['ATTACHMENTS'][$mime_id]=$part->getAllDispositionParameters();
|
$part = $_structure->getPart($mime_id);
|
||||||
$headerObject['ATTACHMENTS'][$mime_id]['mimeType']=$mime_type;
|
|
||||||
$headerObject['ATTACHMENTS'][$mime_id]['uid']=$id;
|
if ($part->getDisposition() == 'attachment' ||
|
||||||
$headerObject['ATTACHMENTS'][$mime_id]['partID']=$mime_id;
|
$fetchEmbeddedImages && $part->getDisposition() == 'inline' &&
|
||||||
if (!isset($headerObject['ATTACHMENTS'][$mime_id]['name']))$headerObject['ATTACHMENTS'][$mime_id]['name']=$part->getName();
|
$part->getPrimaryType() == 'image')
|
||||||
}
|
{
|
||||||
}
|
$attachment = $part->getAllDispositionParameters();
|
||||||
if (isset($headerObject['ATTACHMENTS']) && count($headerObject['ATTACHMENTS'])) foreach ($headerObject['ATTACHMENTS'] as $pID =>$a) $attachments[]=$a;
|
$attachment['mimeType'] = $mime_type;
|
||||||
|
$attachment['uid'] = $_uid;
|
||||||
|
$attachment['partID'] = $mime_id;
|
||||||
|
if (!isset($attachment['name'])) $attachment['name'] = $part->getName();
|
||||||
|
$attachment['size'] = $part->getBytes();
|
||||||
|
if (($cid = $part->getContentId())) $attachment['cid'] = $cid;
|
||||||
|
|
||||||
|
$attachments[] = $attachment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $attachments;
|
return $attachments;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -4428,110 +4568,83 @@ error_log(__METHOD__.__LINE__.array2string($headerObject['ATTACHMENTS'][$mime_id
|
|||||||
* @param string|int $_uid
|
* @param string|int $_uid
|
||||||
* @param string $_cid
|
* @param string $_cid
|
||||||
* @param string $_part
|
* @param string $_part
|
||||||
* @return array with values for keys 'type', 'filename' and 'attachment'
|
* @param boolean $_stream=null null do NOT fetch content, use fetchPartContents later
|
||||||
|
* true:
|
||||||
|
* @return Horde_Mime_Part
|
||||||
*/
|
*/
|
||||||
function getAttachmentByCID($_uid, $_cid, $_part)
|
function getAttachmentByCID($_uid, $_cid, $_part, $_stream=null)
|
||||||
{
|
{
|
||||||
// some static variables to avoid fetching the same mail multiple times
|
// some static variables to avoid fetching the same mail multiple times
|
||||||
static $uid,$part,$attachments,$structure;
|
static $uid=null, $part=null, $structure=null;
|
||||||
//error_log(__METHOD__.__LINE__.":$_uid, $_cid, $_part");
|
//error_log(__METHOD__.__LINE__.":$_uid, $_cid, $_part");
|
||||||
|
|
||||||
if(empty($_cid)) return false;
|
if(empty($_cid)) return false;
|
||||||
|
|
||||||
if ($_uid != $uid || $_part != $part)
|
if ($_uid != $uid || $_part != $part)
|
||||||
{
|
{
|
||||||
$attachments = $this->getMessageAttachments($uid=$_uid, $part=$_part);
|
$structure = $this->getStructure($uid=$_uid, $part=$_part);
|
||||||
$structure = null;
|
|
||||||
}
|
}
|
||||||
$partID = false;
|
/** @var Horde_Mime_Part */
|
||||||
foreach($attachments as $attachment)
|
$attachment = null;
|
||||||
|
foreach($structure->contentTypeMap() as $mime_id => $mime_type)
|
||||||
{
|
{
|
||||||
//error_log(print_r($attachment,true));
|
$part = $structure->getPart($mime_id);
|
||||||
if(isset($attachment['cid']) && (strpos($attachment['cid'], $_cid) !== false || strpos($_cid, $attachment['cid']) !== false))
|
|
||||||
|
if ($part->getPrimaryType() == 'image' &&
|
||||||
|
(($cid = $part->getContentId()) &&
|
||||||
|
// RB: seem a bit fague to search for inclusion in both ways
|
||||||
|
(strpos($cid, $_cid) !== false || strpos($_cid, $cid) !== false)) ||
|
||||||
|
(($name = $part->getName()) &&
|
||||||
|
(strpos($name, $_cid) !== false || strpos($_cid, $name) !== false)))
|
||||||
{
|
{
|
||||||
$partID = $attachment['partID'];
|
// if we have a direct match, dont search any further
|
||||||
|
if ($cid == $_cid)
|
||||||
|
{
|
||||||
|
$attachment = $part;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// everything else we only consider after we checked all
|
||||||
|
if (!isset($attachment)) $attachment = $part;
|
||||||
}
|
}
|
||||||
if ($partID == false)
|
}
|
||||||
|
// do we want content fetched, can be done later, if not needed
|
||||||
|
if (isset($_stream))
|
||||||
{
|
{
|
||||||
foreach($attachments as $attachment)
|
$this->fetchPartContents($_uid, $attachment, $_stream);
|
||||||
|
}
|
||||||
|
// set name as filename, if not set
|
||||||
|
if (!$attachment->getDispositionParameter('filename'))
|
||||||
{
|
{
|
||||||
// if the former did not match try matching the cid to the name of the attachment
|
$attachment->setDispositionParameter('filename', $attachment->getName());
|
||||||
if(isset($attachment['cid']) && isset($attachment['name']) && (strpos($attachment['name'], $_cid) !== false || strpos($_cid, $attachment['name']) !== false))
|
}
|
||||||
|
// guess type, if not set
|
||||||
|
if ($attachment->getType() == 'application/octet-stream')
|
||||||
{
|
{
|
||||||
$partID = $attachment['partID'];
|
$attachment->setType(mime_magic::filename2mime($attachment->getDispositionParameter('filename')));
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
//error_log(__METHOD__."($_uid, '$_cid', '$_part') returning ".array2string($attachment));
|
||||||
}
|
return $attachment;
|
||||||
if ($partID == false)
|
|
||||||
{
|
|
||||||
foreach($attachments as $attachment)
|
|
||||||
{
|
|
||||||
// if the former did not match try matching the cid to the name of the attachment, AND there is no mathing attachment with cid
|
|
||||||
if(isset($attachment['name']) && (strpos($attachment['name'], $_cid) !== false || strpos($_cid, $attachment['name']) !== false))
|
|
||||||
{
|
|
||||||
$partID = $attachment['partID'];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//error_log( "Cid:$_cid PARTID:$partID<bR>"); #exit;
|
|
||||||
|
|
||||||
if($partID == false) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse message structure
|
/**
|
||||||
if (is_null($structure))
|
* Fetch and add contents to a part
|
||||||
|
*
|
||||||
|
* To get contents you use $part->getContents();
|
||||||
|
*
|
||||||
|
* @param int $_uid
|
||||||
|
* @param Horde_Mime_Part $part
|
||||||
|
* @param boolean $_stream=false true return a stream, false a string
|
||||||
|
* @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek
|
||||||
|
* @return Horde_Mime_Part
|
||||||
|
*/
|
||||||
|
public function fetchPartContents($_uid, Horde_Mime_Part $part, $_stream=false, $_preserveSeen=false)
|
||||||
{
|
{
|
||||||
$structure = $this->_getStructure($_uid, true);
|
// we need to set content on structure to decode transfer encoding
|
||||||
}
|
$part->setContents(
|
||||||
$part_structure = $this->_getSubStructure($structure, $partID);
|
$this->getBodyPart($_uid, $part->getMimeId(), null, $_preserveSeen, $_stream, $encoding=null),
|
||||||
$filename = $this->getFileNameFromStructure($part_structure, $_uid, $_uid, $part_structure->partID);
|
array('encoding' => $encoding));
|
||||||
$attachment = $this->icServer->getBodyPart($_uid, $partID, true);
|
|
||||||
if (PEAR::isError($attachment))
|
|
||||||
{
|
|
||||||
error_log(__METHOD__.__LINE__.' failed:'.$attachment->message);
|
|
||||||
return array('type' => 'text/plain',
|
|
||||||
'filename' => 'error.txt',
|
|
||||||
'attachment' =>__METHOD__.' failed:'.$attachment->message
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PEAR::isError($attachment))
|
return $part;
|
||||||
{
|
|
||||||
error_log(__METHOD__.__LINE__.' failed:'.$attachment->message);
|
|
||||||
return array('type' => 'text/plain',
|
|
||||||
'filename' => 'error.txt',
|
|
||||||
'attachment' =>__METHOD__.' failed:'.$attachment->message
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ($part_structure->encoding) {
|
|
||||||
case 'BASE64':
|
|
||||||
// use imap_base64 to decode
|
|
||||||
$attachment = imap_base64($attachment);
|
|
||||||
break;
|
|
||||||
case 'QUOTED-PRINTABLE':
|
|
||||||
// use imap_qprint to decode
|
|
||||||
#$attachment = imap_qprint($attachment);
|
|
||||||
$attachment = quoted_printable_decode($attachment);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// it is either not encoded or we don't know about it
|
|
||||||
}
|
|
||||||
|
|
||||||
$attachmentData = array(
|
|
||||||
'type' => $part_structure->type .'/'. $part_structure->subType,
|
|
||||||
'filename' => $filename,
|
|
||||||
'attachment' => $attachment
|
|
||||||
);
|
|
||||||
// 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']);
|
|
||||||
|
|
||||||
return $attachmentData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1560,11 +1560,11 @@ unset($query['actions']);
|
|||||||
}
|
}
|
||||||
if (!empty($uid)) $flags = $this->mail_bo->getFlags($uid);
|
if (!empty($uid)) $flags = $this->mail_bo->getFlags($uid);
|
||||||
$envelope = $this->mail_bo->getMessageEnvelope($uid, $partID,true);
|
$envelope = $this->mail_bo->getMessageEnvelope($uid, $partID,true);
|
||||||
//_debug_array($headers);
|
|
||||||
$rawheaders = $this->mail_bo->getMessageRawHeader($uid, $partID);
|
$rawheaders = $this->mail_bo->getMessageRawHeader($uid, $partID);
|
||||||
$fetchEmbeddedImages = false;
|
$fetchEmbeddedImages = false;
|
||||||
if ($htmlOptions !='always_display') $fetchEmbeddedImages = true;
|
if ($htmlOptions !='always_display') $fetchEmbeddedImages = true;
|
||||||
$attachments = $this->mail_bo->getMessageAttachments($uid, $partID, '',$fetchEmbeddedImages);
|
$attachments = $this->mail_bo->getMessageAttachments($uid, $partID, null, $fetchEmbeddedImages);
|
||||||
//_debug_array($headers);
|
//_debug_array($headers);
|
||||||
$attachmentHTMLBlock = self::createAttachmentBlock($attachments, $rowID, $uid, $mailbox);
|
$attachmentHTMLBlock = self::createAttachmentBlock($attachments, $rowID, $uid, $mailbox);
|
||||||
$webserverURL = $GLOBALS['egw_info']['server']['webserver_url'];
|
$webserverURL = $GLOBALS['egw_info']['server']['webserver_url'];
|
||||||
@ -1620,17 +1620,17 @@ unset($query['actions']);
|
|||||||
foreach($envelope[$field] as $field_data)
|
foreach($envelope[$field] as $field_data)
|
||||||
{
|
{
|
||||||
//error_log(__METHOD__.__LINE__.array2string($field_data));
|
//error_log(__METHOD__.__LINE__.array2string($field_data));
|
||||||
$content[$field][] = $field_data['EMAIL'];
|
$content[$field][] = $field_data;//['EMAIL'];
|
||||||
$sel_options[$field][] = array(
|
$sel_options[$field][] = array(
|
||||||
// taglist requires these
|
// taglist requires these
|
||||||
'id' => $field_data['EMAIL'],
|
'id' => $field_data,//['EMAIL'],
|
||||||
'label' => ($field_data['PERSONAL_NAME'] && $field_data['PERSONAL_NAME']!='NIL') ? $field_data['PERSONAL_NAME']:$field_data['EMAIL'],
|
// 'label' => ($field_data['PERSONAL_NAME'] && $field_data['PERSONAL_NAME']!='NIL') ? $field_data['PERSONAL_NAME']:$field_data['EMAIL'],
|
||||||
// Optional
|
// Optional
|
||||||
'title' => str_replace('"',"'",$field_data['RFC822_EMAIL']),
|
'title' => str_replace('"',"'",$field_data['RFC822_EMAIL']),
|
||||||
)
|
);
|
||||||
// Add all other data, will be preserved & passed to js onclick
|
// Add all other data, will be preserved & passed to js onclick
|
||||||
// Also available in widget.options.select_options
|
// Also available in widget.options.select_options
|
||||||
+ $field_data;
|
//+ $field_data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$actionsenabled = self::get_actions();
|
$actionsenabled = self::get_actions();
|
||||||
@ -1846,7 +1846,10 @@ unset($query['actions']);
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static function emailAddressToHTML($_emailAddress, $_organisation='', $allwaysShowMailAddress=false, $showAddToAdrdessbookLink=true, $decode=true) {
|
static function emailAddressToHTML($_emailAddress, $_organisation='', $allwaysShowMailAddress=false, $showAddToAdrdessbookLink=true, $decode=true)
|
||||||
|
{
|
||||||
|
// maybe envelop structure was different before, Horde returns either string with mail-address or array of mail-addresses
|
||||||
|
return is_array($_emailAddress) ? implode(', ', $_emailAddress) : $_emailAddress;
|
||||||
//_debug_array($_emailAddress);
|
//_debug_array($_emailAddress);
|
||||||
// create some nice formated HTML for senderaddress
|
// create some nice formated HTML for senderaddress
|
||||||
|
|
||||||
@ -2031,36 +2034,37 @@ unset($query['actions']);
|
|||||||
$cid = base64_decode($_GET['cid']);
|
$cid = base64_decode($_GET['cid']);
|
||||||
$partID = urldecode($_GET['partID']);
|
$partID = urldecode($_GET['partID']);
|
||||||
if (!empty($_GET['mailbox'])) $mailbox = base64_decode($_GET['mailbox']);
|
if (!empty($_GET['mailbox'])) $mailbox = base64_decode($_GET['mailbox']);
|
||||||
|
|
||||||
//error_log(__METHOD__.__LINE__.":$uid, $cid, $partID");
|
//error_log(__METHOD__.__LINE__.":$uid, $cid, $partID");
|
||||||
$this->mail_bo->reopen($mailbox);
|
$this->mail_bo->reopen($mailbox);
|
||||||
|
|
||||||
$attachment = $this->mail_bo->getAttachmentByCID($uid, $cid, $partID);
|
$attachment = $this->mail_bo->getAttachmentByCID($uid, $cid, $partID, true); // true get contents as stream
|
||||||
|
|
||||||
$this->mail_bo->closeConnection();
|
$this->mail_bo->closeConnection();
|
||||||
|
|
||||||
$GLOBALS['egw']->session->commit_session();
|
$GLOBALS['egw']->session->commit_session();
|
||||||
|
|
||||||
if(is_array($attachment)) {
|
if ($attachment)
|
||||||
//error_log("Content-Type: ".$attachment['type']."; name=\"". $attachment['filename'] ."\"");
|
{
|
||||||
header ("Content-Type: ". strtolower($attachment['type']) ."; name=\"". $attachment['filename'] ."\"");
|
header("Content-Type: ". $attachment->getType());// ."; name=\"". $attachment['filename'] ."\"");
|
||||||
header ('Content-Disposition: inline; filename="'. $attachment['filename'] .'"');
|
header('Content-Disposition: inline; filename="'. $attachment->getDispositionParameter('filename') .'"');
|
||||||
header("Expires: 0");
|
header("Expires: 0");
|
||||||
// the next headers are for IE and SSL
|
// the next headers are for IE and SSL
|
||||||
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
|
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
|
||||||
header("Pragma: public");
|
header("Pragma: public");
|
||||||
|
|
||||||
echo trim($attachment['attachment']);
|
echo $attachment->getContents();
|
||||||
exit;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
$GLOBALS['egw']->common->egw_exit();
|
{
|
||||||
|
// send a 404 Not found
|
||||||
exit;
|
header("HTTP/1.1 404 Not found");
|
||||||
|
}
|
||||||
|
common::egw_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAttachment()
|
function getAttachment()
|
||||||
{
|
{
|
||||||
|
|
||||||
if(isset($_GET['id'])) $rowID = $_GET['id'];
|
if(isset($_GET['id'])) $rowID = $_GET['id'];
|
||||||
if(isset($_GET['part'])) $partID = $_GET['part'];
|
if(isset($_GET['part'])) $partID = $_GET['part'];
|
||||||
|
|
||||||
@ -2303,12 +2307,13 @@ $this->uid = $uid;
|
|||||||
$this->partID = $partID;
|
$this->partID = $partID;
|
||||||
$bufferHtmlOptions = $this->mail_bo->htmlOptions;
|
$bufferHtmlOptions = $this->mail_bo->htmlOptions;
|
||||||
if (empty($htmlOptions)) $htmlOptions = $this->mail_bo->htmlOptions;
|
if (empty($htmlOptions)) $htmlOptions = $this->mail_bo->htmlOptions;
|
||||||
$bodyParts = $this->mail_bo->getMessageBody($uid, ($htmlOptions?$htmlOptions:''), $partID, '', false, $mailbox);
|
$bodyParts = $this->mail_bo->getMessageBody($uid, ($htmlOptions?$htmlOptions:''), $partID, null, false, $mailbox);
|
||||||
|
|
||||||
//error_log(__METHOD__.__LINE__.array2string($bodyParts));
|
//error_log(__METHOD__.__LINE__.array2string($bodyParts));
|
||||||
$meetingRequest = false;
|
$meetingRequest = false;
|
||||||
$fetchEmbeddedImages = false;
|
$fetchEmbeddedImages = false;
|
||||||
if ($htmlOptions !='always_display') $fetchEmbeddedImages = true;
|
if ($htmlOptions !='always_display') $fetchEmbeddedImages = true;
|
||||||
$attachments = $this->mail_bo->getMessageAttachments($uid, $partID, '',$fetchEmbeddedImages,true);
|
$attachments = $this->mail_bo->getMessageAttachments($uid, $partID, null, $fetchEmbeddedImages, true);
|
||||||
foreach ((array)$attachments as $key => $attach)
|
foreach ((array)$attachments as $key => $attach)
|
||||||
{
|
{
|
||||||
if (strtolower($attach['mimeType']) == 'text/calendar' &&
|
if (strtolower($attach['mimeType']) == 'text/calendar' &&
|
||||||
@ -2329,7 +2334,7 @@ $this->partID = $partID;
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//_debug_array($bodyParts); die(__METHOD__.__LINE__);
|
||||||
// Compose the content of the frame
|
// Compose the content of the frame
|
||||||
$frameHtml =
|
$frameHtml =
|
||||||
$this->get_email_header($this->mail_bo->getStyles($bodyParts),$fullHeader).
|
$this->get_email_header($this->mail_bo->getStyles($bodyParts),$fullHeader).
|
||||||
@ -2633,9 +2638,10 @@ blockquote[type=cite] {
|
|||||||
$attachment = $this->mail_bo->getAttachmentByCID($this->uid, $matches[2], $this->partID);
|
$attachment = $this->mail_bo->getAttachmentByCID($this->uid, $matches[2], $this->partID);
|
||||||
|
|
||||||
// only use data uri for "smaller" images, as otherwise the first display of the mail takes to long
|
// only use data uri for "smaller" images, as otherwise the first display of the mail takes to long
|
||||||
if (bytes($attachment['attachment']) < 8192) // msie=8 allows max 32k data uris
|
if ($attachment->getBytes() < 8192) // msie=8 allows max 32k data uris
|
||||||
{
|
{
|
||||||
$cache[$imageURL] = 'data:'.$attachment['type'].';base64,'.base64_encode($attachment['attachment']);
|
$this->mail_bo->fetchPartContents($this->uid, $attachment);
|
||||||
|
$cache[$imageURL] = 'data:'.$attachment->getType().';base64,'.base64_encode($attachment->getContents());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2674,9 +2680,10 @@ blockquote[type=cite] {
|
|||||||
$attachment = $this->mail_bo->getAttachmentByCID($this->uid, $matches[1], $this->partID);
|
$attachment = $this->mail_bo->getAttachmentByCID($this->uid, $matches[1], $this->partID);
|
||||||
|
|
||||||
// only use data uri for "smaller" images, as otherwise the first display of the mail takes to long
|
// only use data uri for "smaller" images, as otherwise the first display of the mail takes to long
|
||||||
if (bytes($attachment['attachment']) < 8192) // msie=8 allows max 32k data uris
|
if (bytes($attachment->getBytes()) < 8192) // msie=8 allows max 32k data uris
|
||||||
{
|
{
|
||||||
$cache[$imageURL] = 'data:'.$attachment['type'].';base64,'.base64_encode($attachment['attachment']);
|
$this->mail_bo->fetchPartContents($this->uid, $attachment);
|
||||||
|
$cache[$imageURL] = 'data:'.$attachment->getType().';base64,'.base64_encode($attachment->getContents());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2715,9 +2722,10 @@ blockquote[type=cite] {
|
|||||||
$attachment = $this->mail_bo->getAttachmentByCID($this->uid, $matches[1], $this->partID);
|
$attachment = $this->mail_bo->getAttachmentByCID($this->uid, $matches[1], $this->partID);
|
||||||
|
|
||||||
// only use data uri for "smaller" images, as otherwise the first display of the mail takes to long
|
// only use data uri for "smaller" images, as otherwise the first display of the mail takes to long
|
||||||
if (bytes($attachment['attachment']) < 8192) // msie=8 allows max 32k data uris
|
if ($attachment->getBytes() < 8192) // msie=8 allows max 32k data uris
|
||||||
{
|
{
|
||||||
$cache[$imageURL] = 'data:'.$attachment['type'].';base64,'.base64_encode($attachment['attachment']);
|
$this->mail_bo->fetchPartContents($this->uid, $attachment);
|
||||||
|
$cache[$imageURL] = 'data:'.$attachment->getType().';base64,'.base64_encode($attachment->getContents());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user