* Mail: Implement mail integration with new structure and add new feature

- Add mail to calendar as calendar entry, including all mail attachments as links
- Add user choice for saving mail into an existing ticket or a new ticket
- Fix mail attachments integration into infolog, tracker or calendar entry
This commit is contained in:
Hadi Nategh 2015-05-05 08:03:13 +00:00
commit 50782cfa8b
19 changed files with 840 additions and 576 deletions

View File

@ -856,6 +856,19 @@ END:VALARM';
unset($data); // not used, but in function signature for hooks
return true;
}
/**
* Mail integration hook to import mail message contents into a calendar entry
*
* @return string method to be executed for calendar mail integration
*/
public static function mail_import($args)
{
return array (
'menuaction' => 'calendar.calendar_uiforms.mail_import',
'popup' => egw_link::get_registry('calendar', 'edit_popup')
);
}
}
// Not part of the class, since config hooks are still using the old style

View File

@ -32,6 +32,7 @@ class calendar_uiforms extends calendar_ui
'import' => true,
'cat_acl' => true,
'meeting' => true,
'mail_import' => true,
);
/**
@ -1317,13 +1318,12 @@ class calendar_uiforms extends calendar_ui
$event['whole_day'] = !$start['hour'] && !$start['minute'] && $end['hour'] == 23 && $end['minute'] == 59;
$link_to_id = $event['id'];
if (!$add_link && !$event['id'] && isset($_REQUEST['link_app']) && isset($_REQUEST['link_id']))
if (!$event['id'] && isset($_REQUEST['link_app']) && isset($_REQUEST['link_id']))
{
$link_ids = is_array($_REQUEST['link_id']) ? $_REQUEST['link_id'] : array($_REQUEST['link_id']);
foreach(is_array($_REQUEST['link_app']) ? $_REQUEST['link_app'] : array($_REQUEST['link_app']) as $n => $link_app)
{
$link_id = $link_ids[$n];
$app_entry = array();
if(!preg_match('/^[a-z_0-9-]+:[:a-z_0-9-]+$/i',$link_app.':'.$link_id)) // guard against XSS
{
continue;
@ -1866,7 +1866,7 @@ class calendar_uiforms extends calendar_ui
$event['ics_method_label'] = strtolower($ical_method) == 'request' ?
lang('Meeting request') : lang('Reply to meeting request');
$tpl = new etemplate_new('calendar.meeting');
$tpl->exec('calendar.calendar_uiforms.meeting', $event, $sel_options, $readonlys, $event, 2);
$tpl->exec('calendar.calendar_uiforms.meeting', $event, array(), $readonlys, $event, 2);
}
/**
@ -2058,7 +2058,7 @@ class calendar_uiforms extends calendar_ui
{
if (!$content['duration']) $content['duration'] = $content['end'] - $content['start'];
$weekds = 0;
foreach ($content['weekdays'] as $keys =>$wdays)
foreach ($content['weekdays'] as &$wdays)
{
$weekds = $weekds + $wdays;
}
@ -2288,8 +2288,6 @@ class calendar_uiforms extends calendar_ui
}
if (!is_array($content))
{
$view = $GLOBALS['egw']->session->appsession('view','calendar');
$content = array(
'start' => $this->bo->date2ts($_REQUEST['start'] ? $_REQUEST['start'] : $this->date),
'end' => $this->bo->date2ts($_REQUEST['end'] ? $_REQUEST['end'] : $this->date),
@ -2562,4 +2560,100 @@ class calendar_uiforms extends calendar_ui
}
}
}
/**
* imports a mail as Calendar
*
* @param array $mailContent = null mail content
* @return array
*/
function mail_import(array $mailContent=null)
{
// It would get called from compose as a popup with egw_data
if (!is_array($mailContent) && ($_GET['egw_data']))
{
// get raw mail data
egw_link::get_data ($_GET['egw_data']);
return false;
}
if (is_array($mailContent))
{
// Addressbook
$AB = new addressbook_bo();
$accounts = array(0 => $GLOBALS['egw_info']['user']['account_id']);
$participants[0] = array (
'uid' => $GLOBALS['egw_info']['user']['account_id'],
'delete_id' => $GLOBALS['egw_info']['user']['account_id'],
'status' => 'A',
'old_status' => 'A',
'app' => 'User',
'role' => 'REQ-PARTICIPANT'
);
foreach($mailContent['addresses'] as $address)
{
// Get available contacts from the email
$contacts = $AB->search(array(
'email' => $address['email'],
'email_home' => $address['email']
),'contact_id,contact_email,contact_email_home,egw_addressbook.account_id as account_id','','','',false,'OR',false,array('owner' => 0),'',false);
if (is_array($contacts))
{
foreach($contacts as $account)
{
$accounts[] = $account['account_id'];
}
}
else
{
$participants []= array (
'app' => 'email',
'uid' => 'e'.$address['email'],
'status' => 'U',
'old_status' => 'U'
);
}
}
$participants = array_merge($participants , array(
"account" => $accounts,
"role" => "REQ-PARTICIPANT",
"add" => "pressed"
));
// Prepare calendar event draft
$event = array(
'title' => $mailContent['subject'],
'description' => $mailContent['message'],
'participants' => $participants,
'link_to' => array(
'to_app' => 'calendar',
'to_id' => 0,
),
'start' => $mailContent['date'],
'duration' => 60 * $this->cal_prefs['interval']
);
if (is_array($mailContent['attachments']))
{
foreach ($mailContent['attachments'] as $attachment)
{
if($attachment['egw_data'])
{
egw_link::link('calendar',$event['link_to']['to_id'],egw_link::DATA_APPNAME, $attachment);
}
else if(is_readable($attachment['tmp_name']))
{
egw_link::link('calendar',$event['link_to']['to_id'],'file', $attachment);
}
}
}
}
else
{
egw_framework::window_close(lang('No content found to show up as calendar entry.'));
}
return $this->process_edit($event);
}
}

View File

