Mail - Also include HTML version of email in integration data (for apps that can handle it)

This commit is contained in:
nathangray 2017-11-08 13:09:31 -07:00
parent aaa0d729fb
commit 7c65127e64
3 changed files with 89 additions and 15 deletions

View File

@ -6203,7 +6203,7 @@ class Mail
* @param uid the uid of the email to be processed
* @param partid the partid of the email
* @param mailbox the mailbox, that holds the message
* @param preserveHTML flag to pass through to getdisplayableBody
* @param preserveHTML flag to pass through to getdisplayableBody, null for both text and HTML
* @param addHeaderSection flag to be able to supress headersection
* @param includeAttachments flag to be able to supress possible attachments
* @return array/bool with 'mailaddress'=>$mailaddress,
@ -6219,6 +6219,15 @@ class Mail
if (empty($headers)) return false;
// dont force retrieval of the textpart, let mailClass preferences decide
$bodyParts = $mailClass->getMessageBody($uid,($preserveHTML?'always_display':'only_if_no_text'),$partid,null,false,$mailbox);
if(is_null($preserveHTML))
{
$html = static::getdisplayablebody(
$mailClass,
$mailClass->getMessageBody($uid,'always_display',$partid,null,false,$mailbox),
true
);
}
// if we do not want HTML but there is no TextRepresentation with the message itself, try converting
if ( !$preserveHTML && $bodyParts[0]['mimeType']=='text/html')
{
@ -6316,13 +6325,19 @@ class Mail
}
if (is_array($attachedMessages)) $attachments = array_merge($attachments,$attachedMessages);
}
return array(
$return = array(
'mailaddress'=>$mailaddress,
'subject'=>$subject,
'message'=>$message,
'attachments'=>$attachments,
'headers'=>$headers,
);
);
if($html)
{
$return['html_message'] = $html;
}
return $return;
}
/**

View File

@ -36,6 +36,12 @@ class mail_integration {
*/
const MAX_LINE_CHARS = 40;
/**
* Used to flag inline images so they can be found & urls fixed when in their
* final destination.
*/
const INLINE_PREFIX = 'mail-';
/**
* Gets requested mail information and sets them as data link
* -Execute registered hook method from the requested app for integration
@ -100,7 +106,7 @@ class mail_integration {
// Execute import mail with provided content
ExecMethod($hook['menuaction'],$data);
}
/**
* Gets requested mail information and sets them as data link
* -with provided content from mail:
@ -287,7 +293,7 @@ class mail_integration {
$mo = mail_bo::getInstance(true,$icServerID);
$mo->openConnection();
$mo->reopen($mailbox);
$mailcontent = mail_bo::get_mailcontent($mo,$uid,'',$mailbox,false,true,(!($GLOBALS['egw_info']['user']['preferences'][$sessionLocation]['saveAsOptions']==='text_only')));
$mailcontent = mail_bo::get_mailcontent($mo,$uid,'',$mailbox,null,true,(!($GLOBALS['egw_info']['user']['preferences'][$sessionLocation]['saveAsOptions']==='text_only')));
// this one adds the mail itself (as message/rfc822 (.eml) file) to the app as additional attachment
// this is done to have a simple archive functionality (ToDo: opening .eml in email module)
if ($GLOBALS['egw_info']['user']['preferences'][$sessionLocation]['saveAsOptions']==='add_raw')
@ -350,6 +356,26 @@ class mail_integration {
'EGroupware\\Api\\Mail::getAttachmentAccount',array($icServerID, $mailbox, $uid, $attachment['partID'], $is_winmail, true),true);
}
unset($mailcontent['attachments'][$key]['add_raw']);
// Fix inline images
if($mailcontent['html_message'] && $attachment['cid'] && $data_attachments[$key]['egw_data'])
{
$link_callback = function($cid) use($data_attachments, $key)
{
return self::INLINE_PREFIX.$data_attachments[$key]['egw_data'].'" title="['.$data_attachments[$key]['name'].']';
};
foreach(array('src','url','background') as $type)
{
$mailcontent['html_message'] = mail_ui::resolve_inline_image_byType(
$mailcontent['html_message'],
$mailbox,
$attachment['uid'],
$attachment['partID'],
$type,
$link_callback
);
}
}
}
}
@ -357,10 +383,30 @@ class mail_integration {
'addresses' => $data_addresses,
'attachments' => $data_attachments,
'message' => $data_message,
'html_message' => $mailcontent['html_message'],
'date' => $mailcontent['date'],
'subject' => $mailcontent['subject'],
'entry_id' => $app_entry_id
);
}
public static function fix_inline_images($app, $id, array $links, &$html)
{
$replace = array();
foreach($links as $link)
{
$matches = null;
if (is_array($link) && $link['id']['egw_data'] && strpos($html, self::INLINE_PREFIX . $link['id']['egw_data']) !== false)
{
$replace[self::INLINE_PREFIX. $link['id']['egw_data']] =
Api\Egw::link(Api\Vfs::download_url(Api\Link::vfs_path($app, $id, Api\Vfs::basename($link['id']['name']))));
}
}
if ($replace)
{
$html = strtr($old = $html, $replace);
}
return isset($old) && $old != $html;
}
}

View File

@ -3477,10 +3477,30 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
* @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}
* @param callback $_link_callback Function to generate the link to the image. If
* not provided, a default (using mail) will be used.
* @return string returns body content including all CID replacements
*/
public static function resolve_inline_image_byType ($_body,$_mailbox, $_uid, $_partID, $_type ='src')
public static function resolve_inline_image_byType ($_body,$_mailbox, $_uid, $_partID, $_type ='src', callable $_link_callback = null)
{
/**
* Callback to generate the link
*/
if(is_null($_link_callback))
{
$_link_callback = function($_cid) use ($_mailbox, $_uid, $_partID)
{
$linkData = array (
'menuaction' => 'mail.mail_ui.displayImage',
'uid' => $_uid,
'mailbox' => base64_encode($_mailbox),
'cid' => base64_encode($CID),
'partID' => $_partID,
);
return Egw::link('/index.php', $linkData);
};
}
/**
* Callback for preg_replace_callback function
* returns matched CID replacement string based on given type
@ -3491,7 +3511,7 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
* @param string $_type
* @return string|boolean returns the replace
*/
$replace_callback = function ($matches) use ($_mailbox,$_uid, $_partID, $_type)
$replace_callback = function ($matches) use ($_mailbox,$_uid, $_partID, $_type, $_link_callback)
{
if (!$_type) return false;
$CID = '';
@ -3517,14 +3537,7 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
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);
$imageURL = call_user_func($_link_callback, $CID);
// to test without data uris, comment the if close incl. it's body
if (Api\Header\UserAgent::type() != 'msie' || Api\Header\UserAgent::version() >= 8)
{