diff --git a/mail/inc/class.mail_bo.inc.php b/mail/inc/class.mail_bo.inc.php
index e711356e4b..27fb03186e 100644
--- a/mail/inc/class.mail_bo.inc.php
+++ b/mail/inc/class.mail_bo.inc.php
@@ -14,6 +14,8 @@
* Mail worker class
* -provides backend functionality for all classes in Mail
* -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
{
@@ -245,7 +247,7 @@ $_restoreSession=false;
{
try {
$account = emailadmin_account::read($_profileID);
- if (!empty($account->acc_imap_host))
+ if ($account->acc_imap_host)
{
return $_profileID;
}
@@ -538,6 +540,7 @@ $_restoreSession=false;
*/
function closeConnection() {
//if ($icServer->_connected) error_log(__METHOD__.__LINE__.' disconnect from Server');
+error_log(__METHOD__."() ".function_backtrace());
$this->icServer->disconnect();
}
@@ -549,6 +552,7 @@ $_restoreSession=false;
*/
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
// eMails when not in "current-Folder" (folder that is selected by UI)
static $folderOpened;
@@ -835,6 +839,7 @@ $_restoreSession=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 (!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
* a wrapper for multipartmixed
* @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 boolean $_preserveSeen flag to preserve the seenflag by using body.peek
* @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)
// 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).
- $partText = false;
- $partHTML = false;
+ $partText = $partHTML = null;
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) {
- if ($mimePart->subType == 'CALENDAR' && $partText === false) $partText = $mimePart; // only if there is no partText set already
- if ($mimePart->subType == 'PLAIN') $partText = $mimePart;
- } elseif($mimePart->type == 'TEXT' && $mimePart->subType == 'HTML' && $mimePart->bytes > 0) {
- $partHTML = $mimePart;
- } elseif ($mimePart->type == 'MULTIPART' && ($mimePart->subType == 'RELATED' || $mimePart->subType == 'MIXED') && is_array($mimePart->subParts)) {
- // 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");
- $partHTML = $mimePart;
- } elseif ($mimePart->type == 'MULTIPART' && $mimePart->subType == 'ALTERNATIVE' && is_array($mimePart->subParts)) {
- //cascading multipartAlternative structure, assuming only the first one is to be used
- return $this->getMultipartAlternative($_uid,$mimePart->subParts,$_htmlMode, $_preserveSeen);
- }
- }
- //error_log(__METHOD__.__LINE__.$_htmlMode);
- switch($_htmlMode) {
- case 'html_only':
- case 'always_display':
- if(is_object($partHTML)) {
- if($partHTML->subType == 'RELATED') {
- return $this->getMultipartRelated($_uid, $partHTML, $_htmlMode, $_preserveSeen);
- } elseif($partHTML->subType == 'MIXED') {
- return $this->getMultipartMixed($_uid, $partHTML, $_htmlMode, $_preserveSeen);
- } else {
- return $this->getTextPart($_uid, $partHTML, $_htmlMode, $_preserveSeen);
- }
- } elseif(is_object($partText) && $_htmlMode=='always_display') {
- return $this->getTextPart($_uid, $partText, $_htmlMode, $_preserveSeen);
- }
- break;
- case 'only_if_no_text':
- if(is_object($partText)) {
- return $this->getTextPart($_uid, $partText, $_htmlMode, $_preserveSeen);
- } elseif(is_object($partHTML)) {
- if($partHTML->type) {
- return $this->getMultipartRelated($_uid, $partHTML, $_htmlMode, $_preserveSeen);
- } else {
- return $this->getTextPart($_uid, $partHTML, 'always_display', $_preserveSeen);
- }
- }
+ foreach($_structure->contentTypeMap() as $mime_id => $mime_type)
+ {
+ //error_log(__METHOD__."($_uid, ".$_structure->getMimeId().") $mime_id: $mime_type");
+ if (self::$debug) echo __METHOD__."($_uid, partID=".$_structure->getMimeId().") $mime_id: $mime_type
";
- break;
+ if (!$mime_id) continue; // ignore multipart/alternative itself
- default:
- if(is_object($partText)) {
- return $this->getTextPart($_uid, $partText, $_htmlMode, $_preserveSeen);
- } else {
- $bodyPart = array(
- 'body' => lang("no plain text part found"),
- 'mimeType' => 'text/plain',
- 'charSet' => self::$displayCharset,
- );
- }
+ $mimePart = $_structure->getPart($mime_id);
- break;
- }
-
- return $bodyPart;
- }
-
- /**
- * getMultipartMixed
- * get part of the message, if its stucture is indicating its of multipart mixed style
- * @param string/int $_uid the messageuid,
- * @param array $_structure='', if given use structure for parsing
- * @param string $_htmlMode, how to display a message, html, plain text, ...
- * @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek
- * @return array containing the desired part
- */
- function getMultipartMixed($_uid, $_structure, $_htmlMode, $_preserveSeen = false)
- {
- if (self::$debug) echo __METHOD__."$_uid, $_htmlMode
";
- $bodyPart = array();
- if (self::$debug) _debug_array($_structure);
- if (!is_array($_structure)) $_structure = array($_structure);
- foreach($_structure as $part) {
- if (self::$debug) echo $part->type."/".$part->subType."
";
- switch($part->type) {
- case 'MULTIPART':
- switch($part->subType) {
- case 'ALTERNATIVE':
- $bodyPart[] = $this->getMultipartAlternative($_uid, $part->subParts, $_htmlMode, $_preserveSeen);
+ 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 'MIXED':
- case 'SIGNED':
- $bodyPart = array_merge($bodyPart, $this->getMultipartMixed($_uid, $part->subParts, $_htmlMode, $_preserveSeen));
- break;
-
- case 'RELATED':
- $bodyPart = array_merge($bodyPart, $this->getMultipartRelated($_uid, $part->subParts, $_htmlMode, $_preserveSeen));
+ case 'html':
+ if ($mimePart->getBytes() > 0) $partHTML = $mimePart;
break;
}
break;
- case 'TEXT':
- switch($part->subType) {
- case 'PLAIN':
- case 'HTML':
- case 'CALENDAR': // inline ics/ical files
- if($part->disposition != 'ATTACHMENT') {
+ 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
+ if (self::$debug) error_log(__METHOD__." process MULTIPART/RELATED with array as subparts");
+ $partHTML = $mimePart;
+ }
+ break;
+
+ case 'alternative':
+ if (count($mimePart->getParts()) > 1)
+ {
+ //cascading multipartAlternative structure, assuming only the first one is to be used
+// return $this->getMultipartAlternative($_uid, $mimePart, $_htmlMode, $_preserveSeen);
+ }
+ }
+ }
+ }
+
+ switch($_htmlMode)
+ {
+ case 'html_only':
+ case 'always_display':
+ if ($partHTML)
+ {
+ switch($partHTML->getSubType())
+ {
+ case 'related':
+ return $this->getMultipartRelated($_uid, $partHTML, $_htmlMode, $_preserveSeen);
+
+ case 'mixed':
+ return $this->getMultipartMixed($_uid, $partHTML, $_htmlMode, $_preserveSeen);
+
+ default:
+ return $this->getTextPart($_uid, $partHTML, $_htmlMode, $_preserveSeen);
+ }
+ }
+ elseif ($partText && $_htmlMode=='always_display')
+ {
+ return $this->getTextPart($_uid, $partText, $_htmlMode, $_preserveSeen);
+ }
+ break;
+
+ case 'only_if_no_text':
+ if ($partText)
+ {
+ return $this->getTextPart($_uid, $partText, $_htmlMode, $_preserveSeen);
+ }
+ if ($partHTML)
+ {
+ if ($partHTML->getPrimaryType())
+ {
+ return $this->getMultipartRelated($_uid, $partHTML, $_htmlMode, $_preserveSeen);
+ }
+ return $this->getTextPart($_uid, $partHTML, 'always_display', $_preserveSeen);
+ }
+ break;
+
+ default:
+ if ($partText)
+ {
+ return $this->getTextPart($_uid, $partText, $_htmlMode, $_preserveSeen);
+ }
+ $bodyPart = array(
+ 'body' => lang("no plain text part found"),
+ 'mimeType' => 'text/plain',
+ 'charSet' => self::$displayCharset,
+ );
+ break;
+ }
+ return $bodyPart;
+ }
+
+ /**
+ * Get part of the message, if its stucture is indicating its of multipart mixed style
+ *
+ * @param int $_uid the messageuid,
+ * @param Horde_Mime_Part $_structure='', if given use structure for parsing
+ * @param string $_htmlMode, how to display a message, html, plain text, ...
+ * @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek
+ * @return array containing the desired part
+ */
+ function getMultipartMixed($_uid, Horde_Mime_Part $_structure, $_htmlMode, $_preserveSeen = false)
+ {
+ if (self::$debug) echo __METHOD__."$_uid, $_htmlMode
";
+ $bodyPart = array();
+ if (self::$debug) _debug_array($_structure);
+
+ foreach($_structure->contentTypeMap() as $mime_id => $mime_type)
+ {
+ //error_log(__METHOD__."($_uid, ".$_structure->getMimeId().") $mime_id: $mime_type");
+ if (self::$debug) echo __METHOD__."($_uid, partID=".$_structure->getMimeId().") $mime_id: $mime_type
";
+
+ if (!$mime_id) continue; // ignore multipart/mixed itself
+
+ $part = $_structure->getPart($mime_id);
+
+ switch($part->getPrimaryType())
+ {
+ case 'multipart':
+ switch($part->getSubType())
+ {
+ case 'alternative':
+ $bodyPart[] = $this->getMultipartAlternative($_uid, $part, $_htmlMode, $_preserveSeen);
+ break;
+
+ case 'mixed':
+ case 'signed':
+ $bodyPart = array_merge($bodyPart, $this->getMultipartMixed($_uid, $part, $_htmlMode, $_preserveSeen));
+ break;
+
+ case 'related':
+ $bodyPart = array_merge($bodyPart, $this->getMultipartRelated($_uid, $part, $_htmlMode, $_preserveSeen));
+ break;
+ }
+ break;
+
+ case 'text':
+ switch($part->getSubType())
+ {
+ case 'plain':
+ case 'html':
+ case 'calendar': // inline ics/ical files
+ if($part->getDisposition() != 'attachment')
+ {
$bodyPart[] = $this->getTextPart($_uid, $part, $_htmlMode, $_preserveSeen);
}
//error_log(__METHOD__.__LINE__.' ->'.$part->type."/".$part->subType.' -> BodyPart:'.array2string($bodyPart[count($bodyPart)-1]));
@@ -3383,8 +3440,9 @@ $_restoreSession=false;
}
break;
- case 'MESSAGE':
- if($part->subType == 'delivery-status') {
+ case 'message':
+ if($part->getSubType() == 'delivery-status')
+ {
$bodyPart[] = $this->getTextPart($_uid, $part, $_htmlMode, $_preserveSeen);
}
break;
@@ -3392,10 +3450,6 @@ $_restoreSession=false;
default:
// do nothing
// 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
* a wrapper for multipartmixed
* @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 boolean $_preserveSeen flag to preserve the seenflag by using body.peek
* @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);
}
/**
- * getTextPart
- * get Body from message
- * @param string/int $_uid the messageuid,
- * @param array $_structure='', if given use structure for parsing
- * @param string $_htmlMode, how to display a message, html, plain text, ...
+ * Fetch a body part
+ *
+ * @param int $_uid
+ * @param string $_partID=null
+ * @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 $_stream=false true return a stream, false return string
* @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());
$bodyPart = array();
if (self::$debug) _debug_array(array($_structure,function_backtrace()));
- $partID = $_structure->partID;
- $mimePartBody = $this->icServer->getBodyPart($_uid, $partID, true, $_preserveSeen);
- if (PEAR::isError($mimePartBody))
+
+ $partID = $_structure->getMimeId();
+
+ 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(
'error' => 1,
'body' => lang("displaying html messages is disabled"),
'mimeType' => 'text/html',
'charSet' => self::$displayCharset,
);
- } elseif ($_structure->subType == 'PLAIN' && $_htmlMode == 'html_only') {
+ }
+ elseif ($_structure->getSubType() == 'plain' && $_htmlMode == 'html_only')
+ {
$bodyPart = array(
'error' => 1,
'body' => lang("displaying plain messages is disabled"),
'mimeType' => 'text/plain', // make sure we do not return mimeType text/html
'charSet' => self::$displayCharset,
);
- } else {
+ }
+ else
+ {
// 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(
- 'body' => preg_replace('/PropertyFile___$/','',$this->decodeMimePart($mimePartBody, $_structure->encoding, $this->getMimePartCharset($_structure))),
- 'mimeType' => ($_structure->type == 'TEXT' && $_structure->subType == 'HTML') ? 'text/html' : 'text/plain',
- 'charSet' => $this->getMimePartCharset($_structure),
+ 'body' => $_structure->getContents(array(
+ 'stream' => $_stream,
+ )),
+ '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' &&
is_array($_structure->parameters) && isset($_structure->parameters['FORMAT']) &&
trim(strtolower($_structure->parameters['FORMAT']))=='flowed'
@@ -3475,122 +3570,106 @@ $_restoreSession=false;
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']);
}
- if ($_structure->subType == 'CALENDAR')
+*/
+ if ($_structure->getSubType() == 'calendar')
{
- // we get an inline CALENDAR ical/ics, we display it using the calendar notification style
- $calobj = new calendar_ical;
- $calboupdate = new calendar_boupdate;
- // timezone stuff
- $tz_diff = $GLOBALS['egw_info']['user']['preferences']['common']['tz_offset'] - $this->common_prefs['tz_offset'];
- // form an event out of ical
- $event = $calobj->icaltoegw($bodyPart['body']);
- $event= $event[0];
- // preset the olddate
- $olddate = $calboupdate->format_date($event['start']+$tz_diff);
- // search egw, if we can find it
- $eventid = $calobj->find_event(array('uid'=>$event['uid']));
- if ((int)$eventid[0]>0)
- {
- // we found an event, we use the first one
- $oldevent = $calobj->read($eventid);
- // we set the olddate, to comply with the possible merge params for the notification message
- if($oldevent != False && $oldevent[$eventid[0]]['start']!=$event[$eventid[0]]['start']) {
- $olddate = $calboupdate->format_date($oldevent[$eventid[0]]['start']+$tz_diff);
- }
- // we merge the changes and the original event
- $event = array_merge($oldevent[$eventid[0]],$event);
- // 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.
- // 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'];
- }
- // we prepare the message
- $details = $calboupdate->_get_event_details($event,$action,$event_arr);
- $details['olddate']=$olddate;
- //_debug_array($_structure);
- list($subject,$info) = $calboupdate->get_update_message($event,($_structure->parameters['METHOD']=='REPLY'?false:true));
- $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
- // click on the attached ics to update his own eventstore
- $bodyPart['body'] = $subject;
- $bodyPart['body'] .= "\n".$info;
- $bodyPart['body'] .= "\n\n".lang('Event Details follow').":\n";
- foreach($event_arr as $key => $val)
- {
- if(strlen($details[$key])) {
- switch($key){
- case 'access':
- case 'priority':
- case 'link':
- break;
- default:
- $bodyPart['body'] .= sprintf("%-20s %s\n",$val['field'].':',$details[$key]);
- break;
- }
- }
- }
+ $bodyPart['body'] = $this->getEvent($_structure->getContents(), $_structure->getContentTypeParameter('METHOD'));
}
}
- //_debug_array($bodyPart);
return $bodyPart;
}
/**
- * getMessageBody
- * get Body from message
- * @param string/int $_uid the messageuid,
+ * 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
+ $calobj = new calendar_ical;
+ $calboupdate = new calendar_boupdate;
+ // timezone stuff
+ $tz_diff = $GLOBALS['egw_info']['user']['preferences']['common']['tz_offset'] - $this->common_prefs['tz_offset'];
+ // form an event out of ical
+ $events = $calobj->icaltoegw($ical);
+ $event =& $events[0];
+ // preset the olddate
+ $olddate = $calboupdate->format_date($event['start']+$tz_diff);
+ // search egw, if we can find it
+ $eventid = $calobj->find_event(array('uid'=>$event['uid']));
+ if ((int)$eventid[0]>0)
+ {
+ // we found an event, we use the first one
+ $oldevent = $calobj->read($eventid);
+ // we set the olddate, to comply with the possible merge params for the notification message
+ if($oldevent != False && $oldevent[$eventid[0]]['start']!=$event[$eventid[0]]['start']) {
+ $olddate = $calboupdate->format_date($oldevent[$eventid[0]]['start']+$tz_diff);
+ }
+ // we merge the changes and the original event
+ $event = array_merge($oldevent[$eventid[0]],$event);
+ // 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.
+ // so if it is a mere reply, we dont use the new title (more detailed info/work needed here)
+ if ($method == 'REPLY') $event['title'] = $oldevent[$eventid[0]]['title'];
+ }
+ // we prepare the message
+ $details = $calboupdate->_get_event_details($event,$action,$event_arr);
+ $details['olddate']=$olddate;
+ //_debug_array($_structure);
+ list($subject,$info) = $calboupdate->get_update_message($event, $method !='REPLY');
+ $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
+ // click on the attached ics to update his own eventstore
+ $text = $subject;
+ $text .= "\n".$info;
+ $text .= "\n\n".lang('Event Details follow').":\n";
+ foreach($event_arr as $key => $val)
+ {
+ if(strlen($details[$key])) {
+ switch($key){
+ case 'access':
+ case 'priority':
+ case 'link':
+ break;
+ default:
+ $text .= sprintf("%-20s %s\n",$val['field'].':',$details[$key]);
+ break;
+ }
+ }
+ }
+ return $text;
+ }
+
+ /**
+ * Get Body of message
+ *
+ * @param int $_uid the messageuid,
* @param string $_htmlOptions, how to display a message, html, plain text, ...
- * @param string/int $_partID='' , the partID, may be omitted
- * @param array $_structure='', if given use structure for parsing
+ * @param string $_partID=null , the partID, may be omitted
+ * @param Horde_Mime_Part $_structure=null if given use structure for parsing
* @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek
* @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
";
if($_htmlOptions != '') {
$this->htmlOptions = $_htmlOptions;
}
- if ($_folder=='')
+ if (empty($_folder))
{
$_folder = $this->sessionData['mailbox'];
}
- $uidsToFetch = new Horde_Imap_Client_Ids();
- $uidsToFetch->add((array)$_uid);
-
- $fquery = new Horde_Imap_Client_Fetch_Query();
- $fquery->fullText(array('peek'=>$_preserveSeen));
- if ($_partID != '')
+ if (!isset($_structure))
{
- $fquery->structure();
- $fquery->bodyPart($_partID,array('peek'=>$_preserveSeen));
+ $_structure = $this->getStructure($_uid, $_partID, $_folder, $_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)
{
$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);
}
}
- switch($structure->type) {
- 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
+ */
+ switch($_structure->getPrimaryType())
+ {
+ case 'application':
+ return array(
+ array(
+ 'body' => '',
+ '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,
+ 'mimeType' => $_structure->subType,
),
);
- break;
- case 'TEXT':
+
+ case 'text':
$bodyPart = array();
- if ( $structure->disposition != 'ATTACHMENT') {
- switch($structure->subType) {
- case 'CALENDAR':
+ if ($_structure->getDisposition() != 'attachment')
+ {
+ switch($_structure->getSubType())
+ {
+ case 'calendar':
// this is handeled in getTextPart
- case 'HTML':
- case 'PLAIN':
+ case 'html':
+ case 'plain':
default:
- $bodyPart = array($this->getTextPart($_uid, $structure, $this->htmlOptions, $_preserveSeen));
+ $bodyPart = array($this->getTextPart($_uid, $_structure, $this->htmlOptions, $_preserveSeen));
}
} else {
// what if the structure->disposition is attachment ,...
}
return self::normalizeBodyParts($bodyPart);
- break;
- case 'ATTACHMENT':
- case 'MESSAGE':
- switch($structure->subType) {
- case 'RFC822':
- $newStructure = array_shift($structure->subParts);
+
+ case 'attachment':
+ case 'message':
+ switch($_structure->getSubType())
+ {
+ case 'rfc822':
+ $newStructure = $_structure->getParts();
if (self::$debug) {echo __METHOD__." Message -> RFC -> NewStructure:"; _debug_array($newStructure);}
- return self::normalizeBodyParts($this->getMessageBody($_uid, $_htmlOptions, $newStructure->partID, $newStructure, $_preserveSeen, $_folder));
- break;
+ return self::normalizeBodyParts($this->getMessageBody($_uid, $_htmlOptions, $newStructure->getMimeId(), $newStructure, $_preserveSeen, $_folder));
}
break;
+
default:
- if (self::$debug) _debug_array($structure);
+ if (self::$debug) _debug_array($_structure);
return 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',
- 'charSet' => 'iso-8859-1',
+ 'charSet' => self::$displayCharset,
)
);
- break;
}
}
@@ -3662,6 +3774,9 @@ return array(
*/
static function normalizeBodyParts($_bodyParts)
{
+ // RB: dont think this is still necessary
+ return $_bodyParts;
+
if (is_array($_bodyParts))
{
foreach($_bodyParts as $singleBodyPart)
@@ -4165,57 +4280,82 @@ return array(
}
/**
- * getMessageAttachments
- * 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 string/int $_partID='' , the partID, may be omitted
- * @param array $_structure='', if given use structure for parsing
+ * Get structure of a mail or part of a mail
+ *
+ * @param int $_uid
+ * @param string $_partID=null
+ * @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 $fetchTextCalendar=false,
* @param boolean $resolveTNEF=true
* @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");
- $_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();
- $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);
- if ($part->getDisposition()=='attachment')
- {
- $headerObject['ATTACHMENTS'][$mime_id]=$part->getAllDispositionParameters();
- $headerObject['ATTACHMENTS'][$mime_id]['mimeType']=$mime_type;
- $headerObject['ATTACHMENTS'][$mime_id]['uid']=$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']) && count($headerObject['ATTACHMENTS'])) foreach ($headerObject['ATTACHMENTS'] as $pID =>$a) $attachments[]=$a;
+ if (!isset($_structure))
+ {
+ $_structure = $this->getStructure($_uid, $_partID);
+ }
+
+ foreach($_structure->contentTypeMap() as $mime_id => $mime_type)
+ {
+ $part = $_structure->getPart($mime_id);
+
+ if ($part->getDisposition() == 'attachment' ||
+ $fetchEmbeddedImages && $part->getDisposition() == 'inline' &&
+ $part->getPrimaryType() == 'image')
+ {
+ $attachment = $part->getAllDispositionParameters();
+ $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;
-
}
/**
@@ -4428,110 +4568,83 @@ error_log(__METHOD__.__LINE__.array2string($headerObject['ATTACHMENTS'][$mime_id
* @param string|int $_uid
* @param string $_cid
* @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
- static $uid,$part,$attachments,$structure;
+ static $uid=null, $part=null, $structure=null;
//error_log(__METHOD__.__LINE__.":$_uid, $_cid, $_part");
if(empty($_cid)) return false;
if ($_uid != $uid || $_part != $part)
{
- $attachments = $this->getMessageAttachments($uid=$_uid, $part=$_part);
- $structure = null;
+ $structure = $this->getStructure($uid=$_uid, $part=$_part);
}
- $partID = false;
- foreach($attachments as $attachment)
+ /** @var Horde_Mime_Part */
+ $attachment = null;
+ foreach($structure->contentTypeMap() as $mime_id => $mime_type)
{
- //error_log(print_r($attachment,true));
- if(isset($attachment['cid']) && (strpos($attachment['cid'], $_cid) !== false || strpos($_cid, $attachment['cid']) !== false))
+ $part = $structure->getPart($mime_id);
+
+ 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'];
- break;
- }
- }
- if ($partID == false)
- {
- foreach($attachments as $attachment)
- {
- // if the former did not match try matching the cid to the name of the attachment
- if(isset($attachment['cid']) && isset($attachment['name']) && (strpos($attachment['name'], $_cid) !== false || strpos($_cid, $attachment['name']) !== false))
+ // if we have a direct match, dont search any further
+ if ($cid == $_cid)
{
- $partID = $attachment['partID'];
+ $attachment = $part;
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)
- {
- // 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;
- }
- }
+ $this->fetchPartContents($_uid, $attachment, $_stream);
}
- //error_log( "Cid:$_cid PARTID:$partID
"); #exit;
-
- if($partID == false) {
- return false;
- }
-
- // parse message structure
- if (is_null($structure))
+ // set name as filename, if not set
+ if (!$attachment->getDispositionParameter('filename'))
{
- $structure = $this->_getStructure($_uid, true);
+ $attachment->setDispositionParameter('filename', $attachment->getName());
}
- $part_structure = $this->_getSubStructure($structure, $partID);
- $filename = $this->getFileNameFromStructure($part_structure, $_uid, $_uid, $part_structure->partID);
- $attachment = $this->icServer->getBodyPart($_uid, $partID, true);
- if (PEAR::isError($attachment))
+ // guess type, if not set
+ if ($attachment->getType() == 'application/octet-stream')
{
- error_log(__METHOD__.__LINE__.' failed:'.$attachment->message);
- return array('type' => 'text/plain',
- 'filename' => 'error.txt',
- 'attachment' =>__METHOD__.' failed:'.$attachment->message
- );
+ $attachment->setType(mime_magic::filename2mime($attachment->getDispositionParameter('filename')));
}
+ //error_log(__METHOD__."($_uid, '$_cid', '$_part') returning ".array2string($attachment));
+ return $attachment;
+ }
- if (PEAR::isError($attachment))
- {
- error_log(__METHOD__.__LINE__.' failed:'.$attachment->message);
- return array('type' => 'text/plain',
- 'filename' => 'error.txt',
- 'attachment' =>__METHOD__.' failed:'.$attachment->message
- );
- }
+ /**
+ * 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)
+ {
+ // we need to set content on structure to decode transfer encoding
+ $part->setContents(
+ $this->getBodyPart($_uid, $part->getMimeId(), null, $_preserveSeen, $_stream, $encoding=null),
+ array('encoding' => $encoding));
- 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;
+ return $part;
}
/**
diff --git a/mail/inc/class.mail_ui.inc.php b/mail/inc/class.mail_ui.inc.php
index 78a62cb10e..215698b806 100644
--- a/mail/inc/class.mail_ui.inc.php
+++ b/mail/inc/class.mail_ui.inc.php
@@ -1560,11 +1560,11 @@ unset($query['actions']);
}
if (!empty($uid)) $flags = $this->mail_bo->getFlags($uid);
$envelope = $this->mail_bo->getMessageEnvelope($uid, $partID,true);
-//_debug_array($headers);
+
$rawheaders = $this->mail_bo->getMessageRawHeader($uid, $partID);
$fetchEmbeddedImages = false;
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);
$attachmentHTMLBlock = self::createAttachmentBlock($attachments, $rowID, $uid, $mailbox);
$webserverURL = $GLOBALS['egw_info']['server']['webserver_url'];
@@ -1620,17 +1620,17 @@ unset($query['actions']);
foreach($envelope[$field] as $field_data)
{
//error_log(__METHOD__.__LINE__.array2string($field_data));
- $content[$field][] = $field_data['EMAIL'];
+ $content[$field][] = $field_data;//['EMAIL'];
$sel_options[$field][] = array(
// taglist requires these
- 'id' => $field_data['EMAIL'],
- 'label' => ($field_data['PERSONAL_NAME'] && $field_data['PERSONAL_NAME']!='NIL') ? $field_data['PERSONAL_NAME']:$field_data['EMAIL'],
+ 'id' => $field_data,//['EMAIL'],
+// 'label' => ($field_data['PERSONAL_NAME'] && $field_data['PERSONAL_NAME']!='NIL') ? $field_data['PERSONAL_NAME']:$field_data['EMAIL'],
// Optional
'title' => str_replace('"',"'",$field_data['RFC822_EMAIL']),
- )
+ );
// Add all other data, will be preserved & passed to js onclick
// Also available in widget.options.select_options
- + $field_data;
+ //+ $field_data;
}
}
$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);
// create some nice formated HTML for senderaddress
@@ -2031,36 +2034,37 @@ unset($query['actions']);
$cid = base64_decode($_GET['cid']);
$partID = urldecode($_GET['partID']);
if (!empty($_GET['mailbox'])) $mailbox = base64_decode($_GET['mailbox']);
+
//error_log(__METHOD__.__LINE__.":$uid, $cid, $partID");
$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();
$GLOBALS['egw']->session->commit_session();
- if(is_array($attachment)) {
- //error_log("Content-Type: ".$attachment['type']."; name=\"". $attachment['filename'] ."\"");
- header ("Content-Type: ". strtolower($attachment['type']) ."; name=\"". $attachment['filename'] ."\"");
- header ('Content-Disposition: inline; filename="'. $attachment['filename'] .'"');
+ if ($attachment)
+ {
+ header("Content-Type: ". $attachment->getType());// ."; name=\"". $attachment['filename'] ."\"");
+ header('Content-Disposition: inline; filename="'. $attachment->getDispositionParameter('filename') .'"');
header("Expires: 0");
// the next headers are for IE and SSL
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Pragma: public");
- echo trim($attachment['attachment']);
- exit;
+ echo $attachment->getContents();
}
-
- $GLOBALS['egw']->common->egw_exit();
-
- exit;
+ else
+ {
+ // send a 404 Not found
+ header("HTTP/1.1 404 Not found");
+ }
+ common::egw_exit();
}
function getAttachment()
{
-
if(isset($_GET['id'])) $rowID = $_GET['id'];
if(isset($_GET['part'])) $partID = $_GET['part'];
@@ -2303,12 +2307,13 @@ $this->uid = $uid;
$this->partID = $partID;
$bufferHtmlOptions = $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));
$meetingRequest = false;
$fetchEmbeddedImages = false;
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)
{
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
$frameHtml =
$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);
// 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
{
@@ -2674,9 +2680,10 @@ blockquote[type=cite] {
$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
- 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
{
@@ -2715,9 +2722,10 @@ blockquote[type=cite] {
$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
- 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
{