@ -46,6 +46,7 @@ $setup_info['calendar']['hooks']['infolog_set'] = 'calendar.calendar_bo.infolog_
$setup_info['calendar']['hooks']['export_limit'] = 'calendar_hooks::getAppExportLimit';
$setup_info['calendar']['hooks']['acl_rights'] = 'calendar_hooks::acl_rights';
$setup_info['calendar']['hooks']['categories'] = 'calendar_hooks::categories';
$setup_info['calendar']['hooks']['mail_import'] = 'calendar_hooks::mail_import';
/* Dependencies for this app to work */
$setup_info['calendar']['depends'][] = array(

View File

@ -290,7 +290,7 @@ class emailadmin_imapbase
{
try
{
$mailbox = $_icServerObject->getCurrentMailbox();
$_icServerObject->getCurrentMailbox();
}
catch (Exception $e)
{
@ -445,7 +445,7 @@ class emailadmin_imapbase
function restoreSessionData()
{
$this->sessionData = array();//egw_cache::getCache(egw_cache::SESSION,'mail','session_data',$callback=null,$callback_params=array(),$expiration=60*60*1);
self::$activeFolderCache = egw_cache::getCache(egw_cache::INSTANCE,'email','activeMailbox'.trim($GLOBALS['egw_info']['user']['account_id']),$callback=null,$callback_params=array(),$expiration=60*60*10);
self::$activeFolderCache = egw_cache::getCache(egw_cache::INSTANCE,'email','activeMailbox'.trim($GLOBALS['egw_info']['user']['account_id']),null,array(),60*60*10);
if (!empty(self::$activeFolderCache[$this->profileID])) $this->sessionData['mailbox'] = self::$activeFolderCache[$this->profileID];
}
@ -458,7 +458,7 @@ class emailadmin_imapbase
if (!empty($this->sessionData['mailbox'])) self::$activeFolderCache[$this->profileID]=$this->sessionData['mailbox'];
if (isset(self::$activeFolderCache) && is_array(self::$activeFolderCache))
{
egw_cache::setCache(egw_cache::INSTANCE,'email','activeMailbox'.trim($GLOBALS['egw_info']['user']['account_id']),self::$activeFolderCache, $expiration=60*60*10);
egw_cache::setCache(egw_cache::INSTANCE,'email','activeMailbox'.trim($GLOBALS['egw_info']['user']['account_id']),self::$activeFolderCache, 60*60*10);
}
}
@ -522,10 +522,10 @@ class emailadmin_imapbase
$_profileID = null;
self::resetConnectionErrorCache($_profileID,$account_id);
self::resetFolderObjectCache($_profileID,$account_id);
egw_cache::setCache(egw_cache::INSTANCE,'email','rawHeadersCache'.trim($account_id),array(), $expiration=60*60*1);
egw_cache::setCache(egw_cache::INSTANCE,'email','HierarchyDelimiter'.trim($account_id),array(), $expiration=60*60*24*5);
egw_cache::setCache(egw_cache::INSTANCE,'email','eMailListContainsDeletedMessages'.trim($account_id),array(), $expiration=60*60*1);
egw_cache::setCache(egw_cache::INSTANCE,'email','vacationNotice'.trim($account_id),array(), $expiration=60*60*24*1);
egw_cache::setCache(egw_cache::INSTANCE,'email','rawHeadersCache'.trim($account_id),array(), 60*60*1);
egw_cache::setCache(egw_cache::INSTANCE,'email','HierarchyDelimiter'.trim($account_id),array(), 60*60*24*5);
egw_cache::setCache(egw_cache::INSTANCE,'email','eMailListContainsDeletedMessages'.trim($account_id),array(), 60*60*1);
egw_cache::setCache(egw_cache::INSTANCE,'email','vacationNotice'.trim($account_id),array(), 60*60*24*1);
}
}
}
@ -549,7 +549,6 @@ class emailadmin_imapbase
}
if (is_null($_ImapServerId))
{
$buff = array();
$isConError = array();
$waitOnFailure = array();
}
@ -560,14 +559,14 @@ class emailadmin_imapbase
{
unset($isConError[$_ImapServerId]);
}
$waitOnFailure = egw_cache::getCache(egw_cache::INSTANCE,'email','ActiveSyncWaitOnFailure'.trim($account_id),$callback=null,$callback_params=array(),$expiration=60*60*2);
$waitOnFailure = egw_cache::getCache(egw_cache::INSTANCE,'email','ActiveSyncWaitOnFailure'.trim($account_id),null,array(),60*60*2);
if (isset($waitOnFailure[$_ImapServerId]))
{
unset($waitOnFailure[$_ImapServerId]);
}
}
egw_cache::setCache(egw_cache::INSTANCE,'email','icServerSIEVE_connectionError'.trim($account_id),$isConError,$expiration=60*15);
egw_cache::setCache(egw_cache::INSTANCE,'email','ActiveSyncWaitOnFailure'.trim($account_id),$waitOnFailure,$expiration=60*60*2);
egw_cache::setCache(egw_cache::INSTANCE,'email','icServerSIEVE_connectionError'.trim($account_id),$isConError,60*15);
egw_cache::setCache(egw_cache::INSTANCE,'email','ActiveSyncWaitOnFailure'.trim($account_id),$waitOnFailure,60*60*2);
}
/**
@ -591,12 +590,12 @@ class emailadmin_imapbase
}
else
{
$folders2return = egw_cache::getCache(egw_cache::INSTANCE,'email','folderObjects'.trim($account_id),$callback=null,$callback_params=array(),$expiration=60*60*1);
$folders2return = egw_cache::getCache(egw_cache::INSTANCE,'email','folderObjects'.trim($account_id),null,array(),60*60*1);
if (!empty($folders2return) && isset($folders2return[$_ImapServerId]))
{
unset($folders2return[$_ImapServerId]);
}
$folderInfo = egw_cache::getCache(egw_cache::INSTANCE,'email','icServerFolderExistsInfo'.trim($account_id),null,array(),$expiration=60*60*5);
$folderInfo = egw_cache::getCache(egw_cache::INSTANCE,'email','icServerFolderExistsInfo'.trim($account_id),null,array(),60*60*5);
if (!empty($folderInfo) && isset($folderInfo[$_ImapServerId]))
{
unset($folderInfo[$_ImapServerId]);
@ -608,23 +607,23 @@ class emailadmin_imapbase
unset($lastFolderUsedForMove[$_ImapServerId]);
}
*/
$folderBasicInfo = egw_cache::getCache(egw_cache::INSTANCE,'email','folderBasicInfo'.trim($account_id),null,array(),$expiration=60*60*1);
$folderBasicInfo = egw_cache::getCache(egw_cache::INSTANCE,'email','folderBasicInfo'.trim($account_id),null,array(),60*60*1);
if (!empty($folderBasicInfo) && isset($folderBasicInfo[$_ImapServerId]))
{
unset($folderBasicInfo[$_ImapServerId]);
}
$_specialUseFolders = egw_cache::getCache(egw_cache::INSTANCE,'email','specialUseFolders'.trim($account_id),null,array(),$expiration=60*60*12);
$_specialUseFolders = egw_cache::getCache(egw_cache::INSTANCE,'email','specialUseFolders'.trim($account_id),null,array(),60*60*12);
if (!empty($_specialUseFolders) && isset($_specialUseFolders[$_ImapServerId]))
{
unset($_specialUseFolders[$_ImapServerId]);
self::$specialUseFolders=null;
}
}
egw_cache::setCache(egw_cache::INSTANCE,'email','folderObjects'.trim($account_id),$folders2return, $expiration=60*60*1);
egw_cache::setCache(egw_cache::INSTANCE,'email','icServerFolderExistsInfo'.trim($account_id),$folderInfo,$expiration=60*60*5);
egw_cache::setCache(egw_cache::INSTANCE,'email','folderObjects'.trim($account_id),$folders2return, 60*60*1);
egw_cache::setCache(egw_cache::INSTANCE,'email','icServerFolderExistsInfo'.trim($account_id),$folderInfo,60*60*5);
//egw_cache::setCache(egw_cache::INSTANCE,'email','lastFolderUsedForMove'.trim($account_id),$lastFolderUsedForMove,$expiration=60*60*1);
egw_cache::setCache(egw_cache::INSTANCE,'email','folderBasicInfo'.trim($account_id),$folderBasicInfo,$expiration=60*60*1);
egw_cache::setCache(egw_cache::INSTANCE,'email','specialUseFolders'.trim($account_id),$_specialUseFolders,$expiration=60*60*12);
egw_cache::setCache(egw_cache::INSTANCE,'email','folderBasicInfo'.trim($account_id),$folderBasicInfo,60*60*1);
egw_cache::setCache(egw_cache::INSTANCE,'email','specialUseFolders'.trim($account_id),$_specialUseFolders,60*60*12);
}
/**
@ -663,7 +662,7 @@ class emailadmin_imapbase
/**
* getAllIdentities - function to gather the identities connected to the current user
* @param string/int $_accountToSearch; null; if set search accounts for user specified
* @param string/int $_accountToSearch = null if set search accounts for user specified
* @param boolean $resolve_placeholders wether or not resolve possible placeholders in identities
* @return array - array(email=>realname)
*/
@ -726,7 +725,7 @@ class emailadmin_imapbase
*/
function getDefaultIdentity() {
// retrieve the signature accociated with the identity
$id = $this->getIdentitiesWithAccounts($_accountData);
$id = $this->getIdentitiesWithAccounts($_accountData=array());
$acc = emailadmin_account::read($this->profileID);
$accountDataIT = ($_accountData[$this->profileID]?$acc->identities($this->profileID,false,'ident_id'):$acc->identities($_accountData[$id],false,'ident_id'));
foreach($accountDataIT as $it => $accountData)
@ -745,7 +744,7 @@ class emailadmin_imapbase
{
// account select box
$selectedID = $this->profileID;
$allAccountData = emailadmin_account::search($only_current_user=true, $just_name=false, $order_by=null);
$allAccountData = emailadmin_account::search($only_current_user=true, false, null);
if ($allAccountData) {
$rememberFirst=$selectedFound=null;
foreach ($allAccountData as $tmpkey => $icServers)
@ -808,7 +807,7 @@ class emailadmin_imapbase
/**
* reopens a connection for the active Server ($this->icServer), and selects the folder given
*
* @param string $_foldername, folder to open/select
* @param string $_foldername folder to open/select
* @return void
*/
function reopen($_foldername)
@ -835,8 +834,8 @@ class emailadmin_imapbase
/**
* openConnection
*
* @param int $_icServerID
* @param boolean $_adminConnection
* @param int $_icServerID = 0
* @param boolean $_adminConnection = false
* @throws Horde_Imap_Client_Exception on connection error or authentication failure
* @throws InvalidArgumentException on missing credentials
*/
@ -939,7 +938,6 @@ class emailadmin_imapbase
{
foreach ($singleNameSpaceArray as $k => $singleNameSpace)
{
$prefix_present = false;
$_foldersNameSpace = array();
if($type == 'personal' && $singleNameSpace['name'] == '#mh/' && ($this->folderExists('Mail')||$this->folderExists('INBOX')))
{
@ -975,7 +973,7 @@ class emailadmin_imapbase
*/
function getFolderPrefixFromNamespace($nameSpace, $folderName)
{
foreach($nameSpace as $k => $singleNameSpace)
foreach($nameSpace as &$singleNameSpace)
{
//if (substr($singleNameSpace['prefix'],0,strlen($folderName))==$folderName) return $singleNameSpace['prefix'];
if (substr($folderName,0,strlen($singleNameSpace['prefix']))==$singleNameSpace['prefix']) return $singleNameSpace['prefix'];
@ -991,7 +989,7 @@ class emailadmin_imapbase
function getHierarchyDelimiter($_useCache=true)
{
static $HierarchyDelimiter;
if (is_null($HierarchyDelimiter)) $HierarchyDelimiter = egw_cache::getCache(egw_cache::INSTANCE,'email','HierarchyDelimiter'.trim($GLOBALS['egw_info']['user']['account_id']),$callback=null,$callback_params=array(),$expiration=60*60*24*5);
if (is_null($HierarchyDelimiter)) $HierarchyDelimiter = egw_cache::getCache(egw_cache::INSTANCE,'email','HierarchyDelimiter'.trim($GLOBALS['egw_info']['user']['account_id']),null,array(),60*60*24*5);
if ($_useCache===false) unset($HierarchyDelimiter[$this->icServer->ImapServerId]);
if (isset($HierarchyDelimiter[$this->icServer->ImapServerId])&&!empty($HierarchyDelimiter[$this->icServer->ImapServerId]))
{
@ -1007,7 +1005,7 @@ class emailadmin_imapbase
{
$HierarchyDelimiter[$this->icServer->ImapServerId] = '/';
}
egw_cache::setCache(egw_cache::INSTANCE,'email','HierarchyDelimiter'.trim($GLOBALS['egw_info']['user']['account_id']),$HierarchyDelimiter, $expiration=60*60*24*5);
egw_cache::setCache(egw_cache::INSTANCE,'email','HierarchyDelimiter'.trim($GLOBALS['egw_info']['user']['account_id']),$HierarchyDelimiter, 60*60*24*5);
return $HierarchyDelimiter[$this->icServer->ImapServerId];
}
@ -1020,7 +1018,7 @@ class emailadmin_imapbase
{
//error_log(__METHOD__.' ('.__LINE__.') '.':'.$this->icServer->ImapServerId.' Connected:'.$this->icServer->_connected);
static $_specialUseFolders;
if (is_null($_specialUseFolders)||empty($_specialUseFolders)) $_specialUseFolders = egw_cache::getCache(egw_cache::INSTANCE,'email','specialUseFolders'.trim($GLOBALS['egw_info']['user']['account_id']),$callback=null,$callback_params=array(),$expiration=60*60*24*5);
if (is_null($_specialUseFolders)||empty($_specialUseFolders)) $_specialUseFolders = egw_cache::getCache(egw_cache::INSTANCE,'email','specialUseFolders'.trim($GLOBALS['egw_info']['user']['account_id']),null,array(),60*60*24*5);
//error_log(__METHOD__.' ('.__LINE__.') '.array2string($this->icServer->acc_folder_trash));
//error_log(__METHOD__.' ('.__LINE__.') '.array2string($this->icServer->acc_folder_sent));
//error_log(__METHOD__.' ('.__LINE__.') '.array2string($this->icServer->acc_folder_draft));
@ -1040,7 +1038,7 @@ class emailadmin_imapbase
$_specialUseFolders[$this->icServer->ImapServerId][$this->icServer->acc_folder_junk]='Junk';
//error_log(__METHOD__.' ('.__LINE__.') '.array2string($_specialUseFolders));//.'<->'.array2string($this->icServer));
self::$specialUseFolders = $_specialUseFolders[$this->icServer->ImapServerId];
egw_cache::setCache(egw_cache::INSTANCE,'email','specialUseFolders'.trim($GLOBALS['egw_info']['user']['account_id']),$_specialUseFolders, $expiration=60*60*24*5);
egw_cache::setCache(egw_cache::INSTANCE,'email','specialUseFolders'.trim($GLOBALS['egw_info']['user']['account_id']),$_specialUseFolders, 60*60*24*5);
return $_specialUseFolders[$this->icServer->ImapServerId];
}
@ -1210,7 +1208,7 @@ class emailadmin_imapbase
if (!empty($nameSpace[$this->profileID]))
{
$nsNoPersonal=array();
foreach($nameSpace[$this->profileID] as $k => $ns)
foreach($nameSpace[$this->profileID] as &$ns)
{
if ($ns['type']!='personal') $nsNoPersonal[]=$ns;
}
@ -1249,7 +1247,7 @@ class emailadmin_imapbase
// we filter for the combined status of unseen and undeleted, as this is what we show in list
try
{
$sortResult = $this->getSortedList($_folderName, $_sort=0, $_reverse=1, $_filter=array('status'=>array('UNSEEN','UNDELETED')),$byUid=true,false);
$sortResult = $this->getSortedList($_folderName, $_sort=0, 1, array('status'=>array('UNSEEN','UNDELETED')),true,false);
$retValue['unseen'] = $sortResult['count'];
}
catch (Exception $ee)
@ -1300,8 +1298,8 @@ class emailadmin_imapbase
{
// this will not work we must calculate the range we want to retieve as e.g.: 0:20 retirieves the first 20 mails and sorts them
// if sort capability is applied to the range fetched, not sort first and fetch the range afterwards
$start = $_startMessage-1;
$end = $_startMessage-1+$_numberOfMessages;
//$start = $_startMessage-1;
//$end = $_startMessage-1+$_numberOfMessages;
//$_filter['range'] ="$start:$end";
//$_filter['range'] ="$_startMessage:*";
}
@ -1376,7 +1374,7 @@ class emailadmin_imapbase
$sortResult = (is_array($_thisUIDOnly) ? $_thisUIDOnly:(array)$_thisUIDOnly);
}
//$queryString = implode(',', $sortResult);
// fetch the data for the selected messages
if (self::$debug||self::$debugTimes) $starttime = microtime(true);
try
@ -1414,7 +1412,11 @@ class emailadmin_imapbase
if (self::$debug||self::$debugTimes)
{
self::logRunTimes($starttime,null,'HordeFetch: for Folder:'.$_folderName.' Filter:'.array2string($_filter),__METHOD__.' ('.__LINE__.') ');
if (self::$debug) error_log(__METHOD__.' ('.__LINE__.') '.' Query:'.$queryString.' Result:'.array2string($headersNew));
if (self::$debug)
{
$queryString = implode(',', $sortResult);
error_log(__METHOD__.' ('.__LINE__.') '.' Query:'.$queryString.' Result:'.array2string($headersNew));
}
}
$count = 0;
@ -1506,7 +1508,7 @@ class emailadmin_imapbase
if ($mime_type=='message/rfc822')
{
//error_log(__METHOD__.' ('.__LINE__.') '.' Uid:'.$uid.'->'.$mime_id.':'.array2string($part->contentTypeMap()));
foreach($part->contentTypeMap() as $sub_id => $sub_type) if ($sub_id != $mime_id) $skipParts[$sub_id] = $sub_type;
foreach($part->contentTypeMap() as $sub_id => $sub_type) { if ($sub_id != $mime_id) $skipParts[$sub_id] = $sub_type;}
}
//error_log(__METHOD__.' ('.__LINE__.') '.' Uid:'.$uid.'->'.$mime_id.' Disp:'.$partdisposition.' Type:'.$partPrimaryType.' Skip:'.array2string($skipParts));
if (array_key_exists($mime_id,$skipParts)) continue;
@ -1543,7 +1545,7 @@ class emailadmin_imapbase
if (!isset($attachment['name'])||empty($attachment['name'])) $attachment['name'] = $part->getName();
$attachment['size'] = $part->getBytes();
if (($cid = $part->getContentId())) $attachment['cid'] = $cid;
if (empty($attachment['name'])) $attachment['name'] = (isset($attachment['cid'])&&!empty($attachment['cid'])?$attachment['cid']:lang("unknown").'_Uid'.$_uid.'_Part'.$mime_id).'.'.mime_magic::mime2ext($attachment['mimeType']);
if (empty($attachment['name'])) $attachment['name'] = (isset($attachment['cid'])&&!empty($attachment['cid'])?$attachment['cid']:lang("unknown").'_Uid'.$attachment['uid'].'_Part'.$mime_id).'.'.mime_magic::mime2ext($attachment['mimeType']);
$headerObject['ATTACHMENTS'][$mime_id.'.'.$vmime_id] = $attachment;
}
if ($tnefResolved) unset($headerObject['ATTACHMENTS'][$mime_id]);
@ -1568,7 +1570,7 @@ class emailadmin_imapbase
}
//error_log(__METHOD__.' ('.__LINE__.') '.' '.$headerObject['SUBJECT'].'->'.$headerObject['DATE']);
//error_log(__METHOD__.' ('.__LINE__.') '.' '.$this->decode_subject($headerObject['SUBJECT']).'->'.$headerObject['DATE']);
if (isset($headerObject['ATTACHMENTS']) && count($headerObject['ATTACHMENTS'])) foreach ($headerObject['ATTACHMENTS'] as $pID =>$a) $retValue['header'][$sortOrder[$uid]]['attachments'][]=$a;
if (isset($headerObject['ATTACHMENTS']) && count($headerObject['ATTACHMENTS'])) foreach ($headerObject['ATTACHMENTS'] as &$a) { $retValue['header'][$sortOrder[$uid]]['attachments'][]=$a;}
$retValue['header'][$sortOrder[$uid]]['subject'] = $this->decode_subject($headerObject['SUBJECT']);
$retValue['header'][$sortOrder[$uid]]['size'] = $headerObject['SIZE'];
$retValue['header'][$sortOrder[$uid]]['date'] = self::_strtotime(($headerObject['DATE']&&!($headerObject['DATE']=='NIL')?$headerObject['DATE']:$headerObject['INTERNALDATE']),'ts',true);
@ -1703,23 +1705,23 @@ class emailadmin_imapbase
//error_log(__METHOD__.' ('.__LINE__.') '.' Filter:'.array2string($_filter));
$try2useCache = true;
static $eMailListContainsDeletedMessages;
if (is_null($eMailListContainsDeletedMessages)) $eMailListContainsDeletedMessages = egw_cache::getCache(egw_cache::INSTANCE,'email','eMailListContainsDeletedMessages'.trim($GLOBALS['egw_info']['user']['account_id']),$callback=null,$callback_params=array(),$expiration=60*60*1);
if (is_null($eMailListContainsDeletedMessages)) $eMailListContainsDeletedMessages = egw_cache::getCache(egw_cache::INSTANCE,'email','eMailListContainsDeletedMessages'.trim($GLOBALS['egw_info']['user']['account_id']),null,array(),60*60*1);
// this indicates, that there is no Filter set, and the returned set/subset should not contain DELETED Messages, nor filtered for UNDELETED
if ($setSession==true && ((strpos(array2string($_filter), 'UNDELETED') === false && strpos(array2string($_filter), 'DELETED') === false)))
{
if (self::$debugTimes) $starttime = microtime(true);
if (is_null($eMailListContainsDeletedMessages) || empty($eMailListContainsDeletedMessages[$this->profileID]) || empty($eMailListContainsDeletedMessages[$this->profileID][$_folderName])) $eMailListContainsDeletedMessages = egw_cache::getCache(egw_cache::INSTANCE,'email','eMailListContainsDeletedMessages'.trim($GLOBALS['egw_info']['user']['account_id']),$callback=null,$callback_params=array(),$expiration=60*60*1);
if (is_null($eMailListContainsDeletedMessages) || empty($eMailListContainsDeletedMessages[$this->profileID]) || empty($eMailListContainsDeletedMessages[$this->profileID][$_folderName])) $eMailListContainsDeletedMessages = egw_cache::getCache(egw_cache::INSTANCE,'email','eMailListContainsDeletedMessages'.trim($GLOBALS['egw_info']['user']['account_id']),null,array(),60*60*1);
$deletedMessages = $this->getSortedList($_folderName, 0, $three=1, array('status'=>array('DELETED')),$five=true,false);
if (self::$debug) error_log(__METHOD__.' ('.__LINE__.') Found DeletedMessages:'.array2string($sortResult['match']->ids));
if (self::$debug) error_log(__METHOD__.' ('.__LINE__.') Found DeletedMessages:'.array2string($eMailListContainsDeletedMessages));
$eMailListContainsDeletedMessages[$this->profileID][$_folderName] =$deletedMessages['count'];
egw_cache::setCache(egw_cache::INSTANCE,'email','eMailListContainsDeletedMessages'.trim($GLOBALS['egw_info']['user']['account_id']),$eMailListContainsDeletedMessages, $expiration=60*60*1);
egw_cache::setCache(egw_cache::INSTANCE,'email','eMailListContainsDeletedMessages'.trim($GLOBALS['egw_info']['user']['account_id']),$eMailListContainsDeletedMessages, 60*60*1);
if (self::$debugTimes) self::logRunTimes($starttime,null,'setting eMailListContainsDeletedMessages for Profile:'.$this->profileID.' Folder:'.$_folderName.' to '.$eMailListContainsDeletedMessages[$this->profileID][$_folderName],__METHOD__.' ('.__LINE__.') '); //error_log(__METHOD__.' ('.__LINE__.') '.' Profile:'.$this->profileID.' Folder:'.$_folderName.' -> EXISTS/SessStat:'.array2string($folderStatus['MESSAGES']).'/'.self::$folderStatusCache[$this->profileID][$_folderName]['messages'].' ListContDelMsg/SessDeleted:'.$eMailListContainsDeletedMessages[$this->profileID][$_folderName].'/'.self::$folderStatusCache[$this->profileID][$_folderName]['deleted']);
}
$try2useCache = false;
//self::$supportsORinQuery[$this->profileID]=true;
if (is_null(self::$supportsORinQuery) || !isset(self::$supportsORinQuery[$this->profileID]))
{
self::$supportsORinQuery = egw_cache::getCache(egw_cache::INSTANCE,'email','supportsORinQuery'.trim($GLOBALS['egw_info']['user']['account_id']),$callback=null,$callback_params=array(),$expiration=60*60*10);
self::$supportsORinQuery = egw_cache::getCache(egw_cache::INSTANCE,'email','supportsORinQuery'.trim($GLOBALS['egw_info']['user']['account_id']),null,array(),60*60*10);
if (!isset(self::$supportsORinQuery[$this->profileID])) self::$supportsORinQuery[$this->profileID]=true;
}
//error_log(__METHOD__.' ('.__LINE__.') '.array2string($_filter).' SupportsOrInQuery:'.self::$supportsORinQuery[$this->profileID]);
@ -1777,7 +1779,7 @@ class emailadmin_imapbase
//error_log(__METHOD__.'('.__LINE__.'):'.$e->getMessage());
// possible error OR Query. But Horde gives no detailed Info :-(
self::$supportsORinQuery[$this->profileID]=false;
egw_cache::setCache(egw_cache::INSTANCE,'email','supportsORinQuery'.trim($GLOBALS['egw_info']['user']['account_id']),self::$supportsORinQuery,$expiration=60*60*10);
egw_cache::setCache(egw_cache::INSTANCE,'email','supportsORinQuery'.trim($GLOBALS['egw_info']['user']['account_id']),self::$supportsORinQuery,60*60*10);
if (self::$debug) error_log(__METHOD__.__LINE__." Mailserver seems to have NO OR Capability for Search:".$sortResult->message);
$filter = $this->createIMAPFilter($_folderName, $_filter, self::$supportsORinQuery[$this->profileID]);
try
@ -1889,7 +1891,7 @@ class emailadmin_imapbase
$imapFilter->charset('UTF-8');
//_debug_array($_criterias);
if (self::$debug) error_log(__METHOD__.' ('.__LINE__.') '.' Criterias:'.(!is_array($_criterias)?" none -> returning $all":array2string($_criterias)));
if (self::$debug) error_log(__METHOD__.' ('.__LINE__.') '.' Criterias:'.(!is_array($_criterias)?" none -> returning":array2string($_criterias)));
if((!is_array($_criterias) || $_criterias['status']=='any') && (!isset($_criterias['string']) || empty($_criterias['string']))) {
$imapFilter->flag('DELETED', $set=false);
return $imapFilter;
@ -2222,7 +2224,7 @@ class emailadmin_imapbase
{
$opts['special_use'] = self::$specialUseFolders[$newFolderName];
}
$rv = $this->icServer->createMailbox($newFolderName, $opts);
$this->icServer->createMailbox($newFolderName, $opts);
}
catch (Exception $e)
{
@ -2232,7 +2234,7 @@ class emailadmin_imapbase
}
try
{
$srv = $this->icServer->subscribeMailbox($newFolderName);
$this->icServer->subscribeMailbox($newFolderName);
}
catch (Exception $e)
{
@ -2267,14 +2269,14 @@ class emailadmin_imapbase
if (self::$debug) error_log("create folder: $newFolderName");
try
{
$rv = $this->icServer->renameMailbox($oldFolderName, $newFolderName);
$this->icServer->renameMailbox($oldFolderName, $newFolderName);
}
catch (Exception $e)
{
throw new egw_exception(__METHOD__." failed for $oldFolderName (rename to: $newFolderName) with error:".$e->getMessage());;
}
// clear FolderExistsInfoCache
egw_cache::setCache(egw_cache::INSTANCE,'email','icServerFolderExistsInfo'.trim($GLOBALS['egw_info']['user']['account_id']),$folderInfo,$expiration=60*60*5);
egw_cache::setCache(egw_cache::INSTANCE,'email','icServerFolderExistsInfo'.trim($GLOBALS['egw_info']['user']['account_id']),$folderInfo,60*60*5);
return $newFolderName;
@ -2297,10 +2299,10 @@ class emailadmin_imapbase
}
catch (Exception $e)
{
throw new egw_exception("Deleting Folder $_foldername failed! Error:".$e->getMessage());;
throw new egw_exception("Deleting Folder $_folderName failed! Error:".$e->getMessage());;
}
// clear FolderExistsInfoCache
egw_cache::setCache(egw_cache::INSTANCE,'email','icServerFolderExistsInfo'.trim($GLOBALS['egw_info']['user']['account_id']),$folderInfo,$expiration=60*60*5);
egw_cache::setCache(egw_cache::INSTANCE,'email','icServerFolderExistsInfo'.trim($GLOBALS['egw_info']['user']['account_id']),$folderInfo,60*60*5);
return true;
}
@ -2352,7 +2354,7 @@ class emailadmin_imapbase
if ($_subscribedOnly && $_getCounters===false)
{
if (is_null($folders2return)) $folders2return = egw_cache::getCache(egw_cache::INSTANCE,'email','folderObjects'.trim($GLOBALS['egw_info']['user']['account_id']),$callback=null,$callback_params=array(),$expiration=60*60*1);
if (is_null($folders2return)) $folders2return = egw_cache::getCache(egw_cache::INSTANCE,'email','folderObjects'.trim($GLOBALS['egw_info']['user']['account_id']),null,array(),60*60*1);
if ($_useCacheIfPossible && isset($folders2return[$this->icServer->ImapServerId]) && !empty($folders2return[$this->icServer->ImapServerId]))
{
//error_log(__METHOD__.' ('.__LINE__.') '.' using Cached folderObjects'.array2string($folders2return[$this->icServer->ImapServerId]));
@ -2362,9 +2364,8 @@ class emailadmin_imapbase
}
// use $folderBasicInfo for holding attributes and other basic folderinfo $folderBasicInfo[$this->icServer->ImapServerId]
static $folderBasicInfo;
if (is_null($folderBasicInfo)||!isset($folderBasicInfo[$this->icServer->ImapServerId])) $folderBasicInfo = egw_cache::getCache(egw_cache::INSTANCE,'email','folderBasicInfo'.trim($GLOBALS['egw_info']['user']['account_id']),null,array(),$expiration=60*60*1);
if (is_null($folderBasicInfo)||!isset($folderBasicInfo[$this->icServer->ImapServerId])) $folderBasicInfo = egw_cache::getCache(egw_cache::INSTANCE,'email','folderBasicInfo'.trim($GLOBALS['egw_info']['user']['account_id']),null,array(),60*60*1);
//error_log(__METHOD__.' ('.__LINE__.') '.array2string(array_keys($folderBasicInfo[$this->icServer->ImapServerId])));
$isUWIMAP = false;
$delimiter = $this->getHierarchyDelimiter();
@ -2391,6 +2392,7 @@ class emailadmin_imapbase
//$nameSpace = $this->icServer->getNameSpaces();
$nameSpace = $this->_getNameSpaces();
$fetchedAllInOneGo = false;
$subscribedFoldersForCache = $foldersNameSpace = array();
//error_log(__METHOD__.__LINE__.array2string($nameSpace));
if (is_array($nameSpace))
{
@ -2653,7 +2655,7 @@ class emailadmin_imapbase
$rv = false;
foreach ($haystack as $k => $v)
{
foreach($v as $sk => $sv) if (trim($sv)==trim($needle)) return $k;
foreach($v as &$sv) {if (trim($sv)==trim($needle)) return $k;}
}
return $rv;
}
@ -2663,7 +2665,7 @@ class emailadmin_imapbase
*
* Helper function to sort folder-objects by displayname
* @param object $a
* @param object $b, array of folderobjects
* @param object $b array of folderobjects
* @return int expect values (0, 1 or -1)
*/
function sortByDisplayName($a,$b)
@ -2677,7 +2679,7 @@ class emailadmin_imapbase
*
* Helper function to sort folder-objects by auto Folder Position
* @param object $a
* @param object $b, array of folderobjects
* @param object $b array of folderobjects
* @return int expect values (0, 1 or -1)
*/
function sortByAutoFolderPos($a,$b)
@ -2754,7 +2756,7 @@ class emailadmin_imapbase
if (is_array($mbx[$mbxkeys[0]]["ATTRIBUTES"]) && (in_array('\HasChildren',$mbx[$mbxkeys[0]]["ATTRIBUTES"]) || in_array('\Haschildren',$mbx[$mbxkeys[0]]["ATTRIBUTES"]) || in_array('\haschildren',$mbx[$mbxkeys[0]]["ATTRIBUTES"]))) {
// if there are children fetch them
//echo $mbx[$mbxkeys[0]]['MAILBOX']."<br>";
unset($buff);
$buff = $this->icServer->getMailboxes($mbx[$mbxkeys[0]]['MAILBOX'].($mbx[$mbxkeys[0]]['MAILBOX'] == $prefix ? '':$delimiter),2,false);
//$buff = $this->icServer->getMailboxes($mbx[$mbxkeys[0]]['MAILBOX'],2,false);
//_debug_array($buff);
@ -2778,8 +2780,8 @@ class emailadmin_imapbase
/**
* _getSpecialUseFolder
* abstraction layer for getDraftFolder, getTemplateFolder, getTrashFolder and getSentFolder
* @param string $type the type to fetch (Drafts|Template|Trash|Sent)
* @param boolean $_checkexistance, trigger check for existance
* @param string $_type the type to fetch (Drafts|Template|Trash|Sent)
* @param boolean $_checkexistance trigger check for existance
* @param boolean& $created =null on return true: if folder was just created, false if not
* @return mixed string or false
*/
@ -2870,7 +2872,7 @@ class emailadmin_imapbase
/**
* getDraftFolder wrapper for _getSpecialUseFolder Type Drafts
* @param boolean $_checkexistance, trigger check for existance
* @param boolean $_checkexistance trigger check for existance
* @return mixed string or false
*/
function getJunkFolder($_checkexistance=TRUE)
@ -2880,7 +2882,7 @@ class emailadmin_imapbase
/**
* getDraftFolder wrapper for _getSpecialUseFolder Type Drafts
* @param boolean $_checkexistance, trigger check for existance
* @param boolean $_checkexistance trigger check for existance
* @return mixed string or false
*/
function getDraftFolder($_checkexistance=TRUE)
@ -2890,7 +2892,7 @@ class emailadmin_imapbase
/**
* getTemplateFolder wrapper for _getSpecialUseFolder Type Template
* @param boolean $_checkexistance, trigger check for existance
* @param boolean $_checkexistance trigger check for existance
* @return mixed string or false
*/
function getTemplateFolder($_checkexistance=TRUE)
@ -2900,7 +2902,7 @@ class emailadmin_imapbase
/**
* getTrashFolder wrapper for _getSpecialUseFolder Type Trash
* @param boolean $_checkexistance, trigger check for existance
* @param boolean $_checkexistance trigger check for existance
* @return mixed string or false
*/
function getTrashFolder($_checkexistance=TRUE)
@ -2910,7 +2912,7 @@ class emailadmin_imapbase
/**
* getSentFolder wrapper for _getSpecialUseFolder Type Sent
* @param boolean $_checkexistance, trigger check for existance
* @param boolean $_checkexistance trigger check for existance
* @return mixed string or false
*/
function getSentFolder($_checkexistance=TRUE)
@ -2920,7 +2922,7 @@ class emailadmin_imapbase
/**
* getOutboxFolder wrapper for _getSpecialUseFolder Type Outbox
* @param boolean $_checkexistance, trigger check for existance
* @param boolean $_checkexistance trigger check for existance
* @return mixed string or false
*/
function getOutboxFolder($_checkexistance=TRUE)
@ -2930,8 +2932,8 @@ class emailadmin_imapbase
/**
* isSentFolder is the given folder the sent folder or at least a subfolder of it
* @param string $_foldername, folder to perform the check on
* @param boolean $_checkexistance, trigger check for existance
* @param string $_folderName folder to perform the check on
* @param boolean $_checkexistance trigger check for existance
* @return boolean
*/
function isSentFolder($_folderName, $_checkexistance=TRUE)
@ -2954,8 +2956,8 @@ class emailadmin_imapbase
/**
* checks if the Outbox folder exists and is part of the foldername to be checked
* @param string $_foldername, folder to perform the check on
* @param boolean $_checkexistance, trigger check for existance
* @param string $_folderName folder to perform the check on
* @param boolean $_checkexistance trigger check for existance
* @return boolean
*/
function isOutbox($_folderName, $_checkexistance=TRUE)
@ -2977,8 +2979,8 @@ class emailadmin_imapbase
/**
* isDraftFolder is the given folder the sent folder or at least a subfolder of it
* @param string $_foldername, folder to perform the check on
* @param boolean $_checkexistance, trigger check for existance
* @param string $_folderName folder to perform the check on
* @param boolean $_checkexistance trigger check for existance
* @return boolean
*/
function isDraftFolder($_folderName, $_checkexistance=TRUE)
@ -3001,8 +3003,8 @@ class emailadmin_imapbase
/**
* isTrashFolder is the given folder the sent folder or at least a subfolder of it
* @param string $_foldername, folder to perform the check on
* @param boolean $_checkexistance, trigger check for existance
* @param string $_folderName folder to perform the check on
* @param boolean $_checkexistance trigger check for existance
* @return boolean
*/
function isTrashFolder($_folderName, $_checkexistance=TRUE)
@ -3025,8 +3027,8 @@ class emailadmin_imapbase
/**
* isTemplateFolder is the given folder the sent folder or at least a subfolder of it
* @param string $_foldername, folder to perform the check on
* @param boolean $_checkexistance, trigger check for existance
* @param string $_folderName folder to perform the check on
* @param boolean $_checkexistance trigger check for existance
* @return boolean
*/
function isTemplateFolder($_folderName, $_checkexistance=TRUE)
@ -3049,8 +3051,8 @@ class emailadmin_imapbase
/**
* folderExists checks for existance of a given folder
* @param string $_foldername, folder to perform the check on
* @param boolean $_forceCheck, trigger check for existance on icServer
* @param string $_folder folder to perform the check on
* @param boolean $_forceCheck trigger check for existance on icServer
* @return mixed string or false
*/
function folderExists($_folder, $_forceCheck=false)
@ -3145,7 +3147,6 @@ class emailadmin_imapbase
function deleteMessages($_messageUID, $_folder=NULL, $_forceDeleteMethod='no')
{
//error_log(__METHOD__.' ('.__LINE__.') '.'->'.array2string($_messageUID).','.array2string($_folder).', '.$_forceDeleteMethod);
$msglist = '';
$oldMailbox = '';
if (is_null($_folder) || empty($_folder)) $_folder = $this->sessionData['mailbox'];
if (empty($_messageUID))
@ -3183,13 +3184,13 @@ class emailadmin_imapbase
case "move_to_trash":
//error_log(__METHOD__.' ('.__LINE__.') ');
$updateCache = true;
if(!empty($trashFolder)); {
if(!empty($trashFolder)) {
if (self::$debug) error_log(__METHOD__.' ('.__LINE__.') '.implode(' : ', $_messageUID));
if (self::$debug) error_log(__METHOD__.' ('.__LINE__.') '."$trashFolder <= $_folder / ". $this->sessionData['mailbox']);
// copy messages
try
{
$retValue = $this->icServer->copy($_folder, $trashFolder, array('ids'=>$uidsToDelete,'move'=>true));
$this->icServer->copy($_folder, $trashFolder, array('ids'=>$uidsToDelete,'move'=>true));
}
catch (Exception $e)
{
@ -3347,7 +3348,7 @@ class emailadmin_imapbase
}
try
{
foreach($messageUIDs as $k => $uids)
foreach($messageUIDs as &$uids)
{
if ($uids==='all')
{
@ -3468,9 +3469,8 @@ class emailadmin_imapbase
*/
function moveMessages($_foldername, $_messageUID, $deleteAfterMove=true, $currentFolder = Null, $returnUIDs = false, $_sourceProfileID = Null, $_targetProfileID = Null)
{
$msglist = '';
$source = emailadmin_account::read(($_sourceProfileID?$_sourceProfileID:$this->icServer->ImapServerId))->imapServer();
$deleteOptions = $GLOBALS['egw_info']["user"]["preferences"]["mail"]["deleteOptions"];
//$deleteOptions = $GLOBALS['egw_info']["user"]["preferences"]["mail"]["deleteOptions"];
if (empty($_messageUID))
{
if (self::$debug) error_log(__METHOD__." no Message(s): ".implode(',',$_messageUID));
@ -3512,7 +3512,7 @@ class emailadmin_imapbase
$retUid = new Horde_Imap_Client_Ids();
// we copy chunks of 5 to avoid too much memory and/or server stress
// some servers seem not to allow/support the appendig of multiple messages. so we are down to one
foreach($headersNew as $id=>$_headerObject) {
foreach($headersNew as &$_headerObject) {
$c++;
$flags = $_headerObject->getFlags(); //unseen status seems to be lost when retrieving the full message
$date = $_headerObject->getImapDate();
@ -3578,7 +3578,6 @@ class emailadmin_imapbase
{
error_log(__METHOD__.' ('.__LINE__.') '."Copying to Folder $_foldername failed! Error:".$e->getMessage());
throw new egw_exception("Copying to Folder $_foldername failed! Error:".$e->getMessage());
return false;
}
}
@ -3763,11 +3762,11 @@ class emailadmin_imapbase
case 'BASE64':
// use imap_base64 to decode, not any longer, as it is strict, and fails if it encounters invalid chars
return base64_decode($_mimeMessage);
break;
case 'QUOTED-PRINTABLE':
// use imap_qprint to decode
return quoted_printable_decode($_mimeMessage);
break;
case 'WEDONTKNOWTHEENCODING':
// try base64
$r = base64_decode($_mimeMessage);
@ -3779,7 +3778,6 @@ class emailadmin_imapbase
default:
// it is either not encoded or we don't know about it
return $_mimeMessage;
break;
}
}
@ -3789,7 +3787,7 @@ class emailadmin_imapbase
* a wrapper for multipartmixed
* @param string/int $_uid the messageuid,
* @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
* @return array containing the desired part
*/
@ -3919,8 +3917,8 @@ class emailadmin_imapbase
* 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 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
*/
@ -4014,7 +4012,7 @@ class emailadmin_imapbase
if($part->getSubType() == 'rfc822' || $part->getDisposition() == 'attachment')
{
$skipParts[$mime_id.'.0'] = $mime_type;
foreach($part->contentTypeMap() as $sub_id => $sub_type) $skipParts[$sub_id] = $sub_type;
foreach($part->contentTypeMap() as $sub_id => $sub_type){ $skipParts[$sub_id] = $sub_type;}
//error_log(__METHOD__.' ('.__LINE__.') '.' Uid:'.$_uid.' Part:'.$mime_id.':'.array2string($skipParts));
//break 2;
}
@ -4033,8 +4031,8 @@ class emailadmin_imapbase
* 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 Horde_Mime_Part $_structure, if given use structure for parsing
* @param string $_htmlMode, how to display a message, html, plain text, ...
* @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
*/
@ -4105,7 +4103,7 @@ class emailadmin_imapbase
* Get Body from message
*
* @param int $_uid the messageuid
* @param Horde_Mime_Part $_structure=null, if given use structure for parsing
* @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
@ -4203,7 +4201,7 @@ class emailadmin_imapbase
if ($method == 'REPLY') $event['title'] = $oldevent[$eventid[0]]['title'];
}
// we prepare the message
$details = $calboupdate->_get_event_details($event,$action,$event_arr);
$details = $calboupdate->_get_event_details($event,'',$event_arr=array());
$details['olddate']=$olddate;
//_debug_array($_structure);
list($subject,$info) = $calboupdate->get_update_message($event, $method !='REPLY');
@ -4235,8 +4233,8 @@ class emailadmin_imapbase
* Get Body of message
*
* @param int $_uid the messageuid,
* @param string $_htmlOptions, how to display a message, html, plain text, ...
* @param string $_partID=null , the partID, may be omitted
* @param string $_htmlOptions how to display a message, html, plain text, ...
* @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
* @param string $_folder folder to work on
@ -4377,7 +4375,7 @@ class emailadmin_imapbase
{
if (!isset($singleBodyPart['body'])) {
$buff = self::normalizeBodyParts($singleBodyPart);
foreach ((array)$buff as $val) $body2return[] = $val;
foreach ((array)$buff as $val) { $body2return[] = $val;}
continue;
}
$body2return[] = $singleBodyPart;
@ -4475,7 +4473,7 @@ class emailadmin_imapbase
if (!$preserveHTML)
{
// filter only the 'body', as we only want that part, if we throw away the html
preg_match('`(<htm.+?<body[^>]*>)(.+?)(</body>.*?</html>)`ims', $newBody, $matches);
preg_match('`(<htm.+?<body[^>]*>)(.+?)(</body>.*?</html>)`ims', $newBody, $matches=array());
if ($matches[2])
{
$hasOther = true;
@ -4486,7 +4484,7 @@ class emailadmin_imapbase
else
{
// htmLawed filter only the 'body'
preg_match('`(<htm.+?<body[^>]*>)(.+?)(</body>.*?</html>)`ims', $newBody, $matches);
preg_match('`(<htm.+?<body[^>]*>)(.+?)(</body>.*?</html>)`ims', $newBody, $matches=array());
if ($matches[2])
{
$hasOther = true;
@ -4500,7 +4498,7 @@ class emailadmin_imapbase
if ($hasOther && $preserveHTML) $newBody = $matches[1]. $newBody. $matches[3];
}
//error_log(__METHOD__.' ('.__LINE__.') '.' after purify:'.$newBody);
if ($preserveHTML==false) $newBody = translation::convertHTMLToText($newBody,self::$displayCharset,true,$stripalltags=true);
if ($preserveHTML==false) $newBody = translation::convertHTMLToText($newBody,self::$displayCharset,true,true);
//error_log(__METHOD__.' ('.__LINE__.') '.' after convertHTMLToText:'.$newBody);
if ($preserveHTML==false) $newBody = nl2br($newBody); // we need this, as htmLawed removes \r\n
$mailClass->getCleanHTML($newBody,false,$preserveHTML); // remove stuff we regard as unwanted
@ -4542,7 +4540,7 @@ class emailadmin_imapbase
$s=explode(" ", $line);
$line = "";
$linecnt = 0;
foreach ($s as $k=>$v) {
foreach ($s as &$v) {
$cnt = strlen($v);
// only break long words within the wordboundaries,
// but it may destroy links, so we check for href and dont do it if we find one
@ -4594,10 +4592,11 @@ class emailadmin_imapbase
'ids' => $uidsToFetch,
));
if (is_object($headersNew)) {
foreach($headersNew as $id=>$_headerObject) {
foreach($headersNew as &$_headerObject) {
$env = $_headerObject->getEnvelope();
//_debug_array($envFields->singleFields());
foreach ($envFields->singleFields() as $e => $v)
$singleFields = $envFields->singleFields();
foreach ($singleFields as &$v)
{
switch ($v)
{
@ -4768,7 +4767,7 @@ class emailadmin_imapbase
if (empty($_folder)) $_folder = ($this->sessionData['mailbox']? $this->sessionData['mailbox'] : $this->icServer->getCurrentMailbox());
//error_log(__METHOD__.' ('.__LINE__.') '." Try Using Cache for raw Header $_uid, $_partID in Folder $_folder");
if (is_null($rawHeaders)||!is_array($rawHeaders)) $rawHeaders = egw_cache::getCache(egw_cache::INSTANCE,'email','rawHeadersCache'.trim($GLOBALS['egw_info']['user']['account_id']),$callback=null,$callback_params=array(),$expiration=60*60*1);
if (is_null($rawHeaders)||!is_array($rawHeaders)) $rawHeaders = egw_cache::getCache(egw_cache::INSTANCE,'email','rawHeadersCache'.trim($GLOBALS['egw_info']['user']['account_id']),null,array(),60*60*1);
if (isset($rawHeaders[$this->icServer->ImapServerId][(string)$_folder][$_uid][(empty($_partID)?'NIL':$_partID)]))
{
//error_log(__METHOD__.' ('.__LINE__.') '." Using Cache for raw Header $_uid, $_partID in Folder $_folder");
@ -4793,7 +4792,7 @@ class emailadmin_imapbase
'ids' => $uidsToFetch,
));
if (is_object($headersNew)) {
foreach($headersNew as $id=>$_headerObject) {
foreach($headersNew as &$_headerObject) {
$retValue = $_headerObject->getHeaderText();
if ($_partID != '')
{
@ -4809,13 +4808,13 @@ class emailadmin_imapbase
}
}
$rawHeaders[$this->icServer->ImapServerId][(string)$_folder][$_uid][(empty($_partID)?'NIL':$_partID)]=$retValue;
egw_cache::setCache(egw_cache::INSTANCE,'email','rawHeadersCache'.trim($GLOBALS['egw_info']['user']['account_id']),$rawHeaders,$expiration=60*60*1);
egw_cache::setCache(egw_cache::INSTANCE,'email','rawHeadersCache'.trim($GLOBALS['egw_info']['user']['account_id']),$rawHeaders,60*60*1);
return $retValue;
}
/**
* getStyles - extracts the styles from the given bodyparts
* @param array $bodyParts with the bodyparts
* @param array $_bodyParts with the bodyparts
* @return string a preformatted string with the mails converted to text
*/
static function &getStyles($_bodyParts)
@ -4836,7 +4835,7 @@ class emailadmin_imapbase
);
$ct = 0;
if (stripos($singleBodyPart['body'],'<style')!==false) $ct = preg_match_all('#<style(?:\s.*)?>(.+)</style>#isU', $singleBodyPart['body'], $newStyle);
if (stripos($singleBodyPart['body'],'<style')!==false) $ct = preg_match_all('#<style(?:\s.*)?>(.+)</style>#isU', $singleBodyPart['body'], $newStyle=array());
if ($ct>0)
{
//error_log(__METHOD__.' ('.__LINE__.') '.array2string($newStyle[0]));
@ -4913,7 +4912,7 @@ class emailadmin_imapbase
'ids' => $uidsToFetch,
));
if (is_object($headersNew)) {
foreach($headersNew as $id=>$_headerObject) {
foreach($headersNew as &$_headerObject) {
$body = $_headerObject->getFullMsg();
if ($_partID != '')
{
@ -5019,7 +5018,7 @@ class emailadmin_imapbase
if ($mime_type=='message/rfc822' && $_partID!=$mime_id)
{
//error_log(__METHOD__.' ('.__LINE__.') '.' Uid:'.$uid.'->'.$mime_id.':'.array2string($part->contentTypeMap()));
foreach($part->contentTypeMap() as $sub_id => $sub_type) if ($sub_id != $mime_id) $skipParts[$sub_id] = $sub_type;
foreach($part->contentTypeMap() as $sub_id => $sub_type) {if ($sub_id != $mime_id) $skipParts[$sub_id] = $sub_type;}
}
if (empty($partDisposition) && $partPrimaryType != 'multipart' && $partPrimaryType != 'text')
{
@ -5444,7 +5443,7 @@ class emailadmin_imapbase
//$messageid = true; // for debug reasons only
if ($messageid === true || empty($messageid)) // try to figure out the message uid
{
$list = $this->getHeaders($_folderName, $_startMessage=1, $_numberOfMessages=1, $_sort='INTERNALDATE', $_reverse=true, $_filter=array(),$_thisUIDOnly=null, $_cacheResult=false);
$list = $this->getHeaders($_folderName, $_startMessage=1, 1, 'INTERNALDATE', true, array(),null, false);
if ($list)
{
if (self::$debug) error_log(__METHOD__.' ('.__LINE__.') '.' MessageUid:'.$messageid.' but found:'.array2string($list));
@ -5546,7 +5545,7 @@ class emailadmin_imapbase
fwrite($tmpfile,$headdata.$mailcontent['message']);
fclose($tmpfile);
}
foreach($mailcontent['attachments'] as $tmpattach => $tmpval)
foreach($mailcontent['attachments'] as &$tmpval)
{
$attachedMessages[] = $tmpval;
}
@ -5657,7 +5656,7 @@ class emailadmin_imapbase
* @param array $rfcAddressArray an addressarray as provided by mail retieved via egw_pear....
* @return string a comma separated string with the mailaddress(es) converted to text
*/
static function convertAddressArrayToString($rfcAddressArray, $createHTML = false)
static function convertAddressArrayToString($rfcAddressArray)
{
//error_log(__METHOD__.' ('.__LINE__.') '.array2string($rfcAddressArray));
$returnAddr ='';
@ -5714,11 +5713,10 @@ class emailadmin_imapbase
*/
function merge($content,$ids,$mimetype='')
{
$contacts = new addressbook_bo();
$mergeobj = new addressbook_merge();
if (empty($mimetype)) $mimetype = (strlen(strip_tags($content)) == strlen($content) ?'text/plain':'text/html');
$rv = $mergeobj->merge_string($content,$ids,$err,$mimetype, array(), self::$displayCharset);
$rv = $mergeobj->merge_string($content,$ids,$err='',$mimetype, array(), self::$displayCharset);
if (empty($rv) && !empty($content) && !empty($err)) $rv = $content;
if (!empty($err) && !empty($content) && !empty($ids)) error_log(__METHOD__.' ('.__LINE__.') '.' Merge failed for Ids:'.array2string($ids).' ContentType:'.$mimetype.' Content:'.$content.' Reason:'.array2string($err));
return $rv;
@ -6312,7 +6310,7 @@ class emailadmin_imapbase
$matches = array();
preg_match_all("/[\w\.,-.,_.,0-9.]+@[\w\.,-.,_.,0-9.]+/",$addresses,$matches);
//error_log(__METHOD__.__LINE__.array2string($matches));
foreach ($matches[0] as &$match) $match = trim($match,', ');
foreach ($matches[0] as &$match) {$match = trim($match,', ');}
$addresses = implode(',',$matches[0]);
//error_log(__METHOD__.__LINE__.array2string($addresses));
$ret = $rfc822->parseAddressList($addresses, $default_domain ? array('default_domain' => $default_domain) : array());
@ -6359,22 +6357,8 @@ class emailadmin_imapbase
*/
function addAccount($_hookValues)
{
error_log(__METHOD__.' ('.__LINE__.') '.' NOT DONE JET!');
//$_profile_id=????
//$icServer = emailadmin_account::read($_profile_id)->imapServer();
//$ogServer = emailadmin_account::read($_profile_id)->smtpServer();
error_log(__METHOD__.' ('.__LINE__.') '.' NOT DONE YET!' . ' hookValue = '. $_hookValues);
/*
if(($icServer instanceof defaultimap)) {
// if not connected, try opening an admin connection
if (!$icServer->_connected) $this->openConnection($this->profileID,true);
$icServer->addAccount($_hookValues);
if ($icServer->_connected) $this->closeConnection(); // close connection afterwards
}
if(($ogServer instanceof emailadmin_smtp)) {
$ogServer->addAccount($_hookValues);
}
*/
}
/**
@ -6387,22 +6371,8 @@ class emailadmin_imapbase
*/
function deleteAccount($_hookValues)
{
error_log(__METHOD__.' ('.__LINE__.') '.' NOT DONE JET!');
//$_profile_id=????
//$icServer = emailadmin_account::read($_profile_id)->imapServer();
//$ogServer = emailadmin_account::read($_profile_id)->smtpServer();
/*
if(($icServer instanceof defaultimap)) {
//try to connect with admin rights, when not connected
if (!$icServer->_connected) $this->openConnection($this->profileID,true);
$icServer->deleteAccount($_hookValues);
if ($icServer->_connected) $this->closeConnection(); // close connection
}
error_log(__METHOD__.' ('.__LINE__.') '.' NOT DONE YET!' . ' hookValue = '. $_hookValues);
if(($ogServer instanceof emailadmin_smtp)) {
$ogServer->deleteAccount($_hookValues);
}
*/
}
/**
@ -6415,18 +6385,7 @@ class emailadmin_imapbase
*/
function updateAccount($_hookValues)
{
error_log(__METHOD__.' ('.__LINE__.') '.' NOT DONE JET!');
//$_profile_id=????
//$icServer = emailadmin_account::read($_profile_id)->imapServer();
//$ogServer = emailadmin_account::read($_profile_id)->smtpServer();
/*
if(($icServer instanceof defaultimap)) {
$icServer->updateAccount($_hookValues);
}
error_log(__METHOD__.' ('.__LINE__.') '.' NOT DONE YET!' . ' hookValue = '. $_hookValues);
if(($ogServer instanceof emailadmin_smtp)) {
$ogServer->updateAccount($_hookValues);
}
*/
}
}

View File

@ -1672,7 +1672,7 @@ var et2_link_list = et2_link_string.extend(
link.dom_id = 'temp_'+egw.uid();
}
// Icon should be in registry
if(typeof link.icon == 'undefined')
if(!link.icon)
{
link.icon = egw.link_get_registry(link.app,'icon');
// No icon, try by mime type - different place for un-saved entries
@ -1684,7 +1684,7 @@ var et2_link_list = et2_link_string.extend(
}
}
// Special handling for file - if not existing, we can't ask for title
if(link.app == 'file' && typeof link.title == 'undefined')
if(typeof link.id =='object' && !link.title)
{
link.title = link.id.name || '';
}

View File

@ -1131,33 +1131,29 @@ class infolog_bo
*
* @author Cornelius Weiss <nelius@cwtech.de>
* @todo search if infolog with from and subject allready exists ->appned body & inform user
* @param string $_email_address rfc822 conform emailaddresses
* @param array $_addresses array of addresses
* - array (email,name)
* @param string $_subject
* @param string $_message
* @param array $_attachments
* @param string $_date
* @return array $content array for uiinfolog
*/
function import_mail($_email_address,$_subject,$_message,$_attachments,$_date)
function import_mail($_addresses,$_subject,$_message,$_attachments,$_date)
{
$address_array = imap_rfc822_parse_adrlist($_email_address,'');
foreach ((array)$address_array as $address)
foreach($_addresses as $address)
{
$email[] = $emailadr = sprintf('%s@%s',
trim($address->mailbox),
trim($address->host));
$name[] = !empty($address->personal) ? $address->personal : $emailadr;
$names[] = $address['name'];
$emails[] =$address['email'];
}
// shorten long (> $this->max_line_chars) lines of "line" chars (-_+=~) in mails
$_message = preg_replace_callback('/[-_+=~\.]{'.$this->max_line_chars.',}/m',
create_function('$matches',"return substr(\$matches[0],0,$this->max_line_chars);"),$_message);
$type = isset($this->enums['type']['email']) ? 'email' : 'note';
$status = isset($this->status['defaults'][$type]) ? $this->status['defaults'][$type] : 'done';
$info = array(
'info_id' => 0,
'info_type' => $type,
'info_from' => implode(', ',$name),
'info_addr' => implode(', ',$email),
'info_from' => implode(', ',$names),
'info_addr' => implode(', ',$emails),
'info_subject' => $_subject,
'info_des' => $_message,
'info_startdate' => egw_time::server2user($_date),
@ -1174,7 +1170,7 @@ class infolog_bo
// find the addressbookentry to link with
$addressbook = new addressbook_bo();
$contacts = array();
foreach ($email as $mailadr)
foreach ($emails as $mailadr)
{
$contacts = array_merge($contacts,(array)$addressbook->search(
array(
@ -1202,12 +1198,11 @@ class infolog_bo
{
foreach ($_attachments as $attachment)
{
$is_vfs = false;
if (parse_url($attachment['tmp_name'],PHP_URL_SCHEME) == 'vfs' && egw_vfs::is_readable($attachment['tmp_name']))
if($attachment['egw_data'])
{
$is_vfs = true;
egw_link::link('infolog',$info['link_to']['to_id'],egw_link::DATA_APPNAME, $attachment);
}
if(is_readable($attachment['tmp_name']) || $is_vfs)
else if(is_readable($attachment['tmp_name']))
{
egw_link::link('infolog',$info['link_to']['to_id'],'file', $attachment);
}

View File

@ -558,4 +558,17 @@ class infolog_hooks
unset($location); // not used, but part of hook signature
return true;
}
/**
* Mail integration hook to import mail message contents into an infolog entry
*
* @return array
*/
public static function mail_import($args)
{
return array (
'menuaction' => 'infolog.infolog_ui.mail_import',
'popup' => egw_link::get_registry('infolog', 'edit_popup')
);
}
}

View File

@ -23,7 +23,7 @@ class infolog_ui
'admin' => True,
'hook_view' => True,
'writeLangFile' => True,
'import_mail' => True,
'mail_import' => True
);
/**
* reference to the infolog preferences of the user
@ -2482,185 +2482,25 @@ class infolog_ui
/**
* imports a mail as infolog
* two possible calls:
* 1. with function args set. (we come from send mail)
* 2. with $_GET['uid] = someuid (we come from display mail)
*
* @author Cornelius Weiss <nelius@cwtech.de>
* @param string $_to_emailAddress
* @param string $_subject
* @param string $_body
* @param array $_attachments
* @param string $_date
* @param resource $_rawMail
* @param array $mailContent = null content of mail
* @return array
*/
function import_mail($_to_emailAddress=false,$_subject=false,$_body=false,$_attachments=false,$_date=false,$_rawMail=null)
function mail_import(array $mailContent=null)
{
$uid = $_GET['uid'];
$partid = $_GET['part'];
$mailbox = base64_decode($_GET['mailbox']);
$mailClass = 'mail_bo';
$sessionLocation = 'mail';
// if rowid is set, we are called from new mail module.
if (method_exists('mail_ui','splitRowID') && isset($_GET['rowid']) && !empty($_GET['rowid']))
// It would get called from compose as a popup with egw_data
if (!is_array($mailContent) && ($_GET['egw_data']))
{
// rowid holds all needed information: server, folder, uid, etc.
$rowID = $_GET['rowid'];
$hA = mail_ui::splitRowID($rowID);
$sessionLocation = $hA['app']; // THIS is part of the row ID, we may use this for validation
if ($sessionLocation != 'mail') throw new egw_exception_assertion_failed(lang('Application mail expected but got: %1',$sessionLocation));
$uid = $hA['msgUID'];
$mailbox = $hA['folder'];
$icServerID = $hA['profileID'];
$mailClass = 'mail_bo';
}
if ($_date == false || empty($_date)) $_date = $this->bo->user_time_now;
if (!empty($_to_emailAddress))
{
$GLOBALS['egw_info']['flags']['currentapp'] = 'infolog';
if (!($GLOBALS['egw_info']['user']['preferences'][$sessionLocation]['saveAsOptions']==='text_only')&&is_array($_attachments))
{
//echo __METHOD__.'<br>';
//_debug_array($_attachments);
if (!isset($icServerID)) $icServerID =& egw_cache::getSession($sessionLocation,'activeProfileID');
$mailobject = $mailClass::getInstance(true,$icServerID);
$mailobject->openConnection();
foreach ($_attachments as $attachment)
{
//error_log(__METHOD__.__LINE__.array2string($attachment));
if (trim(strtoupper($attachment['type'])) == 'MESSAGE/RFC822' && !empty($attachment['uid']) && !empty($attachment['folder']))
{
$mailobject->reopen(($attachment['folder']?$attachment['folder']:$mailbox));
// get the message itself, and attach it, as we are able to display it in egw
// instead of fetching only the attachments attached files (as we did previously)
$message = $mailobject->getMessageRawBody($attachment['uid'],$attachment['partID'],($attachment['folder']?$attachment['folder']:$mailbox));
$headers = $mailobject->getMessageHeader($attachment['uid'],$attachment['partID'],true,false,($attachment['folder']?$attachment['folder']:$mailbox));
$subject = $mailClass::adaptSubjectForImport($headers['SUBJECT']);
$attachment_file =tempnam($GLOBALS['egw_info']['server']['temp_dir'],$GLOBALS['egw_info']['flags']['currentapp']."_");
$tmpfile = fopen($attachment_file,'w');
fwrite($tmpfile,$message);
fclose($tmpfile);
$size = filesize($attachment_file);
$attachments[] = array(
'name' => trim($subject).'.eml',
'mimeType' => 'message/rfc822',
'type' => 'message/rfc822',
'tmp_name' => $attachment_file,
'size' => $size,
);
}
else
{
if (!empty($attachment['folder']))
{
$is_winmail = $_GET['is_winmail'] ? $_GET['is_winmail'] : 0;
$mailobject->reopen($attachment['folder']);
$attachmentData = $mailobject->getAttachment($attachment['uid'],$attachment['partID'],$is_winmail);
$attachment['file'] =tempnam($GLOBALS['egw_info']['server']['temp_dir'],$GLOBALS['egw_info']['flags']['currentapp']."_");
$tmpfile = fopen($attachment['file'],'w');
fwrite($tmpfile,$attachmentData['attachment']);
fclose($tmpfile);
}
//make sure we search for our attached file in our configured temp_dir
if (isset($attachment['file']) && parse_url($attachment['file'],PHP_URL_SCHEME) != 'vfs' &&
file_exists($GLOBALS['egw_info']['server']['temp_dir'].SEP.basename($attachment['file'])))
{
$attachment['file'] = $GLOBALS['egw_info']['server']['temp_dir'].SEP.basename($attachment['file']);
}
$attachments[] = array(
'name' => $attachment['name'],
'mimeType' => $attachment['type'],
'type' => $attachment['type'],
'tmp_name' => $attachment['file'],
'size' => $attachment['size'],
);
}
}
$mailobject->closeConnection();
}
// this one adds the mail itself (as message/rfc822 (.eml) file) to the infolog as additional attachment
// this is done to have a simple archive functionality (ToDo: opening .eml in email module)
if (is_resource($_rawMail) && $GLOBALS['egw_info']['user']['preferences'][$sessionLocation]['saveAsOptions']==='add_raw')
{
$subject = $mailClass::adaptSubjectForImport($_subject);
$attachment_file =tempnam($GLOBALS['egw_info']['server']['temp_dir'],$GLOBALS['egw_info']['flags']['currentapp']."_");
$tmpfile = fopen($attachment_file,'w');
fseek($_rawMail, 0, SEEK_SET);
stream_copy_to_stream($_rawMail, $tmpfile);
fclose($tmpfile);
$size = filesize($attachment_file);
$attachments[] = array(
'name' => trim($subject).'.eml',
'mimeType' => 'message/rfc822',
'type' => 'message/rfc822',
'tmp_name' => $attachment_file,
'size' => $size,
);
// get the mail raw data
egw_link::get_data ($_GET['egw_data']);
return false;
}
//_debug_array($_to_emailAddress);
$toaddr = array();
foreach(array('to','cc','bcc') as $x)
{
if (is_array($_to_emailAddress[$x]) && !empty($_to_emailAddress[$x]))
{
$toaddr = array_merge($toaddr,$_to_emailAddress[$x]);
}
}
//_debug_array($attachments);
$body_striped = strip_tags($_body); //we need to fix broken tags (or just stuff like "<800 USD/p" )
$body_decoded = htmlspecialchars_decode($body_striped,ENT_QUOTES);
$body = $mailClass::createHeaderInfoSection(array('FROM'=>$_to_emailAddress['from'],
'TO'=>(!empty($_to_emailAddress['to'])?implode(',',$_to_emailAddress['to']):null),
'CC'=>(!empty($_to_emailAddress['cc'])?implode(',',$_to_emailAddress['cc']):null),
'BCC'=>(!empty($_to_emailAddress['bcc'])?implode(',',$_to_emailAddress['bcc']):null),
'SUBJECT'=>$_subject,
'DATE'=>$mailClass::_strtotime($_date))).$body_decoded;
$this->edit($this->bo->import_mail(
implode(',',$toaddr),$_subject,$body,$attachments,$_date
));
exit;
}
elseif ($uid && $mailbox)
{
if (!isset($icServerID)) $icServerID =& egw_cache::getSession($sessionLocation,'activeProfileID');
$mailobject = $mailClass::getInstance(true,$icServerID);
$mailobject->openConnection();
$mailobject->reopen($mailbox);
$mailcontent = $mailClass::get_mailcontent($mailobject,$uid,$partid,$mailbox,false,true,(!($GLOBALS['egw_info']['user']['preferences'][$sessionLocation]['saveAsOptions']==='text_only')));
// this one adds the mail itself (as message/rfc822 (.eml) file) to the infolog 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')
{
$message = $mailobject->getMessageRawBody($uid, $partid,$mailbox);
$headers = $mailobject->getMessageHeader($uid, $partid,true,false,$mailbox);
$subject = $mailClass::adaptSubjectForImport($headers['SUBJECT']);
$attachment_file =tempnam($GLOBALS['egw_info']['server']['temp_dir'],$GLOBALS['egw_info']['flags']['currentapp']."_");
$tmpfile = fopen($attachment_file,'w');
fwrite($tmpfile,$message);
fclose($tmpfile);
$size = filesize($attachment_file);
$mailcontent['attachments'][] = array(
'name' => trim($subject).'.eml',
'mimeType' => 'message/rfc822',
'type' => 'message/rfc822',
'tmp_name' => $attachment_file,
'size' => $size,
);
}
//_debug_array($mailcontent);
return $this->edit($this->bo->import_mail(
$mailcontent['mailaddress'],
$mailcontent['subject'],
$mailcontent['message'],
$mailcontent['attachments'],
strtotime($mailcontent['headers']['DATE'])
));
}
egw_framework::window_close(lang('Error: no mail (Mailbox / UID) given!'));
return $this->edit($this->bo->import_mail($mailContent['addresses'],
$mailContent['subject'],
$mailContent['message'],
$mailContent['attachments'],
$mailContent['date']));
}
/**

View File

@ -63,6 +63,7 @@ $setup_info['infolog']['hooks']['search_link'] = 'infolog_hooks::search_link';
$setup_info['infolog']['hooks']['pm_custom_app_icons'] = 'infolog.infolog_bo.pm_icons';
$setup_info['infolog']['hooks']['timesheet_set'] = 'infolog.infolog_ui.timesheet_set';
$setup_info['infolog']['hooks']['calendar_set'] = 'infolog.infolog_ui.calendar_set';
$setup_info['infolog']['hooks']['mail_import'] = 'infolog_hooks::mail_import';
/* Dependencies for this app to work */
$setup_info['infolog']['depends'][] = array(

View File

@ -163,6 +163,14 @@ class mail_compose
'hint' => 'check to save as trackerentry on send',
'onExecute' => 'javaScript:app.mail.compose_setToggle'
),
'to_calendar' => array(
'caption' => 'Calendar',
'icon' => 'to_calendar',
'group' => $group,
'checkbox' => true,
'hint' => 'check to save as calendar event on send',
'onExecute' => 'javaScript:app.mail.compose_setToggle'
),
'disposition' => array(
'caption' => 'Notification',
'icon' => 'high',
@ -1002,14 +1010,11 @@ class mail_compose
}
}
}
//Since the ckeditor is not stable enough on mobile devices, we always convert html messages to plain text
//TODO: needs to remove html:$ua_mobile condition after better mobile support from CKeditor
//mobile compatibility is disabled expilcitly in ckeditor.js plugin too, which needs to be removed
if ($content['mimeType'] == 'html' && html::htmlarea_availible()===false || html::$ua_mobile)
if ($content['mimeType'] == 'html' && html::htmlarea_availible()===false)
{
$_content['mimeType'] = $content['mimeType'] = 'plain';
$content['body'] = $this->convertHTMLToText($content['body']);
$readonlys['mimeType'] = true;
}
// is a certain signature requested?
// only the following values are supported (and make sense)
@ -1290,7 +1295,7 @@ class mail_compose
$content['to'] = self::resolveEmailAddressList($content['to']);
//error_log(__METHOD__.__LINE__.array2string($content));
$etpl->exec('mail.mail_compose.compose',$content,$sel_options,$readonlys,$preserv,2);
$etpl->exec('mail.mail_compose.compose',$content,$sel_options,array(),$preserv,2);
}
/**
@ -2448,7 +2453,7 @@ class mail_compose
*/
public function ajax_saveAsDraft ($content, $action='button[saveAsDraft]')
{
//error_log(__METHOD__."(, action=$action)");
//error_log(__METHOD__.__LINE__.array2string($content)."(, action=$action)");
$response = egw_json_response::get();
$success = true;
@ -3047,43 +3052,44 @@ class mail_compose
if (is_array($this->sessionData['cc'])) $mailaddresses['cc'] = $this->sessionData['cc'];
if (is_array($this->sessionData['bcc'])) $mailaddresses['bcc'] = $this->sessionData['bcc'];
if (!empty($mailaddresses)) $mailaddresses['from'] = $GLOBALS['egw']->translation->decodeMailHeader($fromAddress);
// attention: we dont return from infolog/tracker. You cannot check both. cleanups will be done there.
if ($_formData['to_infolog'] == 'on') {
$uiinfolog = new infolog_ui();
$uiinfolog->import_mail(
if ($_formData['to_infolog'] == 'on' || $_formData['to_tracker'] == 'on' || $_formData['to_calendar'] == 'on' )
{
foreach(array('to_infolog','to_tracker','to_calendar') as $app_key)
{
if ($_formData[$app_key] == 'on')
{
$app_name = substr($app_key,3);
// Get registered hook data of the app called for integration
$hook = $GLOBALS['egw']->hooks->single(array('location'=> 'mail_import'),$app_name);
// store mail / eml in temp. file to not have to download it from mail-server again
$eml = tempnam($GLOBALS['egw_info']['server']['temp_dir'],'mail_integrate');
$eml_fp = fopen($eml, 'w');
stream_copy_to_stream($mail->getRaw(), $eml_fp);
fclose($eml_fp);
// Open the app called for integration in a popup
// and store the mail raw data as egw_data, in order to
// be stored from registered app method later
egw_framework::popup(egw::link('/index.php', array(
'menuaction' => $hook['menuaction'],
'egw_data' => egw_link::set_data(null,'mail_integration::integrate',array(
$mailaddresses,
$this->sessionData['subject'],
$this->convertHTMLToText($this->sessionData['body']),
$this->sessionData['attachments'],
false, // date
$mail->getRaw()
);
$eml,
$_formData['serverID']),true),
'app' => $app_name
)),'_blank',$hook['popup']);
}
if ($_formData['to_tracker'] == 'on') {
$uitracker = new tracker_ui();
$uitracker->import_mail(
$mailaddresses,
$this->sessionData['subject'],
$this->convertHTMLToText($this->sessionData['body']),
$this->sessionData['attachments'],
false, // date
$mail->getRaw()
);
}
/*
if ($_formData['to_calendar'] == 'on') {
$uical =& CreateObject('calendar.calendar_uiforms');
$uical->import_mail(
$mailaddresses,
$this->sessionData['subject'],
$this->convertHTMLToText($this->sessionData['body']),
$this->sessionData['attachments']
);
}
*/
if(is_array($this->sessionData['attachments'])) {
// only clean up temp-files, if we dont need them for mail_integration::integrate
elseif(is_array($this->sessionData['attachments']))
{
foreach($this->sessionData['attachments'] as $value) {
if (!empty($value['file']) && parse_url($value['file'],PHP_URL_SCHEME) != 'vfs') { // happens when forwarding mails
unlink($GLOBALS['egw_info']['server']['temp_dir'].'/'.$value['file']);
@ -3302,6 +3308,22 @@ class mail_compose
}
}
// Add groups
$group_options = array('account_type' => 'groups');
$groups = $GLOBALS['egw']->accounts->link_query($_searchString, $group_options);
foreach($groups as $g_id => $name)
{
$group = $GLOBALS['egw']->accounts->read($g_id);
if(!$group['account_email']) continue;
$completeMailString = trim($name) .' <'. trim($group['account_email']) .'>';
$results[] = array(
'id' => $completeMailString,
'label' => $completeMailString,
'name' => $name,
'title' => $group['account_email']
);
}
// Add up to 5 matching mailing lists
if($include_lists)
{

View File

@ -0,0 +1,288 @@
<?php
/**
* EGroupware - Mail - integration interface class
*
* @link http://www.egroupware.org
* @package mail
* @author Hadi Nategh [hn@stylite.de]
* @copyright (c) 2015 by Stylite AG <info-AT-stylite.de>
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @version $Id:$
*/
/**
* Class cotains methods and functions
* to be used to integrate mail's message into other applications
*
*/
class mail_integration {
/**
* Public functions
* @var type
*/
var $public_functions = array(
'integrate' => true
);
/**
* Maximum number of line characters (-_+=~) allowed in a mail, to not stall the layout.
* Longer lines / biger number of these chars are truncated to that max. number or chars.
*
* @var int
*/
const MAX_LINE_CHARS = 40;
/**
* Gets requested mail information and sets them as data link
* -Execute registered hook method from the requested app for integration
* -with provided content from mail:
*
* -array( 'addresses' => array (
* 'email'=> stirng,
* 'personel' => string),
* 'attachments' => array (
* 'name' => string, // file name
* 'type' => string, // mime type
* 'egw_data'=> string, // hash md5 id of an stored attachment in session (attachment which is in IMAP server)
* // NOTE: the attachmet either have egw_data OR tmp_name (e.g. raw mail eml file stores in tmp)
* 'tmp_name' => string), // tmp dir path
* 'message' => string,
* 'date' => string,
* 'subject' => string,
* 'entry_id => string // Id of the app entry which mail content will append to
* )
*
* @param string $_to_emailAddress
* @param string $_subject mail subject
* @param string $_body mail message
* @param array $_attachments attachments
* @param string $_date
* @param string $_rawMail path to file with raw mail
* @param int $_icServerID mail profile id
* @throws egw_exception_assertion_failed
*/
public static function integrate ($_to_emailAddress=false,$_subject=false,$_body=false,$_attachments=false,$_date=false,$_rawMail=null,$_icServerID=null)
{
// App name which is called for integration
$app = isset($GLOBALS['egw_info']['user']['apps'][$_GET['app']])? $_GET['app'] : null;
// preset app entry id, selected by user from app_entry_dialog
$app_entry_id = $_GET['entry_id'];
// Set the date
if (!$_date)
{
$time = time();
$_date = egw_time::server2user($time->now,'ts');
}
// Integrate not yet saved mail
if (empty($_GET['rowid']) && $_to_emailAddress && $app)
{
$sessionLocation = 'mail';
$mailbox = base64_decode($_GET['mailbox']);
$GLOBALS['egw_info']['flags']['currentapp'] = $app;
if (!($GLOBALS['egw_info']['user']['preferences'][$sessionLocation]['saveAsOptions']==='text_only')&&is_array($_attachments))
{
// initialize mail open connection requirements
if (!isset($_icServerID)) $_icServerID =& egw_cache::getSession($sessionLocation,'activeProfileID');
$mo = mail_bo::getInstance(true,$_icServerID);
$mo->openConnection();
foreach ($_attachments as $attachment)
{
if (trim(strtoupper($attachment['type'])) == 'MESSAGE/RFC822' && !empty($attachment['uid']) && !empty($attachment['folder']))
{
$mo->reopen(($attachment['folder']?$attachment['folder']:$mailbox));
// get the message itself, and attach it, as we are able to display it in egw
// instead of fetching only the attachments attached files (as we did previously)
$message = $mo->getMessageRawBody($attachment['uid'],$attachment['partID'],($attachment['folder']?$attachment['folder']:$mailbox));
$headers = $mo->getMessageHeader($attachment['uid'],$attachment['partID'],true,false,($attachment['folder']?$attachment['folder']:$mailbox));
$subject = mail_bo::adaptSubjectForImport($headers['SUBJECT']);
$attachment_file =tempnam($GLOBALS['egw_info']['server']['temp_dir'],$GLOBALS['egw_info']['flags']['currentapp']."_");
$tmpfile = fopen($attachment_file,'w');
fwrite($tmpfile,$message);
fclose($tmpfile);
$size = filesize($attachment_file);
$attachments[] = array(
'name' => trim($subject).'.eml',
'mimeType' => 'message/rfc822',
'type' => 'message/rfc822',
'tmp_name' => $attachment_file,
'size' => $size,
);
}
else
{
if (!empty($attachment['folder']))
{
$is_winmail = $_GET['is_winmail'] ? $_GET['is_winmail'] : 0;
$mo->reopen($attachment['folder']);
$attachmentData = $mo->getAttachment($attachment['uid'],$attachment['partID'],$is_winmail);
$attachment['file'] =tempnam($GLOBALS['egw_info']['server']['temp_dir'],$GLOBALS['egw_info']['flags']['currentapp']."_");
$tmpfile = fopen($attachment['file'],'w');
fwrite($tmpfile,$attachmentData['attachment']);
fclose($tmpfile);
}
//make sure we search for our attached file in our configured temp_dir
if (isset($attachment['file']) && parse_url($attachment['file'],PHP_URL_SCHEME) != 'vfs' &&
file_exists($GLOBALS['egw_info']['server']['temp_dir'].SEP.basename($attachment['file'])))
{
$attachment['file'] = $GLOBALS['egw_info']['server']['temp_dir'].SEP.basename($attachment['file']);
}
$attachments[] = array(
'name' => $attachment['name'],
'mimeType' => $attachment['type'],
'type' => $attachment['type'],
'tmp_name' => $attachment['file'],
'size' => $attachment['size'],
);
}
}
$mo->closeConnection();
}
// 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' &&
$_rawMail && file_exists($_rawMail))
{
$subject = mail_bo::adaptSubjectForImport($_subject);
$attachments[] = array(
'name' => trim($subject).'.eml',
'mimeType' => 'message/rfc822',
'type' => 'message/rfc822',
'tmp_name' => $_rawMail,
'size' => filesize($_rawMail),
'add_raw' => true
);
}
$toaddr = array();
foreach(array('to','cc','bcc') as $x)
{
if (is_array($_to_emailAddress[$x]) && !empty($_to_emailAddress[$x]))
{
$toaddr = array_merge($toaddr,$_to_emailAddress[$x]);
}
}
$body_striped = strip_tags($_body); //we need to fix broken tags (or just stuff like "<800 USD/p" )
$body_decoded = htmlspecialchars_decode($body_striped,ENT_QUOTES);
$body = mail_bo::createHeaderInfoSection(array('FROM'=>$_to_emailAddress['from'],
'TO'=>(!empty($_to_emailAddress['to'])?implode(',',$_to_emailAddress['to']):null),
'CC'=>(!empty($_to_emailAddress['cc'])?implode(',',$_to_emailAddress['cc']):null),
'BCC'=>(!empty($_to_emailAddress['bcc'])?implode(',',$_to_emailAddress['bcc']):null),
'SUBJECT'=>$_subject,
'DATE'=>mail_bo::_strtotime($_date))).$body_decoded;
$mailcontent = array(
'mailaddress' => implode(',',$toaddr),
'subject' => $_subject,
'message' => $body,
'attachments' => $attachments,
'date' => $_date
);
}
// Integrate already saved mail with ID
else
{
// Initializing mail connection requirements
$hA = mail_ui::splitRowID($_GET['rowid']);
$sessionLocation = $hA['app']; // THIS is part of the row ID, we may use this for validation
// Check the mail app
if ($sessionLocation != 'mail') throw new egw_exception_assertion_failed(lang('Application mail expected but got: %1',$sessionLocation));
$uid = $hA['msgUID'];
$mailbox = $hA['folder'];
$icServerID = $hA['profileID'];
if ($uid && $mailbox)
{
if (!isset($icServerID)) $icServerID =& egw_cache::getSession($sessionLocation,'activeProfileID');
$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')));
// 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')
{
$message = $mo->getMessageRawBody($uid, '',$mailbox);
$headers = $mo->getMessageHeader($uid, '',true,false,$mailbox);
$subject = mail_bo::adaptSubjectForImport($headers['SUBJECT']);
$attachment_file =tempnam($GLOBALS['egw_info']['server']['temp_dir'],$GLOBALS['egw_info']['flags']['currentapp']."mail_integrate");
$tmpfile = fopen($attachment_file,'w');
fwrite($tmpfile,$message);
fclose($tmpfile);
$size = filesize($attachment_file);
$mailcontent['attachments'][] = array(
'name' => trim($subject).'.eml',
'mimeType' => 'message/rfc822',
'type' => 'message/rfc822',
'tmp_name' => $attachment_file,
'size' => $size,
'add_raw' => true
);
}
$mailcontent['date'] = strtotime($mailcontent['headers']['DATE']);
}
}
// Convert addresses to email and personal
$addresses = imap_rfc822_parse_adrlist($mailcontent['mailaddress'],'');
foreach ($addresses as $address)
{
$email = sprintf('%s@%s',trim($address->mailbox),trim($address->host));
$data_addresses[] = array (
'email' => $email,
'name' => !empty($address->personal) ? $address->personal : $email
);
}
// shorten long (> self::max_line_chars) lines of "line" chars (-_+=~) in mails
$data_message = preg_replace_callback(
'/[-_+=~\.]{'.self::MAX_LINE_CHARS.',}/m',
function($matches) {
return substr($matches[0],0,self::MAX_LINE_CHARS);
},
$mailcontent['message']
);
// Get attachments ready for integration as link
if (is_array($mailcontent['attachments']))
{
foreach($mailcontent['attachments'] as $key => $attachment)
{
$data_attachments[$key] = array(
'name' => $mailcontent['attachments'][$key]['name'],
'type' => $mailcontent['attachments'][$key]['type'],
'size' => $mailcontent['attachments'][$key]['size'],
'tmp_name' => $mailcontent['attachments'][$key]['tmp_name']
);
if ($uid && !$mailcontent['attachments'][$key]['add_raw'])
{
$data_attachments[$key]['egw_data'] = egw_link::set_data($mailcontent['attachments'][$key]['mimeType'],
'emailadmin_imapbase::getAttachmentAccount',array($icServerID, $mailbox, $uid, $attachment['partID'], $is_winmail, true),true);
}
unset($mailcontent['attachments'][$key]['add_raw']);
}
}
// Get the registered hook method of requested app for integration
$hook = $GLOBALS['egw']->hooks->single(array('location' => 'mail_import'),$app);
// Execute import mail with provided content
ExecMethod($hook['menuaction'],array (
'addresses' => $data_addresses,
'attachments' => $data_attachments,
'message' => $data_message,
'date' => $mailcontent['date'],
'subject' => $mailcontent['subject'],
'entry_id' => $app_entry_id
));
}
}

View File

@ -125,12 +125,12 @@ class mail_ui
if ($_GET["resetConnection"])
{
unset($_GET["resetConnection"]);
if (mail_bo::$debug) error_log(__METHOD__.__LINE__.' Connection Reset triggered:'.$connectionReset.' for Profile with ID:'.self::$icServerID);
if (mail_bo::$debug) error_log(__METHOD__.__LINE__.' Connection Reset triggered: for Profile with ID:'.self::$icServerID);
emailadmin_imapbase::unsetCachedObjects(self::$icServerID);
}
try {
$this->mail_bo = mail_bo::getInstance(true,self::$icServerID,$_validate=true, $_oldImapServerObject=false, $_reuseCache=true);
$this->mail_bo = mail_bo::getInstance(true,self::$icServerID, true, false, true);
if (mail_bo::$debug) error_log(__METHOD__.__LINE__.' Fetched IC Server:'.self::$icServerID.'/'.$this->mail_bo->profileID.':'.function_backtrace());
//error_log(__METHOD__.__LINE__.array2string($this->mail_bo->icServer));
@ -1224,8 +1224,7 @@ class mail_ui
'hint' => 'Save as InfoLog',
'icon' => 'infolog/navbar',
'group' => ++$group,
'onExecute' => 'javaScript:app.mail.mail_infolog',
'url' => 'menuaction=infolog.infolog_ui.import_mail',
'onExecute' => 'javaScript:app.mail.mail_integrate',
'popup' => egw_link::get_registry('infolog', 'add_popup'),
'allowOnMultiple' => false,
'toolbarDefault' => true
@ -1235,11 +1234,21 @@ class mail_ui
'hint' => 'Save as ticket',
'group' => $group,
'icon' => 'tracker/navbar',
'onExecute' => 'javaScript:app.mail.mail_tracker',
'url' => 'menuaction=tracker.tracker_ui.import_mail',
'onExecute' => 'javaScript:app.mail.mail_integrate',
'popup' => egw_link::get_registry('tracker', 'add_popup'),
'mail_import' => $GLOBALS['egw']->hooks->single(array('location' => 'mail_import'),'tracker'),
'allowOnMultiple' => false,
),
'calendar' => array(
'caption' => 'Calendar',
'hint' => 'Save as Calendar',
'icon' => 'calendar/navbar',
'group' => $group,
'onExecute' => 'javaScript:app.mail.mail_integrate',
'popup' => egw_link::get_registry('calendar', 'add_popup'),
'allowOnMultiple' => false,
'toolbarDefault' => true
),
'print' => array(
'caption' => 'Print',
'group' => ++$group,
@ -3239,7 +3248,6 @@ class mail_ui
$file = $content['uploadForImport'];
}
$destination = $content['FOLDER'][0];
$rememberServerID = $icServerID = $this->mail_bo->profileID;
if (stripos($destination,self::$delimiter)!==false) list($icServerID,$destination) = explode(self::$delimiter,$destination,2);
if ($icServerID && $icServerID != $this->mail_bo->profileID)
@ -3462,7 +3470,6 @@ class mail_ui
$folder = $uidA['folder']; // all messages in one set are supposed to be within the same folder
$messageID = $uidA['msgUID'];
$icServerID = $uidA['profileID'];
$rememberServerID = $this->mail_bo->profileID;
if ($icServerID && $icServerID != $this->mail_bo->profileID)
{
//error_log(__METHOD__.__LINE__.' change Profile to ->'.$icServerID);
@ -4693,7 +4700,7 @@ class mail_ui
//error_log(__METHOD__.__LINE__.$uID);
if ($_copyOrMove=='move')
{
$messageListForRefresh[] = self::generateRowID($sourceProfileID, $folderName, $uID, $_prependApp=false);
$messageListForRefresh[] = self::generateRowID($sourceProfileID, $_folderName, $uID, $_prependApp=false);
}
}
}

View File

@ -2565,16 +2565,23 @@ app.classes.mail = AppJS.extend(
},
/**
* Save message as InfoLog
* Integrate mail message into another app's entry
*
* @param _action
* @param _elems _elems[0].id is the row-id
*/
mail_infolog: function(_action, _elems)
mail_integrate: function(_action, _elems)
{
//define/preset w_h in case something fails
var reg = '750x580';
var w_h =reg.split('x');
var app = _action.id;
var w_h = ['750','580']; // define a default wxh if there's no popup size registered
var add_as_new = true;
if (typeof _action.data != 'undefined' )
{
if (typeof _action.data.popup != 'undefined') w_h = _action.data.popup.split('x');
if (typeof _action.data.mail_import != 'undefined') var mail_import_hook = _action.data.mail_import;
}
if (typeof _elems == 'undefined' || _elems.length==0)
{
@ -2591,77 +2598,72 @@ app.classes.mail = AppJS.extend(
_elems.push({id:this.mail_currentlyFocussed});
}
}
if (typeof _action.data.width == 'undefined' && typeof _action.data.height == 'undefined' && !(typeof _action.data.event == 'undefined' &&typeof _action.data.event.popup == 'undefined'))
{
if (_action.data.event.popup)
{
var app_registry = _action.data.event.popup;
}
else
{
var app_registry = egw.link_get_registry('infolog');//this.appname);
}
if (typeof app_registry['edit'] != 'undefined' && typeof app_registry['edit_popup'] != 'undefined' )
{
w_h =app_registry['edit_popup'].split('x');
}
}
}
var url = window.egw_webserverUrl+'/index.php?';
url += 'menuaction=infolog.infolog_ui.import_mail'; // todo compose for Draft folder
url += '&rowid='+_elems[0].id;
egw_openWindowCentered(url,'import_mail_'+_elems[0].id,(_action.data.width?_action.data.width:w_h[0]),(_action.data.height?_action.data.height:w_h[1]));
},
var url = window.egw_webserverUrl+ '/index.php?menuaction=mail.mail_integration.integrate&rowid=' + _elems[0].id + '&app='+app;
/**
* Save message as ticket
* Checks the application entry existance and offers user
* to select desire app id to append mail content into it,
* or add the mail content as a new app entry
*
* @param _action _action.id is 'read', 'unread', 'flagged' or 'unflagged'
* @param _elems
* @param {string} _title select app entry title
* @param {string} _appName app to be integrated
* @param {string} _appCheckCallback registered mail_import hook method
* for check app entry existance
*/
mail_tracker: function(_action, _elems)
check_app_entry = function (_title, _appName, _appCheckCallback)
{
//define/preset w_h in case something fails
var reg = '780x535';
var w_h =reg.split('x');
if (typeof _elems == 'undefined' || _elems.length==0)
var data = egw.dataGetUIDdata(_elems[0].id);
var subject = (data && typeof data.data != 'undefined')? data.data.subject : '';
egw.json(_appCheckCallback, subject,function(_entryId){
// if there's no entry saved already
// open dialog in order to select one
if (!_entryId)
{
if (this.et2.getArrayMgr("content").getEntry('mail_id'))
var buttons = [
{text: 'Append', id: 'append', image: 'check', default:true},
{text: 'Add as new', id: 'new', image: 'check'},
{text: 'Cancel', id: 'cancel', image: 'check'}
];
et2_createWidget("dialog",
{
var _elems = [];
_elems.push({id:this.et2.getArrayMgr("content").getEntry('mail_id') || ''});
callback: function(_buttons, _value)
{
if (_buttons == 'cancel') return;
if (_buttons == 'append' && _value)
{
url += '&entry_id=' + _value.id;
}
if ((typeof _elems == 'undefined' || _elems.length==0) && this.mail_isMainWindow)
{
if (this.mail_currentlyFocussed)
{
var _elems = [];
_elems.push({id:this.mail_currentlyFocussed});
egw_openWindowCentered(url,'import_mail_'+_elems[0].id,w_h[0],w_h[1]);
},
title: egw.lang(_title),
buttons: buttons||et2_dialog.BUTTONS_OK_CANCEL,
value:{
content:{
appName:_appName // appName to search on its list later
}},
template: egw.webserverUrl+'/mail/templates/default/integration_to_entry_dialog.xet'
},et2_dialog._create_parent('mail'));
}
else // there is an entry saved related to this mail's subject
{
egw_openWindowCentered(url,'import_mail_'+_elems[0].id,w_h[0],w_h[1]);
}
if (typeof _action.data.width == 'undefined' && typeof _action.data.height == 'undefined' && !(typeof _action.data.event == 'undefined' &&typeof _action.data.event.popup == 'undefined'))
},this,true,this).sendRequest();
}
if (mail_import_hook && typeof mail_import_hook.app_entry_method != 'undefined')
{
if (_action.data.event.popup)
{
var app_registry = _action.data.event.popup;
check_app_entry('Select '+ app + ' entry', app, mail_import_hook.app_entry_method);
}
else
{
var app_registry = egw.link_get_registry('tracker');//this.appname);
egw_openWindowCentered(url,'import_mail_'+_elems[0].id,w_h[0],w_h[1]);
}
if (typeof app_registry['add'] != 'undefined' && typeof app_registry['add_popup'] != 'undefined' )
{
w_h =app_registry['add_popup'].split('x');
}
}
}
//alert('mail_tracker('+_elems[0].id+')');
var url = window.egw_webserverUrl+'/index.php?';
url += 'menuaction=tracker.tracker_ui.import_mail'; // todo compose for Draft folder
url += '&rowid='+_elems[0].id;
egw_openWindowCentered(url,'import_tracker_'+_elems[0].id,(_action.data.width?_action.data.width:w_h[0]),(_action.data.height?_action.data.height:w_h[1]));
},
},
/**
* mail_getFormData

View File

@ -373,6 +373,7 @@ saving of message %1 failed. destination folder %2 does not exist. mail de Speic
saving of message %1 succeeded. check folder %2. mail de Speichern der Nachricht %1 war erfolgreich. Prüfen Sie den Ziel Ordner %2
saving the rule failed: mail de Speichern der Regel ist fehlgeschlagen:
select all mail de Alle Auswählen
select an existing entry in order to append mail content to it mail de Bestehendes Ticket auswählen, zu dem die Mail als Kommentar hinzugefügt werden soll.
select file to attach to message mail de Wählen Sie die Dateien aus, die Sie an diese Nachricht anhängen möchten.
select file to import into folder mail de Wählen Sie ein E-Mail als Datei aus, damit Sie in ein Ordner importiert werden kann.
select file(s) from vfs mail de Dateien aus dem EGroupware Dateimanager anhängen.

View File

@ -373,6 +373,7 @@ saving of message %1 failed. destination folder %2 does not exist. mail en Savin
saving of message %1 succeeded. check folder %2. mail en Saving of message %1 succeeded. Check Folder %2.
saving the rule failed: mail en Saving the rule failed:
select all mail en Select all
select an existing entry in order to append mail content to it mail en Select an existing entry in order to append mail content to it
select file to attach to message mail en Select file to attach to message
select file to import into folder mail en Select file to import into Folder
select file(s) from vfs mail en Select file(s) from VFS

View File

@ -10,6 +10,7 @@
<file class="mail-compose_fileselector" statustext="Select file to attach to message" multiple='true' progress='attachments' onFinish="app.mail.uploadForCompose" onStart="app.mail.composeUploadStart" id="uploadForCompose" drop_target ="mail-compose"/>
<checkbox statustext="check to save as infolog on send" id="to_infolog" options="on,off"/>
<checkbox statustext="check to save as trackerentry on send" id="to_tracker" options="on,off"/>
<checkbox statustext="check to save as calendar event on send" id="to_calendar" options="on,off"/>
<checkbox statustext="check to recieve a notification when the message is read (note: not all clients support this and/or the reciever may not authorize the notification)" id="disposition" options="on,off"/>
<menulist>
<menupopup id="priority"/>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE overlay PUBLIC "-//Stylite AG//eTemplate 2//EN" "http://www.egroupware.org/etemplate2.dtd">
<!-- $Id$ -->
<overlay>
<template id="mail.integration_to_entry_dialog" template="" lang="" group="0" version="1.9.001">
<vbox width="100%">
<description value="Select an existing entry in order to append mail content to it"/>
<description/>
<link-entry id="id" only_app="@appName" class="et2_fullWidth"/>
</vbox>
</template>
</overlay>

View File

@ -112,6 +112,11 @@ class egw_link extends solink
*/
const VFS_APPNAME = 'file'; // pseudo-appname for own file-attachments in vfs, this is NOT the vfs-app
/**
* Appname used of files stored via egw_link::set_data()
*/
const DATA_APPNAME = 'egw-data';
/**
* appname used for linking existing files to VFS
*/
@ -188,9 +193,10 @@ class egw_link extends solink
static function init_static( )
{
// FireFox 36 can not display pdf with it's internal viewer in an iframe used by mobile theme/template for popups
if (html::$user_agent == 'firefox' && $GLOBALS['egw_info']['user']['preferences']['common']['theme'] == 'mobile')
// same is true for all mobile devices
if (html::$user_agent == 'firefox' && $GLOBALS['egw_info']['user']['preferences']['common']['theme'] == 'mobile' || html::$ua_mobile)
{
unset(self::$app_register['home']['mime']['application/pdf']['mime_popup']);
unset(self::$app_register['home']['mime']['application/pdf']);
}
// other apps can participate in the linking by implementing a search_link hook, which
// has to return an array in the format of an app_register entry
@ -307,13 +313,12 @@ class egw_link extends solink
* of not created item or $file-array if $app1 == self::VFS_APPNAME (see below).
* If $id==0 it will be set on return to an array with the links for the new item.
* @param string|array $app2 app of 2.linkend or array with links ($id2 not used)
* @param string $id2 ='' id of 2. item of $file-array if $app2 == self::VFS_APPNAME (see below)<br>
* $file array with informations about the file in format of the etemplate file-type<br>
* $file['name'] name of the file (no directory)<br>
* $file['type'] mine-type of the file<br>
* $file['tmp_name'] name of the uploaded file (incl. directory)<br>
* $file['path'] path of the file on the client computer<br>
* $file['ip'] of the client (path and ip in $file are only needed if u want a symlink (if possible))
* @param string $id2 ='' id of 2. item of $file-array if $app2 == self::VFS_APPNAME or self::DATA_APPNAME
* $file array with informations about the file in format of the etemplate file-type
* $file['name'] name of the file (no directory)
* $file['type'] mime-type of the file
* $file['tmp_name'] name of the uploaded file (incl. directory) for self::VFS_APPNAME or
* $file['egw_data'] id of egw_link::set_data() call for self::DATA_APPNAME
* @param string $remark ='' Remark to be saved with the link (defaults to '')
* @param int $owner =0 Owner of the link (defaults to user)
* @param int $lastmod =0 timestamp of last modification (defaults to now=time())
@ -346,22 +351,30 @@ class egw_link extends solink
self::link($app1, $id1, $link['app'], $link['id'], $link['remark'],$link['owner'],$link['lastmod']);
continue;
}
if ($link['app'] == self::VFS_APPNAME)
switch ($link['app'])
{
case self::DATA_APPNAME:
if (!($link['id']['tmp_name'] = self::get_data($link['id']['egw_data'], true)))
{
$link_id = false;
break;
}
// fall through
case self::VFS_APPNAME:
$link_id = self::attach_file($app1,$id1,$link['id'],$link['remark']);
}
else if ($link['app'] == self::VFS_LINK)
{
break;
case self::VFS_LINK:
$link_id = self::link_file($app1,$id1, $link['id'],$link['remark']);
}
else
{
break;
default:
$link_id = solink::link($app1,$id1,$link['app'],$link['id'],
$link['remark'],$link['owner'],$link['lastmod']);
// notify both sides
if (!($no_notify&2)) self::notify('link',$link['app'],$link['id'],$app1,$id1,$link_id);
if (!($no_notify&1)) self::notify('link',$app1,$id1,$link['app'],$link['id'],$link_id);
break;
}
}
return $link_id;
@ -421,7 +434,7 @@ class egw_link extends solink
*/
static function temp_link_id($app,$id)
{
return $app.':'.($app != self::VFS_APPNAME && $app != self::VFS_LINK ? $id : $id['name']);
return $app.':'.(!in_array($app, array(self::VFS_APPNAME,self::VFS_LINK, self::DATA_APPNAME)) ? $id : $id['name']);
}
/**
@ -1178,9 +1191,7 @@ class egw_link extends solink
* @param array $file informations about the file in format of the etemplate file-type
* $file['name'] name of the file (no directory)
* $file['type'] mine-type of the file
* $file['tmp_name'] name of the uploaded file (incl. directory)
* $file['path'] path of the file on the client computer
* $file['ip'] of the client (path and ip are only needed if u want a symlink (if possible))
* $file['tmp_name'] name of the uploaded file (incl. directory) or resource of opened file
* @param string $comment ='' comment to add to the link
* @return int negative id of egw_sqlfs table as negative link-id's are for vfs attachments
*/
@ -1552,16 +1563,18 @@ class egw_link extends solink
* @param string $mime_type
* @param string $method
* @param array $params
* @param boolean $ignore_mime =false true: return id, even if nothing registered for given mime-type
* @return string|null md5 hash of stored data of server-side supported mime-type or null otherwise
*/
public static function set_data($mime_type, $method, array $params)
public static function set_data($mime_type, $method, array $params, $ignore_mime=false)
{
if (!($info = self::get_mime_info($mime_type)) || empty($info['mime_data']))
if (!$ignore_mime && (!($info = self::get_mime_info($mime_type)) || empty($info['mime_data'])))
{
return null;
}
array_unshift($params, $method);
$id = md5(json_encode($params));
$id = md5(serialize($params));
//error_log(__METHOD__."('$mime_type', '$method', ...) params=".array2string($params)." --> json=".array2string(serialize($params)).' --> id='.array2string($id));
egw_cache::setSession(__CLASS__, $id, $params);
return $id;
}
@ -1584,6 +1597,8 @@ class egw_link extends solink
}
$ret = call_user_func_array('ExecMethod2', $data);
if (is_resource($ret)) fseek($ret, 0);
if ($return_resource != is_resource($ret))
{
if ($return_resource && ($fp = fopen('php://temp', 'w')))
@ -1596,7 +1611,6 @@ class egw_link extends solink
{
$fp = $ret;
$ret = '';
fseek($fp, 0);
while(!feof($fp))
{
$ret .= fread($fp, 8192);

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB