* 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 unset($data); // not used, but in function signature for hooks
return true; 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 // 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, 'import' => true,
'cat_acl' => true, 'cat_acl' => true,
'meeting' => 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; $event['whole_day'] = !$start['hour'] && !$start['minute'] && $end['hour'] == 23 && $end['minute'] == 59;
$link_to_id = $event['id']; $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']); $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) foreach(is_array($_REQUEST['link_app']) ? $_REQUEST['link_app'] : array($_REQUEST['link_app']) as $n => $link_app)
{ {
$link_id = $link_ids[$n]; $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 if(!preg_match('/^[a-z_0-9-]+:[:a-z_0-9-]+$/i',$link_app.':'.$link_id)) // guard against XSS
{ {
continue; continue;
@ -1866,7 +1866,7 @@ class calendar_uiforms extends calendar_ui
$event['ics_method_label'] = strtolower($ical_method) == 'request' ? $event['ics_method_label'] = strtolower($ical_method) == 'request' ?
lang('Meeting request') : lang('Reply to meeting request'); lang('Meeting request') : lang('Reply to meeting request');
$tpl = new etemplate_new('calendar.meeting'); $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']; if (!$content['duration']) $content['duration'] = $content['end'] - $content['start'];
$weekds = 0; $weekds = 0;
foreach ($content['weekdays'] as $keys =>$wdays) foreach ($content['weekdays'] as &$wdays)
{ {
$weekds = $weekds + $wdays; $weekds = $weekds + $wdays;
} }
@ -2288,8 +2288,6 @@ class calendar_uiforms extends calendar_ui
} }
if (!is_array($content)) if (!is_array($content))
{ {
$view = $GLOBALS['egw']->session->appsession('view','calendar');
$content = array( $content = array(
'start' => $this->bo->date2ts($_REQUEST['start'] ? $_REQUEST['start'] : $this->date), 'start' => $this->bo->date2ts($_REQUEST['start'] ? $_REQUEST['start'] : $this->date),
'end' => $this->bo->date2ts($_REQUEST['end'] ? $_REQUEST['end'] : $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']['export_limit'] = 'calendar_hooks::getAppExportLimit';
$setup_info['calendar']['hooks']['acl_rights'] = 'calendar_hooks::acl_rights'; $setup_info['calendar']['hooks']['acl_rights'] = 'calendar_hooks::acl_rights';
$setup_info['calendar']['hooks']['categories'] = 'calendar_hooks::categories'; $setup_info['calendar']['hooks']['categories'] = 'calendar_hooks::categories';
$setup_info['calendar']['hooks']['mail_import'] = 'calendar_hooks::mail_import';
/* Dependencies for this app to work */ /* Dependencies for this app to work */
$setup_info['calendar']['depends'][] = array( $setup_info['calendar']['depends'][] = array(

View File

@ -290,7 +290,7 @@ class emailadmin_imapbase
{ {
try try
{ {
$mailbox = $_icServerObject->getCurrentMailbox(); $_icServerObject->getCurrentMailbox();
} }
catch (Exception $e) catch (Exception $e)
{ {
@ -445,7 +445,7 @@ class emailadmin_imapbase
function restoreSessionData() function restoreSessionData()
{ {
$this->sessionData = array();//egw_cache::getCache(egw_cache::SESSION,'mail','session_data',$callback=null,$callback_params=array(),$expiration=60*60*1); $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]; 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 (!empty($this->sessionData['mailbox'])) self::$activeFolderCache[$this->profileID]=$this->sessionData['mailbox'];
if (isset(self::$activeFolderCache) && is_array(self::$activeFolderCache)) 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; $_profileID = null;
self::resetConnectionErrorCache($_profileID,$account_id); self::resetConnectionErrorCache($_profileID,$account_id);
self::resetFolderObjectCache($_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','rawHeadersCache'.trim($account_id),array(), 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','HierarchyDelimiter'.trim($account_id),array(), 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','eMailListContainsDeletedMessages'.trim($account_id),array(), 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','vacationNotice'.trim($account_id),array(), 60*60*24*1);
} }
} }
} }
@ -549,7 +549,6 @@ class emailadmin_imapbase
} }
if (is_null($_ImapServerId)) if (is_null($_ImapServerId))
{ {
$buff = array();
$isConError = array(); $isConError = array();
$waitOnFailure = array(); $waitOnFailure = array();
} }
@ -560,14 +559,14 @@ class emailadmin_imapbase
{ {
unset($isConError[$_ImapServerId]); 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])) if (isset($waitOnFailure[$_ImapServerId]))
{ {
unset($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','icServerSIEVE_connectionError'.trim($account_id),$isConError,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','ActiveSyncWaitOnFailure'.trim($account_id),$waitOnFailure,60*60*2);
} }
/** /**
@ -591,12 +590,12 @@ class emailadmin_imapbase
} }
else 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])) if (!empty($folders2return) && isset($folders2return[$_ImapServerId]))
{ {
unset($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])) if (!empty($folderInfo) && isset($folderInfo[$_ImapServerId]))
{ {
unset($folderInfo[$_ImapServerId]); unset($folderInfo[$_ImapServerId]);
@ -608,23 +607,23 @@ class emailadmin_imapbase
unset($lastFolderUsedForMove[$_ImapServerId]); 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])) if (!empty($folderBasicInfo) && isset($folderBasicInfo[$_ImapServerId]))
{ {
unset($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])) if (!empty($_specialUseFolders) && isset($_specialUseFolders[$_ImapServerId]))
{ {
unset($_specialUseFolders[$_ImapServerId]); unset($_specialUseFolders[$_ImapServerId]);
self::$specialUseFolders=null; 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','folderObjects'.trim($account_id),$folders2return, 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','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','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','folderBasicInfo'.trim($account_id),$folderBasicInfo,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','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 * 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 * @param boolean $resolve_placeholders wether or not resolve possible placeholders in identities
* @return array - array(email=>realname) * @return array - array(email=>realname)
*/ */
@ -726,7 +725,7 @@ class emailadmin_imapbase
*/ */
function getDefaultIdentity() { function getDefaultIdentity() {
// retrieve the signature accociated with the identity // retrieve the signature accociated with the identity
$id = $this->getIdentitiesWithAccounts($_accountData); $id = $this->getIdentitiesWithAccounts($_accountData=array());
$acc = emailadmin_account::read($this->profileID); $acc = emailadmin_account::read($this->profileID);
$accountDataIT = ($_accountData[$this->profileID]?$acc->identities($this->profileID,false,'ident_id'):$acc->identities($_accountData[$id],false,'ident_id')); $accountDataIT = ($_accountData[$this->profileID]?$acc->identities($this->profileID,false,'ident_id'):$acc->identities($_accountData[$id],false,'ident_id'));
foreach($accountDataIT as $it => $accountData) foreach($accountDataIT as $it => $accountData)
@ -745,7 +744,7 @@ class emailadmin_imapbase
{ {
// account select box // account select box
$selectedID = $this->profileID; $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) { if ($allAccountData) {
$rememberFirst=$selectedFound=null; $rememberFirst=$selectedFound=null;
foreach ($allAccountData as $tmpkey => $icServers) 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 * 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 * @return void
*/ */
function reopen($_foldername) function reopen($_foldername)
@ -835,8 +834,8 @@ class emailadmin_imapbase
/** /**
* openConnection * openConnection
* *
* @param int $_icServerID * @param int $_icServerID = 0
* @param boolean $_adminConnection * @param boolean $_adminConnection = false
* @throws Horde_Imap_Client_Exception on connection error or authentication failure * @throws Horde_Imap_Client_Exception on connection error or authentication failure
* @throws InvalidArgumentException on missing credentials * @throws InvalidArgumentException on missing credentials
*/ */
@ -939,7 +938,6 @@ class emailadmin_imapbase
{ {
foreach ($singleNameSpaceArray as $k => $singleNameSpace) foreach ($singleNameSpaceArray as $k => $singleNameSpace)
{ {
$prefix_present = false;
$_foldersNameSpace = array(); $_foldersNameSpace = array();
if($type == 'personal' && $singleNameSpace['name'] == '#mh/' && ($this->folderExists('Mail')||$this->folderExists('INBOX'))) if($type == 'personal' && $singleNameSpace['name'] == '#mh/' && ($this->folderExists('Mail')||$this->folderExists('INBOX')))
{ {
@ -975,7 +973,7 @@ class emailadmin_imapbase
*/ */
function getFolderPrefixFromNamespace($nameSpace, $folderName) 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($singleNameSpace['prefix'],0,strlen($folderName))==$folderName) return $singleNameSpace['prefix'];
if (substr($folderName,0,strlen($singleNameSpace['prefix']))==$singleNameSpace['prefix']) 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) function getHierarchyDelimiter($_useCache=true)
{ {
static $HierarchyDelimiter; 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 ($_useCache===false) unset($HierarchyDelimiter[$this->icServer->ImapServerId]);
if (isset($HierarchyDelimiter[$this->icServer->ImapServerId])&&!empty($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] = '/'; $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]; return $HierarchyDelimiter[$this->icServer->ImapServerId];
} }
@ -1020,7 +1018,7 @@ class emailadmin_imapbase
{ {
//error_log(__METHOD__.' ('.__LINE__.') '.':'.$this->icServer->ImapServerId.' Connected:'.$this->icServer->_connected); //error_log(__METHOD__.' ('.__LINE__.') '.':'.$this->icServer->ImapServerId.' Connected:'.$this->icServer->_connected);
static $_specialUseFolders; 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_trash));
//error_log(__METHOD__.' ('.__LINE__.') '.array2string($this->icServer->acc_folder_sent)); //error_log(__METHOD__.' ('.__LINE__.') '.array2string($this->icServer->acc_folder_sent));
//error_log(__METHOD__.' ('.__LINE__.') '.array2string($this->icServer->acc_folder_draft)); //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'; $_specialUseFolders[$this->icServer->ImapServerId][$this->icServer->acc_folder_junk]='Junk';
//error_log(__METHOD__.' ('.__LINE__.') '.array2string($_specialUseFolders));//.'<->'.array2string($this->icServer)); //error_log(__METHOD__.' ('.__LINE__.') '.array2string($_specialUseFolders));//.'<->'.array2string($this->icServer));
self::$specialUseFolders = $_specialUseFolders[$this->icServer->ImapServerId]; 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]; return $_specialUseFolders[$this->icServer->ImapServerId];
} }
@ -1210,7 +1208,7 @@ class emailadmin_imapbase
if (!empty($nameSpace[$this->profileID])) if (!empty($nameSpace[$this->profileID]))
{ {
$nsNoPersonal=array(); $nsNoPersonal=array();
foreach($nameSpace[$this->profileID] as $k => $ns) foreach($nameSpace[$this->profileID] as &$ns)
{ {
if ($ns['type']!='personal') $nsNoPersonal[]=$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 // we filter for the combined status of unseen and undeleted, as this is what we show in list
try 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']; $retValue['unseen'] = $sortResult['count'];
} }
catch (Exception $ee) 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 // 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 // if sort capability is applied to the range fetched, not sort first and fetch the range afterwards
$start = $_startMessage-1; //$start = $_startMessage-1;
$end = $_startMessage-1+$_numberOfMessages; //$end = $_startMessage-1+$_numberOfMessages;
//$_filter['range'] ="$start:$end"; //$_filter['range'] ="$start:$end";
//$_filter['range'] ="$_startMessage:*"; //$_filter['range'] ="$_startMessage:*";
} }
@ -1376,7 +1374,7 @@ class emailadmin_imapbase
$sortResult = (is_array($_thisUIDOnly) ? $_thisUIDOnly:(array)$_thisUIDOnly); $sortResult = (is_array($_thisUIDOnly) ? $_thisUIDOnly:(array)$_thisUIDOnly);
} }
//$queryString = implode(',', $sortResult);
// fetch the data for the selected messages // fetch the data for the selected messages
if (self::$debug||self::$debugTimes) $starttime = microtime(true); if (self::$debug||self::$debugTimes) $starttime = microtime(true);
try try
@ -1414,7 +1412,11 @@ class emailadmin_imapbase
if (self::$debug||self::$debugTimes) if (self::$debug||self::$debugTimes)
{ {
self::logRunTimes($starttime,null,'HordeFetch: for Folder:'.$_folderName.' Filter:'.array2string($_filter),__METHOD__.' ('.__LINE__.') '); 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; $count = 0;
@ -1506,7 +1508,7 @@ class emailadmin_imapbase
if ($mime_type=='message/rfc822') if ($mime_type=='message/rfc822')
{ {
//error_log(__METHOD__.' ('.__LINE__.') '.' Uid:'.$uid.'->'.$mime_id.':'.array2string($part->contentTypeMap())); //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)); //error_log(__METHOD__.' ('.__LINE__.') '.' Uid:'.$uid.'->'.$mime_id.' Disp:'.$partdisposition.' Type:'.$partPrimaryType.' Skip:'.array2string($skipParts));
if (array_key_exists($mime_id,$skipParts)) continue; 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(); if (!isset($attachment['name'])||empty($attachment['name'])) $attachment['name'] = $part->getName();
$attachment['size'] = $part->getBytes(); $attachment['size'] = $part->getBytes();
if (($cid = $part->getContentId())) $attachment['cid'] = $cid; 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; $headerObject['ATTACHMENTS'][$mime_id.'.'.$vmime_id] = $attachment;
} }
if ($tnefResolved) unset($headerObject['ATTACHMENTS'][$mime_id]); 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__.') '.' '.$headerObject['SUBJECT'].'->'.$headerObject['DATE']);
//error_log(__METHOD__.' ('.__LINE__.') '.' '.$this->decode_subject($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]]['subject'] = $this->decode_subject($headerObject['SUBJECT']);
$retValue['header'][$sortOrder[$uid]]['size'] = $headerObject['SIZE']; $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); $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)); //error_log(__METHOD__.' ('.__LINE__.') '.' Filter:'.array2string($_filter));
$try2useCache = true; $try2useCache = true;
static $eMailListContainsDeletedMessages; 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 // 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 ($setSession==true && ((strpos(array2string($_filter), 'UNDELETED') === false && strpos(array2string($_filter), 'DELETED') === false)))
{ {
if (self::$debugTimes) $starttime = microtime(true); 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); $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']; $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']); 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; $try2useCache = false;
//self::$supportsORinQuery[$this->profileID]=true; //self::$supportsORinQuery[$this->profileID]=true;
if (is_null(self::$supportsORinQuery) || !isset(self::$supportsORinQuery[$this->profileID])) 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; if (!isset(self::$supportsORinQuery[$this->profileID])) self::$supportsORinQuery[$this->profileID]=true;
} }
//error_log(__METHOD__.' ('.__LINE__.') '.array2string($_filter).' SupportsOrInQuery:'.self::$supportsORinQuery[$this->profileID]); //error_log(__METHOD__.' ('.__LINE__.') '.array2string($_filter).' SupportsOrInQuery:'.self::$supportsORinQuery[$this->profileID]);
@ -1777,7 +1779,7 @@ class emailadmin_imapbase
//error_log(__METHOD__.'('.__LINE__.'):'.$e->getMessage()); //error_log(__METHOD__.'('.__LINE__.'):'.$e->getMessage());
// possible error OR Query. But Horde gives no detailed Info :-( // possible error OR Query. But Horde gives no detailed Info :-(
self::$supportsORinQuery[$this->profileID]=false; 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); 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]); $filter = $this->createIMAPFilter($_folderName, $_filter, self::$supportsORinQuery[$this->profileID]);
try try
@ -1889,7 +1891,7 @@ class emailadmin_imapbase
$imapFilter->charset('UTF-8'); $imapFilter->charset('UTF-8');
//_debug_array($_criterias); //_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']))) { if((!is_array($_criterias) || $_criterias['status']=='any') && (!isset($_criterias['string']) || empty($_criterias['string']))) {
$imapFilter->flag('DELETED', $set=false); $imapFilter->flag('DELETED', $set=false);
return $imapFilter; return $imapFilter;
@ -2222,7 +2224,7 @@ class emailadmin_imapbase
{ {
$opts['special_use'] = self::$specialUseFolders[$newFolderName]; $opts['special_use'] = self::$specialUseFolders[$newFolderName];
} }
$rv = $this->icServer->createMailbox($newFolderName, $opts); $this->icServer->createMailbox($newFolderName, $opts);
} }
catch (Exception $e) catch (Exception $e)
{ {
@ -2232,7 +2234,7 @@ class emailadmin_imapbase
} }
try try
{ {
$srv = $this->icServer->subscribeMailbox($newFolderName); $this->icServer->subscribeMailbox($newFolderName);
} }
catch (Exception $e) catch (Exception $e)
{ {
@ -2267,14 +2269,14 @@ class emailadmin_imapbase
if (self::$debug) error_log("create folder: $newFolderName"); if (self::$debug) error_log("create folder: $newFolderName");
try try
{ {
$rv = $this->icServer->renameMailbox($oldFolderName, $newFolderName); $this->icServer->renameMailbox($oldFolderName, $newFolderName);
} }
catch (Exception $e) catch (Exception $e)
{ {
throw new egw_exception(__METHOD__." failed for $oldFolderName (rename to: $newFolderName) with error:".$e->getMessage());; throw new egw_exception(__METHOD__." failed for $oldFolderName (rename to: $newFolderName) with error:".$e->getMessage());;
} }
// clear FolderExistsInfoCache // 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; return $newFolderName;
@ -2297,10 +2299,10 @@ class emailadmin_imapbase
} }
catch (Exception $e) 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 // 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; return true;
} }
@ -2352,7 +2354,7 @@ class emailadmin_imapbase
if ($_subscribedOnly && $_getCounters===false) 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])) if ($_useCacheIfPossible && isset($folders2return[$this->icServer->ImapServerId]) && !empty($folders2return[$this->icServer->ImapServerId]))
{ {
//error_log(__METHOD__.' ('.__LINE__.') '.' using Cached folderObjects'.array2string($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] // use $folderBasicInfo for holding attributes and other basic folderinfo $folderBasicInfo[$this->icServer->ImapServerId]
static $folderBasicInfo; 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]))); //error_log(__METHOD__.' ('.__LINE__.') '.array2string(array_keys($folderBasicInfo[$this->icServer->ImapServerId])));
$isUWIMAP = false;
$delimiter = $this->getHierarchyDelimiter(); $delimiter = $this->getHierarchyDelimiter();
@ -2391,6 +2392,7 @@ class emailadmin_imapbase
//$nameSpace = $this->icServer->getNameSpaces(); //$nameSpace = $this->icServer->getNameSpaces();
$nameSpace = $this->_getNameSpaces(); $nameSpace = $this->_getNameSpaces();
$fetchedAllInOneGo = false; $fetchedAllInOneGo = false;
$subscribedFoldersForCache = $foldersNameSpace = array();
//error_log(__METHOD__.__LINE__.array2string($nameSpace)); //error_log(__METHOD__.__LINE__.array2string($nameSpace));
if (is_array($nameSpace)) if (is_array($nameSpace))
{ {
@ -2653,7 +2655,7 @@ class emailadmin_imapbase
$rv = false; $rv = false;
foreach ($haystack as $k => $v) 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; return $rv;
} }
@ -2663,7 +2665,7 @@ class emailadmin_imapbase
* *
* Helper function to sort folder-objects by displayname * Helper function to sort folder-objects by displayname
* @param object $a * @param object $a
* @param object $b, array of folderobjects * @param object $b array of folderobjects
* @return int expect values (0, 1 or -1) * @return int expect values (0, 1 or -1)
*/ */
function sortByDisplayName($a,$b) function sortByDisplayName($a,$b)
@ -2677,7 +2679,7 @@ class emailadmin_imapbase
* *
* Helper function to sort folder-objects by auto Folder Position * Helper function to sort folder-objects by auto Folder Position
* @param object $a * @param object $a
* @param object $b, array of folderobjects * @param object $b array of folderobjects
* @return int expect values (0, 1 or -1) * @return int expect values (0, 1 or -1)
*/ */
function sortByAutoFolderPos($a,$b) 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 (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 // if there are children fetch them
//echo $mbx[$mbxkeys[0]]['MAILBOX']."<br>"; //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'].($mbx[$mbxkeys[0]]['MAILBOX'] == $prefix ? '':$delimiter),2,false);
//$buff = $this->icServer->getMailboxes($mbx[$mbxkeys[0]]['MAILBOX'],2,false); //$buff = $this->icServer->getMailboxes($mbx[$mbxkeys[0]]['MAILBOX'],2,false);
//_debug_array($buff); //_debug_array($buff);
@ -2778,8 +2780,8 @@ class emailadmin_imapbase
/** /**
* _getSpecialUseFolder * _getSpecialUseFolder
* abstraction layer for getDraftFolder, getTemplateFolder, getTrashFolder and getSentFolder * abstraction layer for getDraftFolder, getTemplateFolder, getTrashFolder and getSentFolder
* @param string $type the type to fetch (Drafts|Template|Trash|Sent) * @param string $_type the type to fetch (Drafts|Template|Trash|Sent)
* @param boolean $_checkexistance, trigger check for existance * @param boolean $_checkexistance trigger check for existance
* @param boolean& $created =null on return true: if folder was just created, false if not * @param boolean& $created =null on return true: if folder was just created, false if not
* @return mixed string or false * @return mixed string or false
*/ */
@ -2870,7 +2872,7 @@ class emailadmin_imapbase
/** /**
* getDraftFolder wrapper for _getSpecialUseFolder Type Drafts * 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 * @return mixed string or false
*/ */
function getJunkFolder($_checkexistance=TRUE) function getJunkFolder($_checkexistance=TRUE)
@ -2880,7 +2882,7 @@ class emailadmin_imapbase
/** /**
* getDraftFolder wrapper for _getSpecialUseFolder Type Drafts * 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 * @return mixed string or false
*/ */
function getDraftFolder($_checkexistance=TRUE) function getDraftFolder($_checkexistance=TRUE)
@ -2890,7 +2892,7 @@ class emailadmin_imapbase
/** /**
* getTemplateFolder wrapper for _getSpecialUseFolder Type Template * 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 * @return mixed string or false
*/ */
function getTemplateFolder($_checkexistance=TRUE) function getTemplateFolder($_checkexistance=TRUE)
@ -2900,7 +2902,7 @@ class emailadmin_imapbase
/** /**
* getTrashFolder wrapper for _getSpecialUseFolder Type Trash * 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 * @return mixed string or false
*/ */
function getTrashFolder($_checkexistance=TRUE) function getTrashFolder($_checkexistance=TRUE)
@ -2910,7 +2912,7 @@ class emailadmin_imapbase
/** /**
* getSentFolder wrapper for _getSpecialUseFolder Type Sent * 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 * @return mixed string or false
*/ */
function getSentFolder($_checkexistance=TRUE) function getSentFolder($_checkexistance=TRUE)
@ -2920,7 +2922,7 @@ class emailadmin_imapbase
/** /**
* getOutboxFolder wrapper for _getSpecialUseFolder Type Outbox * 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 * @return mixed string or false
*/ */
function getOutboxFolder($_checkexistance=TRUE) 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 * 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 string $_folderName folder to perform the check on
* @param boolean $_checkexistance, trigger check for existance * @param boolean $_checkexistance trigger check for existance
* @return boolean * @return boolean
*/ */
function isSentFolder($_folderName, $_checkexistance=TRUE) 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 * 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 string $_folderName folder to perform the check on
* @param boolean $_checkexistance, trigger check for existance * @param boolean $_checkexistance trigger check for existance
* @return boolean * @return boolean
*/ */
function isOutbox($_folderName, $_checkexistance=TRUE) 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 * 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 string $_folderName folder to perform the check on
* @param boolean $_checkexistance, trigger check for existance * @param boolean $_checkexistance trigger check for existance
* @return boolean * @return boolean
*/ */
function isDraftFolder($_folderName, $_checkexistance=TRUE) 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 * 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 string $_folderName folder to perform the check on
* @param boolean $_checkexistance, trigger check for existance * @param boolean $_checkexistance trigger check for existance
* @return boolean * @return boolean
*/ */
function isTrashFolder($_folderName, $_checkexistance=TRUE) 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 * 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 string $_folderName folder to perform the check on
* @param boolean $_checkexistance, trigger check for existance * @param boolean $_checkexistance trigger check for existance
* @return boolean * @return boolean
*/ */
function isTemplateFolder($_folderName, $_checkexistance=TRUE) function isTemplateFolder($_folderName, $_checkexistance=TRUE)
@ -3049,8 +3051,8 @@ class emailadmin_imapbase
/** /**
* folderExists checks for existance of a given folder * folderExists checks for existance of a given folder
* @param string $_foldername, folder to perform the check on * @param string $_folder folder to perform the check on
* @param boolean $_forceCheck, trigger check for existance on icServer * @param boolean $_forceCheck trigger check for existance on icServer
* @return mixed string or false * @return mixed string or false
*/ */
function folderExists($_folder, $_forceCheck=false) function folderExists($_folder, $_forceCheck=false)
@ -3145,7 +3147,6 @@ class emailadmin_imapbase
function deleteMessages($_messageUID, $_folder=NULL, $_forceDeleteMethod='no') function deleteMessages($_messageUID, $_folder=NULL, $_forceDeleteMethod='no')
{ {
//error_log(__METHOD__.' ('.__LINE__.') '.'->'.array2string($_messageUID).','.array2string($_folder).', '.$_forceDeleteMethod); //error_log(__METHOD__.' ('.__LINE__.') '.'->'.array2string($_messageUID).','.array2string($_folder).', '.$_forceDeleteMethod);
$msglist = '';
$oldMailbox = ''; $oldMailbox = '';
if (is_null($_folder) || empty($_folder)) $_folder = $this->sessionData['mailbox']; if (is_null($_folder) || empty($_folder)) $_folder = $this->sessionData['mailbox'];
if (empty($_messageUID)) if (empty($_messageUID))
@ -3183,13 +3184,13 @@ class emailadmin_imapbase
case "move_to_trash": case "move_to_trash":
//error_log(__METHOD__.' ('.__LINE__.') '); //error_log(__METHOD__.' ('.__LINE__.') ');
$updateCache = true; $updateCache = true;
if(!empty($trashFolder)); { if(!empty($trashFolder)) {
if (self::$debug) error_log(__METHOD__.' ('.__LINE__.') '.implode(' : ', $_messageUID)); if (self::$debug) error_log(__METHOD__.' ('.__LINE__.') '.implode(' : ', $_messageUID));
if (self::$debug) error_log(__METHOD__.' ('.__LINE__.') '."$trashFolder <= $_folder / ". $this->sessionData['mailbox']); if (self::$debug) error_log(__METHOD__.' ('.__LINE__.') '."$trashFolder <= $_folder / ". $this->sessionData['mailbox']);
// copy messages // copy messages
try 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) catch (Exception $e)
{ {
@ -3347,7 +3348,7 @@ class emailadmin_imapbase
} }
try try
{ {
foreach($messageUIDs as $k => $uids) foreach($messageUIDs as &$uids)
{ {
if ($uids==='all') if ($uids==='all')
{ {
@ -3468,9 +3469,8 @@ class emailadmin_imapbase
*/ */
function moveMessages($_foldername, $_messageUID, $deleteAfterMove=true, $currentFolder = Null, $returnUIDs = false, $_sourceProfileID = Null, $_targetProfileID = Null) 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(); $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 (empty($_messageUID))
{ {
if (self::$debug) error_log(__METHOD__." no Message(s): ".implode(',',$_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(); $retUid = new Horde_Imap_Client_Ids();
// we copy chunks of 5 to avoid too much memory and/or server stress // 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 // 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++; $c++;
$flags = $_headerObject->getFlags(); //unseen status seems to be lost when retrieving the full message $flags = $_headerObject->getFlags(); //unseen status seems to be lost when retrieving the full message
$date = $_headerObject->getImapDate(); $date = $_headerObject->getImapDate();
@ -3578,7 +3578,6 @@ class emailadmin_imapbase
{ {
error_log(__METHOD__.' ('.__LINE__.') '."Copying to Folder $_foldername failed! Error:".$e->getMessage()); error_log(__METHOD__.' ('.__LINE__.') '."Copying to Folder $_foldername failed! Error:".$e->getMessage());
throw new egw_exception("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': case 'BASE64':
// use imap_base64 to decode, not any longer, as it is strict, and fails if it encounters invalid chars // use imap_base64 to decode, not any longer, as it is strict, and fails if it encounters invalid chars
return base64_decode($_mimeMessage); return base64_decode($_mimeMessage);
break;
case 'QUOTED-PRINTABLE': case 'QUOTED-PRINTABLE':
// use imap_qprint to decode // use imap_qprint to decode
return quoted_printable_decode($_mimeMessage); return quoted_printable_decode($_mimeMessage);
break;
case 'WEDONTKNOWTHEENCODING': case 'WEDONTKNOWTHEENCODING':
// try base64 // try base64
$r = base64_decode($_mimeMessage); $r = base64_decode($_mimeMessage);
@ -3779,7 +3778,6 @@ class emailadmin_imapbase
default: default:
// it is either not encoded or we don't know about it // it is either not encoded or we don't know about it
return $_mimeMessage; return $_mimeMessage;
break;
} }
} }
@ -3789,7 +3787,7 @@ class emailadmin_imapbase
* a wrapper for multipartmixed * a wrapper for multipartmixed
* @param string/int $_uid the messageuid, * @param string/int $_uid the messageuid,
* @param Horde_Mime_Part $_structure structure for parsing * @param Horde_Mime_Part $_structure structure for parsing
* @param string $_htmlMode, how to display a message, html, plain text, ... * @param string $_htmlMode how to display a message, html, plain text, ...
* @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek * @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek
* @return array containing the desired part * @return array containing the desired part
*/ */
@ -3919,8 +3917,8 @@ class emailadmin_imapbase
* Get part of the message, if its stucture is indicating its of multipart mixed style * Get part of the message, if its stucture is indicating its of multipart mixed style
* *
* @param int $_uid the messageuid, * @param int $_uid the messageuid,
* @param Horde_Mime_Part $_structure='', if given use structure for parsing * @param Horde_Mime_Part $_structure = '' if given use structure for parsing
* @param string $_htmlMode, how to display a message, html, plain text, ... * @param string $_htmlMode how to display a message, html, plain text, ...
* @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek * @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek
* @return array containing the desired part * @return array containing the desired part
*/ */
@ -4014,7 +4012,7 @@ class emailadmin_imapbase
if($part->getSubType() == 'rfc822' || $part->getDisposition() == 'attachment') if($part->getSubType() == 'rfc822' || $part->getDisposition() == 'attachment')
{ {
$skipParts[$mime_id.'.0'] = $mime_type; $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)); //error_log(__METHOD__.' ('.__LINE__.') '.' Uid:'.$_uid.' Part:'.$mime_id.':'.array2string($skipParts));
//break 2; //break 2;
} }
@ -4033,8 +4031,8 @@ class emailadmin_imapbase
* get part of the message, if its stucture is indicating its of multipart related style * get part of the message, if its stucture is indicating its of multipart related style
* a wrapper for multipartmixed * a wrapper for multipartmixed
* @param string/int $_uid the messageuid, * @param string/int $_uid the messageuid,
* @param Horde_Mime_Part $_structure, if given use structure for parsing * @param Horde_Mime_Part $_structure if given use structure for parsing
* @param string $_htmlMode, how to display a message, html, plain text, ... * @param string $_htmlMode how to display a message, html, plain text, ...
* @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek * @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek
* @return array containing the desired part * @return array containing the desired part
*/ */
@ -4105,7 +4103,7 @@ class emailadmin_imapbase
* Get Body from message * Get Body from message
* *
* @param int $_uid the messageuid * @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 string $_htmlMode how to display a message: 'html_only', 'always_display', 'only_if_no_text' or ''
* @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek * @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek
* @param boolean $_stream = false true return a stream, false return string * @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']; if ($method == 'REPLY') $event['title'] = $oldevent[$eventid[0]]['title'];
} }
// we prepare the message // we prepare the message
$details = $calboupdate->_get_event_details($event,$action,$event_arr); $details = $calboupdate->_get_event_details($event,'',$event_arr=array());
$details['olddate']=$olddate; $details['olddate']=$olddate;
//_debug_array($_structure); //_debug_array($_structure);
list($subject,$info) = $calboupdate->get_update_message($event, $method !='REPLY'); list($subject,$info) = $calboupdate->get_update_message($event, $method !='REPLY');
@ -4235,8 +4233,8 @@ class emailadmin_imapbase
* Get Body of message * Get Body of message
* *
* @param int $_uid the messageuid, * @param int $_uid the messageuid,
* @param string $_htmlOptions, how to display a message, html, plain text, ... * @param string $_htmlOptions how to display a message, html, plain text, ...
* @param string $_partID=null , the partID, may be omitted * @param string $_partID = null the partID, may be omitted
* @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 boolean $_preserveSeen flag to preserve the seenflag by using body.peek * @param boolean $_preserveSeen flag to preserve the seenflag by using body.peek
* @param string $_folder folder to work on * @param string $_folder folder to work on
@ -4377,7 +4375,7 @@ class emailadmin_imapbase
{ {
if (!isset($singleBodyPart['body'])) { if (!isset($singleBodyPart['body'])) {
$buff = self::normalizeBodyParts($singleBodyPart); $buff = self::normalizeBodyParts($singleBodyPart);
foreach ((array)$buff as $val) $body2return[] = $val; foreach ((array)$buff as $val) { $body2return[] = $val;}
continue; continue;
} }
$body2return[] = $singleBodyPart; $body2return[] = $singleBodyPart;
@ -4475,7 +4473,7 @@ class emailadmin_imapbase
if (!$preserveHTML) if (!$preserveHTML)
{ {
// filter only the 'body', as we only want that part, if we throw away the html // 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]) if ($matches[2])
{ {
$hasOther = true; $hasOther = true;
@ -4486,7 +4484,7 @@ class emailadmin_imapbase
else else
{ {
// htmLawed filter only the 'body' // 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]) if ($matches[2])
{ {
$hasOther = true; $hasOther = true;
@ -4500,7 +4498,7 @@ class emailadmin_imapbase
if ($hasOther && $preserveHTML) $newBody = $matches[1]. $newBody. $matches[3]; if ($hasOther && $preserveHTML) $newBody = $matches[1]. $newBody. $matches[3];
} }
//error_log(__METHOD__.' ('.__LINE__.') '.' after purify:'.$newBody); //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); //error_log(__METHOD__.' ('.__LINE__.') '.' after convertHTMLToText:'.$newBody);
if ($preserveHTML==false) $newBody = nl2br($newBody); // we need this, as htmLawed removes \r\n 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 $mailClass->getCleanHTML($newBody,false,$preserveHTML); // remove stuff we regard as unwanted
@ -4542,7 +4540,7 @@ class emailadmin_imapbase
$s=explode(" ", $line); $s=explode(" ", $line);
$line = ""; $line = "";
$linecnt = 0; $linecnt = 0;
foreach ($s as $k=>$v) { foreach ($s as &$v) {
$cnt = strlen($v); $cnt = strlen($v);
// only break long words within the wordboundaries, // 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 // 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, 'ids' => $uidsToFetch,
)); ));
if (is_object($headersNew)) { if (is_object($headersNew)) {
foreach($headersNew as $id=>$_headerObject) { foreach($headersNew as &$_headerObject) {
$env = $_headerObject->getEnvelope(); $env = $_headerObject->getEnvelope();
//_debug_array($envFields->singleFields()); //_debug_array($envFields->singleFields());
foreach ($envFields->singleFields() as $e => $v) $singleFields = $envFields->singleFields();
foreach ($singleFields as &$v)
{ {
switch ($v) switch ($v)
{ {
@ -4768,7 +4767,7 @@ class emailadmin_imapbase
if (empty($_folder)) $_folder = ($this->sessionData['mailbox']? $this->sessionData['mailbox'] : $this->icServer->getCurrentMailbox()); 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"); //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)])) 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"); //error_log(__METHOD__.' ('.__LINE__.') '." Using Cache for raw Header $_uid, $_partID in Folder $_folder");
@ -4793,7 +4792,7 @@ class emailadmin_imapbase
'ids' => $uidsToFetch, 'ids' => $uidsToFetch,
)); ));
if (is_object($headersNew)) { if (is_object($headersNew)) {
foreach($headersNew as $id=>$_headerObject) { foreach($headersNew as &$_headerObject) {
$retValue = $_headerObject->getHeaderText(); $retValue = $_headerObject->getHeaderText();
if ($_partID != '') if ($_partID != '')
{ {
@ -4809,13 +4808,13 @@ class emailadmin_imapbase
} }
} }
$rawHeaders[$this->icServer->ImapServerId][(string)$_folder][$_uid][(empty($_partID)?'NIL':$_partID)]=$retValue; $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; return $retValue;
} }
/** /**
* getStyles - extracts the styles from the given bodyparts * 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 * @return string a preformatted string with the mails converted to text
*/ */
static function &getStyles($_bodyParts) static function &getStyles($_bodyParts)
@ -4836,7 +4835,7 @@ class emailadmin_imapbase
); );
$ct = 0; $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) if ($ct>0)
{ {
//error_log(__METHOD__.' ('.__LINE__.') '.array2string($newStyle[0])); //error_log(__METHOD__.' ('.__LINE__.') '.array2string($newStyle[0]));
@ -4913,7 +4912,7 @@ class emailadmin_imapbase
'ids' => $uidsToFetch, 'ids' => $uidsToFetch,
)); ));
if (is_object($headersNew)) { if (is_object($headersNew)) {
foreach($headersNew as $id=>$_headerObject) { foreach($headersNew as &$_headerObject) {
$body = $_headerObject->getFullMsg(); $body = $_headerObject->getFullMsg();
if ($_partID != '') if ($_partID != '')
{ {
@ -5019,7 +5018,7 @@ class emailadmin_imapbase
if ($mime_type=='message/rfc822' && $_partID!=$mime_id) if ($mime_type=='message/rfc822' && $_partID!=$mime_id)
{ {
//error_log(__METHOD__.' ('.__LINE__.') '.' Uid:'.$uid.'->'.$mime_id.':'.array2string($part->contentTypeMap())); //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') if (empty($partDisposition) && $partPrimaryType != 'multipart' && $partPrimaryType != 'text')
{ {
@ -5444,7 +5443,7 @@ class emailadmin_imapbase
//$messageid = true; // for debug reasons only //$messageid = true; // for debug reasons only
if ($messageid === true || empty($messageid)) // try to figure out the message uid 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 ($list)
{ {
if (self::$debug) error_log(__METHOD__.' ('.__LINE__.') '.' MessageUid:'.$messageid.' but found:'.array2string($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']); fwrite($tmpfile,$headdata.$mailcontent['message']);
fclose($tmpfile); fclose($tmpfile);
} }
foreach($mailcontent['attachments'] as $tmpattach => $tmpval) foreach($mailcontent['attachments'] as &$tmpval)
{ {
$attachedMessages[] = $tmpval; $attachedMessages[] = $tmpval;
} }
@ -5657,7 +5656,7 @@ class emailadmin_imapbase
* @param array $rfcAddressArray an addressarray as provided by mail retieved via egw_pear.... * @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 * @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)); //error_log(__METHOD__.' ('.__LINE__.') '.array2string($rfcAddressArray));
$returnAddr =''; $returnAddr ='';
@ -5714,11 +5713,10 @@ class emailadmin_imapbase
*/ */
function merge($content,$ids,$mimetype='') function merge($content,$ids,$mimetype='')
{ {
$contacts = new addressbook_bo();
$mergeobj = new addressbook_merge(); $mergeobj = new addressbook_merge();
if (empty($mimetype)) $mimetype = (strlen(strip_tags($content)) == strlen($content) ?'text/plain':'text/html'); 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($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)); 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; return $rv;
@ -6312,7 +6310,7 @@ class emailadmin_imapbase
$matches = array(); $matches = array();
preg_match_all("/[\w\.,-.,_.,0-9.]+@[\w\.,-.,_.,0-9.]+/",$addresses,$matches); preg_match_all("/[\w\.,-.,_.,0-9.]+@[\w\.,-.,_.,0-9.]+/",$addresses,$matches);
//error_log(__METHOD__.__LINE__.array2string($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]); $addresses = implode(',',$matches[0]);
//error_log(__METHOD__.__LINE__.array2string($addresses)); //error_log(__METHOD__.__LINE__.array2string($addresses));
$ret = $rfc822->parseAddressList($addresses, $default_domain ? array('default_domain' => $default_domain) : array()); $ret = $rfc822->parseAddressList($addresses, $default_domain ? array('default_domain' => $default_domain) : array());
@ -6359,22 +6357,8 @@ class emailadmin_imapbase
*/ */
function addAccount($_hookValues) function addAccount($_hookValues)
{ {
error_log(__METHOD__.' ('.__LINE__.') '.' NOT DONE JET!'); error_log(__METHOD__.' ('.__LINE__.') '.' NOT DONE YET!' . ' hookValue = '. $_hookValues);
//$_profile_id=????
//$icServer = emailadmin_account::read($_profile_id)->imapServer();
//$ogServer = emailadmin_account::read($_profile_id)->smtpServer();
/*
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) function deleteAccount($_hookValues)
{ {
error_log(__METHOD__.' ('.__LINE__.') '.' NOT DONE JET!'); error_log(__METHOD__.' ('.__LINE__.') '.' NOT DONE YET!' . ' hookValue = '. $_hookValues);
//$_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
}
if(($ogServer instanceof emailadmin_smtp)) {
$ogServer->deleteAccount($_hookValues);
}
*/
} }
/** /**
@ -6415,18 +6385,7 @@ class emailadmin_imapbase
*/ */
function updateAccount($_hookValues) function updateAccount($_hookValues)
{ {
error_log(__METHOD__.' ('.__LINE__.') '.' NOT DONE JET!'); error_log(__METHOD__.' ('.__LINE__.') '.' NOT DONE YET!' . ' hookValue = '. $_hookValues);
//$_profile_id=????
//$icServer = emailadmin_account::read($_profile_id)->imapServer();
//$ogServer = emailadmin_account::read($_profile_id)->smtpServer();
/*
if(($icServer instanceof defaultimap)) {
$icServer->updateAccount($_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(); link.dom_id = 'temp_'+egw.uid();
} }
// Icon should be in registry // Icon should be in registry
if(typeof link.icon == 'undefined') if(!link.icon)
{ {
link.icon = egw.link_get_registry(link.app,'icon'); link.icon = egw.link_get_registry(link.app,'icon');
// No icon, try by mime type - different place for un-saved entries // 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 // 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 || ''; link.title = link.id.name || '';
} }

View File

@ -1131,33 +1131,29 @@ class infolog_bo
* *
* @author Cornelius Weiss <nelius@cwtech.de> * @author Cornelius Weiss <nelius@cwtech.de>
* @todo search if infolog with from and subject allready exists ->appned body & inform user * @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 $_subject
* @param string $_message * @param string $_message
* @param array $_attachments * @param array $_attachments
* @param string $_date * @param string $_date
* @return array $content array for uiinfolog * @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($_addresses as $address)
foreach ((array)$address_array as $address)
{ {
$email[] = $emailadr = sprintf('%s@%s', $names[] = $address['name'];
trim($address->mailbox), $emails[] =$address['email'];
trim($address->host));
$name[] = !empty($address->personal) ? $address->personal : $emailadr;
} }
// 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'; $type = isset($this->enums['type']['email']) ? 'email' : 'note';
$status = isset($this->status['defaults'][$type]) ? $this->status['defaults'][$type] : 'done'; $status = isset($this->status['defaults'][$type]) ? $this->status['defaults'][$type] : 'done';
$info = array( $info = array(
'info_id' => 0, 'info_id' => 0,
'info_type' => $type, 'info_type' => $type,
'info_from' => implode(', ',$name), 'info_from' => implode(', ',$names),
'info_addr' => implode(', ',$email), 'info_addr' => implode(', ',$emails),
'info_subject' => $_subject, 'info_subject' => $_subject,
'info_des' => $_message, 'info_des' => $_message,
'info_startdate' => egw_time::server2user($_date), 'info_startdate' => egw_time::server2user($_date),
@ -1174,7 +1170,7 @@ class infolog_bo
// find the addressbookentry to link with // find the addressbookentry to link with
$addressbook = new addressbook_bo(); $addressbook = new addressbook_bo();
$contacts = array(); $contacts = array();
foreach ($email as $mailadr) foreach ($emails as $mailadr)
{ {
$contacts = array_merge($contacts,(array)$addressbook->search( $contacts = array_merge($contacts,(array)$addressbook->search(
array( array(
@ -1202,12 +1198,11 @@ class infolog_bo
{ {
foreach ($_attachments as $attachment) foreach ($_attachments as $attachment)
{ {
$is_vfs = false; if($attachment['egw_data'])
if (parse_url($attachment['tmp_name'],PHP_URL_SCHEME) == 'vfs' && egw_vfs::is_readable($attachment['tmp_name']))
{ {
$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); 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 unset($location); // not used, but part of hook signature
return true; 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, 'admin' => True,
'hook_view' => True, 'hook_view' => True,
'writeLangFile' => True, 'writeLangFile' => True,
'import_mail' => True, 'mail_import' => True
); );
/** /**
* reference to the infolog preferences of the user * reference to the infolog preferences of the user
@ -2482,185 +2482,25 @@ class infolog_ui
/** /**
* imports a mail as infolog * 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 array $mailContent = null content of mail
* @param string $_to_emailAddress * @return array
* @param string $_subject
* @param string $_body
* @param array $_attachments
* @param string $_date
* @param resource $_rawMail
*/ */
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']; // It would get called from compose as a popup with egw_data
$partid = $_GET['part']; if (!is_array($mailContent) && ($_GET['egw_data']))
$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']))
{ {
// rowid holds all needed information: server, folder, uid, etc. // get the mail raw data
$rowID = $_GET['rowid']; egw_link::get_data ($_GET['egw_data']);
$hA = mail_ui::splitRowID($rowID); return false;
$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,
);
} }
//_debug_array($_to_emailAddress); return $this->edit($this->bo->import_mail($mailContent['addresses'],
$toaddr = array(); $mailContent['subject'],
foreach(array('to','cc','bcc') as $x) $mailContent['message'],
{ $mailContent['attachments'],
if (is_array($_to_emailAddress[$x]) && !empty($_to_emailAddress[$x])) $mailContent['date']));
{
$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!'));
} }
/** /**

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']['pm_custom_app_icons'] = 'infolog.infolog_bo.pm_icons';
$setup_info['infolog']['hooks']['timesheet_set'] = 'infolog.infolog_ui.timesheet_set'; $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']['calendar_set'] = 'infolog.infolog_ui.calendar_set';
$setup_info['infolog']['hooks']['mail_import'] = 'infolog_hooks::mail_import';
/* Dependencies for this app to work */ /* Dependencies for this app to work */
$setup_info['infolog']['depends'][] = array( $setup_info['infolog']['depends'][] = array(

View File

@ -163,6 +163,14 @@ class mail_compose
'hint' => 'check to save as trackerentry on send', 'hint' => 'check to save as trackerentry on send',
'onExecute' => 'javaScript:app.mail.compose_setToggle' '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( 'disposition' => array(
'caption' => 'Notification', 'caption' => 'Notification',
'icon' => 'high', '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 if ($content['mimeType'] == 'html' && html::htmlarea_availible()===false)
//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)
{ {
$_content['mimeType'] = $content['mimeType'] = 'plain'; $_content['mimeType'] = $content['mimeType'] = 'plain';
$content['body'] = $this->convertHTMLToText($content['body']); $content['body'] = $this->convertHTMLToText($content['body']);
$readonlys['mimeType'] = true;
} }
// is a certain signature requested? // is a certain signature requested?
// only the following values are supported (and make sense) // only the following values are supported (and make sense)
@ -1290,7 +1295,7 @@ class mail_compose
$content['to'] = self::resolveEmailAddressList($content['to']); $content['to'] = self::resolveEmailAddressList($content['to']);
//error_log(__METHOD__.__LINE__.array2string($content)); //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]') 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(); $response = egw_json_response::get();
$success = true; $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['cc'])) $mailaddresses['cc'] = $this->sessionData['cc'];
if (is_array($this->sessionData['bcc'])) $mailaddresses['bcc'] = $this->sessionData['bcc']; if (is_array($this->sessionData['bcc'])) $mailaddresses['bcc'] = $this->sessionData['bcc'];
if (!empty($mailaddresses)) $mailaddresses['from'] = $GLOBALS['egw']->translation->decodeMailHeader($fromAddress); 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') { if ($_formData['to_infolog'] == 'on' || $_formData['to_tracker'] == 'on' || $_formData['to_calendar'] == 'on' )
$uiinfolog = new infolog_ui(); {
$uiinfolog->import_mail( 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, $mailaddresses,
$this->sessionData['subject'], $this->sessionData['subject'],
$this->convertHTMLToText($this->sessionData['body']), $this->convertHTMLToText($this->sessionData['body']),
$this->sessionData['attachments'], $this->sessionData['attachments'],
false, // date 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']
);
} }
*/ // only clean up temp-files, if we dont need them for mail_integration::integrate
elseif(is_array($this->sessionData['attachments']))
{
if(is_array($this->sessionData['attachments'])) {
foreach($this->sessionData['attachments'] as $value) { foreach($this->sessionData['attachments'] as $value) {
if (!empty($value['file']) && parse_url($value['file'],PHP_URL_SCHEME) != 'vfs') { // happens when forwarding mails 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']); 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 // Add up to 5 matching mailing lists
if($include_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"]) if ($_GET["resetConnection"])
{ {
unset($_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); emailadmin_imapbase::unsetCachedObjects(self::$icServerID);
} }
try { 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()); 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)); //error_log(__METHOD__.__LINE__.array2string($this->mail_bo->icServer));
@ -1224,8 +1224,7 @@ class mail_ui
'hint' => 'Save as InfoLog', 'hint' => 'Save as InfoLog',
'icon' => 'infolog/navbar', 'icon' => 'infolog/navbar',
'group' => ++$group, 'group' => ++$group,
'onExecute' => 'javaScript:app.mail.mail_infolog', 'onExecute' => 'javaScript:app.mail.mail_integrate',
'url' => 'menuaction=infolog.infolog_ui.import_mail',
'popup' => egw_link::get_registry('infolog', 'add_popup'), 'popup' => egw_link::get_registry('infolog', 'add_popup'),
'allowOnMultiple' => false, 'allowOnMultiple' => false,
'toolbarDefault' => true 'toolbarDefault' => true
@ -1235,11 +1234,21 @@ class mail_ui
'hint' => 'Save as ticket', 'hint' => 'Save as ticket',
'group' => $group, 'group' => $group,
'icon' => 'tracker/navbar', 'icon' => 'tracker/navbar',
'onExecute' => 'javaScript:app.mail.mail_tracker', 'onExecute' => 'javaScript:app.mail.mail_integrate',
'url' => 'menuaction=tracker.tracker_ui.import_mail',
'popup' => egw_link::get_registry('tracker', 'add_popup'), 'popup' => egw_link::get_registry('tracker', 'add_popup'),
'mail_import' => $GLOBALS['egw']->hooks->single(array('location' => 'mail_import'),'tracker'),
'allowOnMultiple' => false, '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( 'print' => array(
'caption' => 'Print', 'caption' => 'Print',
'group' => ++$group, 'group' => ++$group,
@ -3239,7 +3248,6 @@ class mail_ui
$file = $content['uploadForImport']; $file = $content['uploadForImport'];
} }
$destination = $content['FOLDER'][0]; $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 (stripos($destination,self::$delimiter)!==false) list($icServerID,$destination) = explode(self::$delimiter,$destination,2);
if ($icServerID && $icServerID != $this->mail_bo->profileID) 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 $folder = $uidA['folder']; // all messages in one set are supposed to be within the same folder
$messageID = $uidA['msgUID']; $messageID = $uidA['msgUID'];
$icServerID = $uidA['profileID']; $icServerID = $uidA['profileID'];
$rememberServerID = $this->mail_bo->profileID;
if ($icServerID && $icServerID != $this->mail_bo->profileID) if ($icServerID && $icServerID != $this->mail_bo->profileID)
{ {
//error_log(__METHOD__.__LINE__.' change Profile to ->'.$icServerID); //error_log(__METHOD__.__LINE__.' change Profile to ->'.$icServerID);
@ -4693,7 +4700,7 @@ class mail_ui
//error_log(__METHOD__.__LINE__.$uID); //error_log(__METHOD__.__LINE__.$uID);
if ($_copyOrMove=='move') 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 _action
* @param _elems _elems[0].id is the row-id * @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 app = _action.id;
var reg = '750x580'; var w_h = ['750','580']; // define a default wxh if there's no popup size registered
var w_h =reg.split('x');
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) if (typeof _elems == 'undefined' || _elems.length==0)
{ {
@ -2591,77 +2598,72 @@ app.classes.mail = AppJS.extend(
_elems.push({id:this.mail_currentlyFocussed}); _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 url = window.egw_webserverUrl+ '/index.php?menuaction=mail.mail_integration.integrate&rowid=' + _elems[0].id + '&app='+app;
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]));
},
/** /**
* 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 {string} _title select app entry title
* @param _elems * @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 data = egw.dataGetUIDdata(_elems[0].id);
var reg = '780x535'; var subject = (data && typeof data.data != 'undefined')? data.data.subject : '';
var w_h =reg.split('x'); egw.json(_appCheckCallback, subject,function(_entryId){
if (typeof _elems == 'undefined' || _elems.length==0)
// 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 = []; callback: function(_buttons, _value)
_elems.push({id:this.et2.getArrayMgr("content").getEntry('mail_id') || ''}); {
if (_buttons == 'cancel') return;
if (_buttons == 'append' && _value)
{
url += '&entry_id=' + _value.id;
} }
if ((typeof _elems == 'undefined' || _elems.length==0) && this.mail_isMainWindow) egw_openWindowCentered(url,'import_mail_'+_elems[0].id,w_h[0],w_h[1]);
{ },
if (this.mail_currentlyFocussed) title: egw.lang(_title),
{ buttons: buttons||et2_dialog.BUTTONS_OK_CANCEL,
var _elems = []; value:{
_elems.push({id:this.mail_currentlyFocussed}); 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) check_app_entry('Select '+ app + ' entry', app, mail_import_hook.app_entry_method);
{
var app_registry = _action.data.event.popup;
} }
else 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 * 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 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: saving the rule failed: mail de Speichern der Regel ist fehlgeschlagen:
select all mail de Alle Auswählen 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 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 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. 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 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: saving the rule failed: mail en Saving the rule failed:
select all mail en Select all 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 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 to import into folder mail en Select file to import into Folder
select file(s) from vfs mail en Select file(s) from VFS 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"/> <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 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 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"/> <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> <menulist>
<menupopup id="priority"/> <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 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 * appname used for linking existing files to VFS
*/ */
@ -188,9 +193,10 @@ class egw_link extends solink
static function init_static( ) 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 // 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 // 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 // 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). * 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. * 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|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> * @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<br> * $file array with informations about the file in format of the etemplate file-type
* $file['name'] name of the file (no directory)<br> * $file['name'] name of the file (no directory)
* $file['type'] mine-type of the file<br> * $file['type'] mime-type of the file
* $file['tmp_name'] name of the uploaded file (incl. directory)<br> * $file['tmp_name'] name of the uploaded file (incl. directory) for self::VFS_APPNAME or
* $file['path'] path of the file on the client computer<br> * $file['egw_data'] id of egw_link::set_data() call for self::DATA_APPNAME
* $file['ip'] of the client (path and ip in $file are only needed if u want a symlink (if possible))
* @param string $remark ='' Remark to be saved with the link (defaults to '') * @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 $owner =0 Owner of the link (defaults to user)
* @param int $lastmod =0 timestamp of last modification (defaults to now=time()) * @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']); self::link($app1, $id1, $link['app'], $link['id'], $link['remark'],$link['owner'],$link['lastmod']);
continue; 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']); $link_id = self::attach_file($app1,$id1,$link['id'],$link['remark']);
} break;
else if ($link['app'] == self::VFS_LINK)
{ case self::VFS_LINK:
$link_id = self::link_file($app1,$id1, $link['id'],$link['remark']); $link_id = self::link_file($app1,$id1, $link['id'],$link['remark']);
} break;
else
{ default:
$link_id = solink::link($app1,$id1,$link['app'],$link['id'], $link_id = solink::link($app1,$id1,$link['app'],$link['id'],
$link['remark'],$link['owner'],$link['lastmod']); $link['remark'],$link['owner'],$link['lastmod']);
// notify both sides // notify both sides
if (!($no_notify&2)) self::notify('link',$link['app'],$link['id'],$app1,$id1,$link_id); 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); if (!($no_notify&1)) self::notify('link',$app1,$id1,$link['app'],$link['id'],$link_id);
break;
} }
} }
return $link_id; return $link_id;
@ -421,7 +434,7 @@ class egw_link extends solink
*/ */
static function temp_link_id($app,$id) 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 * @param array $file informations about the file in format of the etemplate file-type
* $file['name'] name of the file (no directory) * $file['name'] name of the file (no directory)
* $file['type'] mine-type of the file * $file['type'] mine-type of the file
* $file['tmp_name'] name of the uploaded file (incl. directory) * $file['tmp_name'] name of the uploaded file (incl. directory) or resource of opened file
* $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))
* @param string $comment ='' comment to add to the link * @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 * @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 $mime_type
* @param string $method * @param string $method
* @param array $params * @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 * @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; return null;
} }
array_unshift($params, $method); 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); egw_cache::setSession(__CLASS__, $id, $params);
return $id; return $id;
} }
@ -1584,6 +1597,8 @@ class egw_link extends solink
} }
$ret = call_user_func_array('ExecMethod2', $data); $ret = call_user_func_array('ExecMethod2', $data);
if (is_resource($ret)) fseek($ret, 0);
if ($return_resource != is_resource($ret)) if ($return_resource != is_resource($ret))
{ {
if ($return_resource && ($fp = fopen('php://temp', 'w'))) if ($return_resource && ($fp = fopen('php://temp', 'w')))
@ -1596,7 +1611,6 @@ class egw_link extends solink
{ {
$fp = $ret; $fp = $ret;
$ret = ''; $ret = '';
fseek($fp, 0);
while(!feof($fp)) while(!feof($fp))
{ {
$ret .= fread($fp, 8192); $ret .= fread($fp, 8192);

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB