diff --git a/emailadmin/inc/class.emailadmin_imapbase.inc.php b/emailadmin/inc/class.emailadmin_imapbase.inc.php
index 025588d010..5e638e4ae1 100644
--- a/emailadmin/inc/class.emailadmin_imapbase.inc.php
+++ b/emailadmin/inc/class.emailadmin_imapbase.inc.php
@@ -5919,9 +5919,10 @@ class emailadmin_imapbase
*
* @param egw_mailer $_mailObject instance of the egw_mailer/phpmailer Object to be used
* @param string $_html2parse the html to parse and to be altered, if conditions meet
+ * @param $mail_bo mail bo object
* @return void
*/
- static function processURL2InlineImages($_mailObject, &$_html2parse)
+ static function processURL2InlineImages($_mailObject, &$_html2parse, $mail_bo)
{
//error_log(__METHOD__."()");
$imageC = 0;
@@ -5957,8 +5958,32 @@ class emailadmin_imapbase
$basedir = 'vfs://default';
$needTempFile = false;
}
+
+ // If it is an inline image url, we need to fetch the actuall attachment
+ // content and later on to be able to store its content as temp file
+ if (strpos($myUrl, '/index.php?menuaction=mail.mail_ui.displayImage') !== false)
+ {
+ $URI_params = array();
+ // Strips the url and store it into a temp for further procss
+ $tmp_url = html_entity_decode($myUrl);
+
+ parse_str(parse_url($tmp_url, PHP_URL_QUERY),$URI_params);
+ if ($URI_params['mailbox'] && $URI_params['uid'] && $URI_params['cid'])
+ {
+ $mail_bo->reopen(base64_decode($URI_params['mailbox']));
+ $attachment = $mail_bo->getAttachmentByCID($URI_params['uid'], base64_decode($URI_params['cid']),base64_decode($URI_params['partID']),true);
+ $mail_bo->closeConnection();
+ if ($attachment)
+ {
+ $data = $attachment->getContents();
+ $mimeType = $attachment->getType();
+ $filename = $attachment->getDispositionParameter('filename');
+ }
+ }
+ }
+
if ( strlen($basedir) > 1 && substr($basedir,-1) != '/' && $myUrl[0]!='/') { $basedir .= '/'; }
- if ($needTempFile) $data = file_get_contents($basedir.urldecode($myUrl));
+ if ($needTempFile && !$attachment) $data = file_get_contents($basedir.urldecode($myUrl));
}
if (substr($url,0,strlen('data:'))=='data:')
{
diff --git a/mail/inc/class.mail_compose.inc.php b/mail/inc/class.mail_compose.inc.php
index 00aa5558e9..3cb4649091 100644
--- a/mail/inc/class.mail_compose.inc.php
+++ b/mail/inc/class.mail_compose.inc.php
@@ -1625,6 +1625,7 @@ class mail_compose
#error_log( "GetDraftData (HTML) CharSet:".mb_detect_encoding($bodyParts[$i]['body'] . 'a' , strtoupper($bodyParts[$i]['charSet']).','.strtoupper($this->displayCharset).',UTF-8, ISO-8859-1'));
$this->sessionData['body'] .= ($i>0?"
":""). $bodyParts[$i]['body'] ;
}
+ $this->sessionData['body'] = mail_ui::resolve_inline_images($this->sessionData['body'], $_folder, $_uid, $_partID);
} else {
$this->sessionData['mimeType'] = 'plain';
@@ -1638,15 +1639,21 @@ class mail_compose
#error_log( "GetDraftData (Plain) CharSet".mb_detect_encoding($bodyParts[$i]['body'] . 'a' , strtoupper($bodyParts[$i]['charSet']).','.strtoupper($this->displayCharset).',UTF-8, ISO-8859-1'));
$this->sessionData['body'] .= ($i>0?"\r\n":""). $bodyParts[$i]['body'] ;
}
+ $this->sessionData['body'] = mail_ui::resolve_inline_images($this->sessionData['body'], $_folder, $_uid, $_partID,'plain');
}
-
+
if(($attachments = $mail_bo->getMessageAttachments($_uid,$_partID))) {
foreach($attachments as $attachment) {
- $this->addMessageAttachment($_uid, $attachment['partID'],
- $_folder,
- $attachment['name'],
- $attachment['mimeType'],
- $attachment['size']);
+ $cid = $attachment['cid'];
+ preg_match("/[cid:{$cid}]/", $bodyParts['0']['body'], $match);
+ if (!$match || !$attachment['cid'])
+ {
+ $this->addMessageAttachment($_uid, $attachment['partID'],
+ $_folder,
+ $attachment['name'],
+ $attachment['mimeType'],
+ $attachment['size']);
+ }
}
}
$mail_bo->closeConnection();
@@ -1706,11 +1713,14 @@ class mail_compose
if(($attachments = $mail_bo->getMessageAttachments($_uid,$_partID))) {
//error_log(__METHOD__.__LINE__.':'.array2string($attachments));
foreach($attachments as $attachment) {
- $this->addMessageAttachment($_uid, $attachment['partID'],
- $_folder,
- $attachment['name'],
- $attachment['mimeType'],
- $attachment['size']);
+ if (!($attachment['cid'] && preg_match("/image\//",$attachment['mimeType'])))
+ {
+ $this->addMessageAttachment($_uid, $attachment['partID'],
+ $_folder,
+ $attachment['name'],
+ $attachment['mimeType'],
+ $attachment['size']);
+ }
}
}
}
@@ -2081,6 +2091,7 @@ class mail_compose
}
$this->sessionData['body'] .= '
';
+ $this->sessionData['body'] = mail_ui::resolve_inline_images($this->sessionData['body'], $_folder, $_uid, $_partID, 'html');
} else {
//$this->sessionData['body'] = @htmlspecialchars(lang("on")." ".$headers['DATE']." ".$mail_bo->decode_header($fromAddress), ENT_QUOTES) . " ".lang("wrote").":\r\n";
// take care the way the ReplyHeader is created here, is used later on in uicompose::compose, in case you force replys to be HTML (prefs)
@@ -2100,7 +2111,7 @@ class mail_compose
if ($bodyParts[$i]['charSet']===false) $bodyParts[$i]['charSet'] = mail_bo::detect_encoding($bodyParts[$i]['body']);
$newBody = translation::convert($bodyParts[$i]['body'], $bodyParts[$i]['charSet']);
#error_log( "GetReplyData (Plain) CharSet:".mb_detect_encoding($bodyParts[$i]['body'] . 'a' , strtoupper($bodyParts[$i]['charSet']).','.strtoupper($this->displayCharset).',UTF-8, ISO-8859-1'));
-
+ $newBody = mail_ui::resolve_inline_images($newBody, $_folder, $_uid, $_partID, 'plain');
$this->sessionData['body'] .= "\r\n";
// create body new, with good line breaks and indention
foreach(explode("\n",$newBody) as $value) {
@@ -2284,7 +2295,7 @@ class mail_compose
$_mailObject->setBody($this->convertHTMLToText($body, true, true));
}
// convert URL Images to inline images - if possible
- if (!$_autosaving) mail_bo::processURL2InlineImages($_mailObject, $body);
+ if (!$_autosaving) mail_bo::processURL2InlineImages($_mailObject, $body, $mail_bo);
if (strpos($body,"")!==false)
{
$body = str_replace(array('',''),'',$body);
diff --git a/mail/inc/class.mail_ui.inc.php b/mail/inc/class.mail_ui.inc.php
index 427763f372..d82c5d4533 100644
--- a/mail/inc/class.mail_ui.inc.php
+++ b/mail/inc/class.mail_ui.inc.php
@@ -3004,7 +3004,7 @@ class mail_ui
// create links for inline images
if ($modifyURI)
{
- $newBody = preg_replace_callback("/\[cid:(.*)\]/iU",array($this,'image_callback_plain'),$newBody);
+ $newBody = self::resolve_inline_images($newBody, $this->mailbox, $this->uid, $this->partID, 'plain');
}
//TODO:$newBody = $this->highlightQuotes($newBody);
@@ -3055,9 +3055,7 @@ class mail_ui
// create links for inline images
if ($modifyURI)
{
- $newBody = preg_replace_callback("/src=(\"|\')cid:(.*)(\"|\')/iU",array($this,'image_callback'),$newBody);
- $newBody = preg_replace_callback("/url\(cid:(.*)\);/iU",array($this,'image_callback_url'),$newBody);
- $newBody = preg_replace_callback("/background=(\"|\')cid:(.*)(\"|\')/iU",array($this,'image_callback_background'),$newBody);
+ $newBody = self::resolve_inline_images ($newBody, $this->mailbox, $this->uid, $this->partID);
}
// email addresses / mailto links get now activated on client-side
}
@@ -3073,162 +3071,147 @@ class mail_ui
return $body;
}
-
+
/**
- * preg_replace callback to replace image cid url's
+ * Resolve inline images from CID to proper url
*
- * @param array $matches matches from preg_replace("/src=(\"|\')cid:(.*)(\"|\')/iU",...)
- * @return string src attribute to replace
+ * @param string $_body message content
+ * @param string $_mailbox mail folder
+ * @param string $_uid uid
+ * @param string $_partID part id
+ * @param string $_messageType = 'html', message type is either html or plain
+ * @return string message body including all CID images replaced
*/
- function image_callback($matches)
+ public static function resolve_inline_images ($_body,$_mailbox, $_uid, $_partID, $_messageType = 'html')
{
- static $cache = array(); // some caching, if mails containing the same image multiple times
-
- $linkData = array (
- 'menuaction' => 'mail.mail_ui.displayImage',
- 'uid' => $this->uid,
- 'mailbox' => base64_encode($this->mailbox),
- // as src:cid contains some kind of url, it is likely to be urlencoded
- 'cid' => base64_encode(trim(urldecode($matches[2]))),
- 'partID' => $this->partID,
- );
- $imageURL = egw::link('/index.php', $linkData);
-
- // to test without data uris, comment the if close incl. it's body
- if (html::$user_agent != 'msie' || html::$ua_version >= 8)
+ if ($_messageType === 'plain')
{
- if (!isset($cache[$imageURL]))
- {
- $attachment = $this->mail_bo->getAttachmentByCID($this->uid, trim(urldecode($matches[2])), $this->partID);
-
- // only use data uri for "smaller" images, as otherwise the first display of the mail takes to long
- if (($attachment instanceof Horde_Mime_Part) && $attachment->getBytes() < 8192) // msie=8 allows max 32k data uris
- {
- $this->mail_bo->fetchPartContents($this->uid, $attachment);
- $cache[$imageURL] = 'data:'.$attachment->getType().';base64,'.base64_encode($attachment->getContents());
- }
- else
- {
- $cache[$imageURL] = $imageURL;
- }
- }
- $imageURL = $cache[$imageURL];
+ return self::resolve_inline_image_byType($_body, $_mailbox, $_uid, $_partID, 'plain');
+ }
+ else
+ {
+ foreach(array('src','url','background') as $type)
+ {
+ $_body = self::resolve_inline_image_byType($_body, $_mailbox, $_uid, $_partID, $type);
+ }
+ return $_body;
}
- return 'src="'.$imageURL.'"';
}
-
+
/**
- * preg_replace callback to replace image cid url's
+ * Replace CID with proper type of content understandable by browser
*
- * @param array $matches matches from preg_replace("/src=(\"|\')cid:(.*)(\"|\')/iU",...)
- * @return string src attribute to replace
+ * @param type $_body content of message
+ * @param type $_mailbox mail box
+ * @param type $_uid uid
+ * @param type $_partID part id
+ * @param type $_type = 'src' type of inline image that needs to be resolved and replaced
+ * - types: {plain|src|url|background}
+ * @return string returns body content including all CID replacements
*/
- function image_callback_plain($matches)
+ public static function resolve_inline_image_byType ($_body,$_mailbox, $_uid, $_partID, $_type ='src')
{
- static $cache = array(); // some caching, if mails containing the same image multiple times
- //error_log(__METHOD__.__LINE__.array2string($matches));
- $linkData = array (
- 'menuaction' => 'mail.mail_ui.displayImage',
- 'uid' => $this->uid,
- 'mailbox' => base64_encode($this->mailbox),
- 'cid' => base64_encode($matches[1]),
- 'partID' => $this->partID,
- );
- $imageURL = egw::link('/index.php', $linkData);
-
- // to test without data uris, comment the if close incl. it's body
- if (html::$user_agent != 'msie' || html::$ua_version >= 8)
+ /**
+ * Callback for preg_replace_callback function
+ * returns matched CID replacement string based on given type
+ * @param array $matches
+ * @param string $_mailbox
+ * @param string $_uid
+ * @param string $_partID
+ * @param string $_type
+ * @return string|boolean returns the replace
+ */
+ $replace_callback = function ($matches) use ($_mailbox,$_uid, $_partID, $_type)
{
- if (!isset($cache[$imageURL]))
+ if (!$_type) return false;
+ $CID = '';
+ // Build up matches according to selected type
+ switch ($_type)
{
- $attachment = $this->mail_bo->getAttachmentByCID($this->uid, $matches[1], $this->partID);
+ case "plain":
+ $CID = $matches[1];
+ break;
+ case "src":
+ // as src:cid contains some kind of url, it is likely to be urlencoded
+ $CID = urldecode($matches[2]);
+ break;
+ case "url":
+ $CID = $matches[1];
+ break;
+ case "background":
+ $CID = $matches[2];
+ break;
+ }
- // only use data uri for "smaller" images, as otherwise the first display of the mail takes to long
- if (($attachment instanceof Horde_Mime_Part) && bytes($attachment->getBytes()) < 8192) // msie=8 allows max 32k data uris
+ static $cache = array(); // some caching, if mails containing the same image multiple times
+
+ if (is_array($matches) && $CID)
+ {
+ $linkData = array (
+ 'menuaction' => 'mail.mail_ui.displayImage',
+ 'uid' => $_uid,
+ 'mailbox' => base64_encode($_mailbox),
+ 'cid' => base64_encode($CID),
+ 'partID' => $_partID,
+ );
+ $imageURL = egw::link('/index.php', $linkData);
+ // to test without data uris, comment the if close incl. it's body
+ if (html::$user_agent != 'msie' || html::$ua_version >= 8)
{
- $this->mail_bo->fetchPartContents($this->uid, $attachment);
- $cache[$imageURL] = 'data:'.$attachment->getType().';base64,'.base64_encode($attachment->getContents());
+ if (!isset($cache[$imageURL]))
+ {
+ if ($_type !="background")
+ {
+ $bo = emailadmin_imapbase::getInstance(false, self::$icServerID);
+ $attachment = $bo->getAttachmentByCID($_uid, $CID, $_partID);
+
+ // only use data uri for "smaller" images, as otherwise the first display of the mail takes to long
+ if (($attachment instanceof Horde_Mime_Part) && $attachment->getBytes() < 8192) // msie=8 allows max 32k data uris
+ {
+ $bo->fetchPartContents($_uid, $attachment);
+ $cache[$imageURL] = 'data:'.$attachment->getType().';base64,'.base64_encode($attachment->getContents());
+ }
+ else
+ {
+ $cache[$imageURL] = $imageURL;
+ }
+ }
+ else
+ {
+ $cache[$imageURL] = $imageURL;
+ }
+ }
+ $imageURL = $cache[$imageURL];
}
- else
+
+ // Decides the final result of replacement according to the type
+ switch ($_type)
{
- $cache[$imageURL] = $imageURL;
+ case "plain":
+ return '';
+ case "src":
+ return 'src="'.$imageURL.'"';
+ case "url":
+ return 'url('.$imageURL.');';
+ case "background":
+ return 'background="'.$imageURL.'"';
}
}
- $imageURL = $cache[$imageURL];
- }
- return '';
- }
-
- /**
- * preg_replace callback to replace image cid url's
- *
- * @param array $matches matches from preg_replace("/src=(\"|\')cid:(.*)(\"|\')/iU",...)
- * @return string src attribute to replace
- */
- function image_callback_url($matches)
- {
- static $cache = array(); // some caching, if mails containing the same image multiple times
- //error_log(__METHOD__.__LINE__.array2string($matches));
- $linkData = array (
- 'menuaction' => 'mail.mail_ui.displayImage',
- 'uid' => $this->uid,
- 'mailbox' => base64_encode($this->mailbox),
- 'cid' => base64_encode($matches[1]),
- 'partID' => $this->partID,
- );
- $imageURL = egw::link('/index.php', $linkData);
-
- // to test without data uris, comment the if close incl. it's body
- if (html::$user_agent != 'msie' || html::$ua_version >= 8)
+ return false;
+ };
+
+ // return new body content base on chosen type
+ switch($_type)
{
- if (!isset($cache[$imageURL]))
- {
- $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 (($attachment instanceof Horde_Mime_Part) && $attachment->getBytes() < 8192) // msie=8 allows max 32k data uris
- {
- $this->mail_bo->fetchPartContents($this->uid, $attachment);
- $cache[$imageURL] = 'data:'.$attachment->getType().';base64,'.base64_encode($attachment->getContents());
- }
- else
- {
- $cache[$imageURL] = $imageURL;
- }
- }
- $imageURL = $cache[$imageURL];
+ case"plain":
+ return preg_replace_callback("/\[cid:(.*)\]/iU",$replace_callback,$_body);
+ case "src":
+ return preg_replace_callback("/src=(\"|\')cid:(.*)(\"|\')/iU",$replace_callback,$_body);
+ case "url":
+ return preg_replace_callback("/url\(cid:(.*)\);/iU",$replace_callback,$_body);
+ case "background":
+ return preg_replace_callback("/background=(\"|\')cid:(.*)(\"|\')/iU",$replace_callback,$_body);
}
- return 'url('.$imageURL.');';
- }
-
- /**
- * preg_replace callback to replace image cid url's
- *
- * @param array $matches matches from preg_replace("/src=(\"|\')cid:(.*)(\"|\')/iU",...)
- * @return string src attribute to replace
- */
- function image_callback_background($matches)
- {
- static $cache = array(); // some caching, if mails containing the same image multiple times
- $linkData = array (
- 'menuaction' => 'mail.mail_ui.displayImage',
- 'uid' => $this->uid,
- 'mailbox' => base64_encode($this->mailbox),
- 'cid' => base64_encode($matches[2]),
- 'partID' => $this->partID,
- );
- $imageURL = egw::link('/index.php', $linkData);
-
- // to test without data uris, comment the if close incl. it's body
- if (html::$user_agent != 'msie' || html::$ua_version >= 8)
- {
- if (!isset($cache[$imageURL]))
- {
- $cache[$imageURL] = $imageURL;
- }
- $imageURL = $cache[$imageURL];
- }
- return 'background="'.$imageURL.'"';
}
/**