From 035e4b32b6090f8e0723a38a64670bf62c6f3862 Mon Sep 17 00:00:00 2001 From: Klaus Leithoff Date: Mon, 29 Apr 2013 14:56:33 +0000 Subject: [PATCH] implement move7copy mails; rename folder simple renanme implemented. refresh of tree still to be done, if renaming a leaf inbetween --- mail/inc/class.mail_bo.inc.php | 57 +++++++++++++++++- mail/inc/class.mail_bopreferences.inc.php | 18 ++++-- mail/inc/class.mail_ui.inc.php | 73 +++++++++++++++++++++-- mail/js/app.js | 15 ++++- 4 files changed, 151 insertions(+), 12 deletions(-) diff --git a/mail/inc/class.mail_bo.inc.php b/mail/inc/class.mail_bo.inc.php index 7f161b8589..5a88db2b2d 100644 --- a/mail/inc/class.mail_bo.inc.php +++ b/mail/inc/class.mail_bo.inc.php @@ -1617,7 +1617,7 @@ class mail_bo $HierarchyDelimiter = $this->getHierarchyDelimiter(); $newFolderName = $parent . $HierarchyDelimiter . $folderName; } - if (self::$debug); error_log("create folder: $newFolderName"); + if (self::$debug) error_log("create folder: $newFolderName"); $rv = $this->icServer->renameMailbox($oldFolderName, $newFolderName); if ( PEAR::isError($rv) ) { if (self::$debug) error_log(__METHOD__." failed for $oldFolderName, $newFolderName with error: ".print_r($rv->message,true)); @@ -2662,6 +2662,61 @@ class mail_bo return true; // as we do not catch/examine setFlags returnValue } + /** + * move Message(s) + * + * @param string _foldername target folder + * @param mixed array/string _messageUID array of ids to flag, or 'all' + * @param boolean $deleteAfterMove - decides if a mail is moved (true) or copied (false) + * @param string $currentFolder + * @param boolean $returnUIDs - control wether or not the action called should return the new uids + * caveat: not all servers do support that + * + * @return mixed/bool true,false or new uid + */ + function moveMessages($_foldername, $_messageUID, $deleteAfterMove=true, $currentFolder = Null, $returnUIDs = false) + { + $msglist = ''; + + $deleteOptions = $GLOBALS['egw_info']["user"]["preferences"]["mail"]["deleteOptions"]; + $retUid = $this->icServer->copyMessages($_foldername, $_messageUID, (!empty($currentFolder)?$currentFolder: $this->sessionData['mailbox']), true, $returnUIDs); + if ( PEAR::isError($retUid) ) { + error_log(__METHOD__.__LINE__."Copying to Folder $_foldername failed! PEAR::Error:".array2string($retUid->message)); + throw new egw_exception("Copying to Folder $_foldername failed! PEAR::Error:".array2string($retUid->message)); + return false; + } + if ($deleteAfterMove === true) + { + $retValue = $this->icServer->deleteMessages($_messageUID, true); + if ( PEAR::isError($retValue)) + { + error_log(__METHOD__.__LINE__."Delete After Move PEAR::Error:".array2string($retValue->message)); + throw new egw_exception("Delete After Move PEAR::Error:".array2string($retValue->message)); + return false; + } + + if($deleteOptions != "mark_as_deleted") + { + $structure = egw_cache::getCache(egw_cache::INSTANCE,'email','structureCache'.trim($GLOBALS['egw_info']['user']['account_id']),$callback=null,$callback_params=array(),$expiration=60*60*1); + $cachemodified = false; + foreach ((array)$_messageUID as $k => $_uid) + { + if (isset($structure[$this->icServer->ImapServerId][(!empty($currentFolder)?$currentFolder: $this->sessionData['mailbox'])][$_uid])) + { + $cachemodified = true; + unset($structure[$this->icServer->ImapServerId][(!empty($currentFolder)?$currentFolder: $this->sessionData['mailbox'])][$_uid]); + } + } + if ($cachemodified) egw_cache::setCache(egw_cache::INSTANCE,'email','structureCache'.trim($GLOBALS['egw_info']['user']['account_id']),$structure,$expiration=60*60*1); + + // delete the messages finaly + $this->icServer->expunge(); + } + } + //error_log(__METHOD__.__LINE__.array2string($retUid)); + return ($returnUIDs ? $retUid : true); + } + /** * Helper function to handle wrong or unrecognized timezones * returns the date as it is parseable by strtotime, or current timestamp if everything failes diff --git a/mail/inc/class.mail_bopreferences.inc.php b/mail/inc/class.mail_bopreferences.inc.php index 3c713bb2d0..f350ce4e90 100644 --- a/mail/inc/class.mail_bopreferences.inc.php +++ b/mail/inc/class.mail_bopreferences.inc.php @@ -47,7 +47,6 @@ class mail_bopreferences extends mail_sopreferences * constructor * * @param boolean $_restoreSession=true - */ function __construct($_restoreSession = true) { @@ -438,7 +437,15 @@ class mail_bopreferences extends mail_sopreferences parent::deleteAccountData($GLOBALS['egw_info']['user']['account_id'], $identity); } - function setProfileActive($_status, $_identity=NULL) + /** + * setProfileActive + * sets the profile given as active; updates database via parent call + * @param boolean $_status + * @param int $_identityID=NULL Identity to update. + * @param boolean $_identityOnly indicates, that the profile represented by id ($_identity) is an identity only (true), or a full mailprofile (false) + * @return void + */ + function setProfileActive($_status, $_identity=NULL, $_identityOnly=false) { $this->sessionData = array(); $this->saveSessionData(); @@ -446,11 +453,12 @@ class mail_bopreferences extends mail_sopreferences { //error_log(__METHOD__.__LINE__.' change status of Profile '.$_identity.' to '.$_status); // globals preferences add appname varname value - $GLOBALS['egw']->preferences->add('mail','ActiveProfileID',$_identity,'user'); + if (!$_identityOnly) $GLOBALS['egw']->preferences->add('mail','ActiveProfileID',$_identity,'user'); // save prefs - $GLOBALS['egw']->preferences->save_repository(true); - egw_cache::setSession('mail','activeProfileID',$_identity); + if (!$_identityOnly) $GLOBALS['egw']->preferences->save_repository(true); + if (!$_identityOnly) egw_cache::setSession('mail','activeProfileID',$_identity); } + // the parentCall only saves the database value parent::setProfileActive($GLOBALS['egw_info']['user']['account_id'], $_status, $_identity); } } diff --git a/mail/inc/class.mail_ui.inc.php b/mail/inc/class.mail_ui.inc.php index a13a8e033b..bd1496a0b3 100644 --- a/mail/inc/class.mail_ui.inc.php +++ b/mail/inc/class.mail_ui.inc.php @@ -2181,11 +2181,11 @@ blockquote[type=cite] { //error_log(__METHOD__.__LINE__.' OldFolderName:'.array2string($_folderName).' NewName:'.array2string($_newName)); if ($_folderName) { - $_folderName = $this->mail_bo->decodeEntityFolderName($_folderName); + $decodedFolderName = $this->mail_bo->decodeEntityFolderName($_folderName); $_newName = translation::convert($this->mail_bo->decodeEntityFolderName($_newName), $this->charset, 'UTF7-IMAP'); $del = $this->mail_bo->getHierarchyDelimiter(false); $oA = array(); - list($profileID,$folderName) = explode(self::$delimiter,$_folderName,2); + list($profileID,$folderName) = explode(self::$delimiter,$decodedFolderName,2); if (is_numeric($profileID)) { if ($profileID != $this->mail_bo->profileID) return; // only current connection @@ -2195,26 +2195,33 @@ blockquote[type=cite] { if (strtoupper($folderName)!= 'INBOX') { //error_log(__METHOD__.__LINE__."$folderName, $parentFolder, $_newName"); + $this->mail_bo->reopen('INBOX'); if($newFolderName = $this->mail_bo->renameFolder($folderName, $parentFolder, $_newName)) { $this->mail_bo->resetFolderObjectCache($profileID); //enforce the subscription to the newly named server, as it seems to fail for names with umlauts $rv = $this->mail_bo->subscribe($newFolderName, true); $rv = $this->mail_bo->subscribe($folderName, false); } + $this->mail_bo->reopen($newFolderName); $fS = $this->mail_bo->getFolderStatus($newFolderName,false); //error_log(__METHOD__.__LINE__.array2string($fS)); + $oA[$_folderName]['id'] = $profileID.self::$delimiter.$newFolderName; if ($fS['unseen']) { - $oA[$_folderName] = ''.$fS['shortDisplayName'].' ('.$fS['unseen'].')'; + $oA[$_folderName]['desc'] = ''.$fS['shortDisplayName'].' ('.$fS['unseen'].')'; } + else + { + $oA[$_folderName]['desc'] = $fS['shortDisplayName']; + } } } //error_log(__METHOD__.__LINE__.array2string($oA)); if ($oA) { $response = egw_json_response::get(); - $response->call('app.mail.mail_setFolderStatus',$oA,'mail'); + $response->call('app.mail.mail_setLeaf',$oA,'mail'); } } } @@ -2361,8 +2368,36 @@ blockquote[type=cite] { */ function ajax_moveMessages($_folderName, $_messageList) { - if(mail_bo::$debug); error_log(__METHOD__."->".$_folderName.':'.print_r($_messageList,true)); + if(mail_bo::$debug) error_log(__METHOD__."->".$_folderName.':'.print_r($_messageList,true)); + $_folderName = $this->mail_bo->decodeEntityFolderName($_folderName); + list($profileID,$targetFolder) = explode(self::$delimiter,$_folderName,2); + if ($_messageList=='all' || !empty($_messageList['msg'])) + { + if ($_messageList=='all') + { + // we have no folder information + $folder=null; + } + else + { + $uidA = self::splitRowID($_messageList['msg'][0]); + $folder = $uidA['folder']; // all messages in one set are supposed to be within the same folder + } + foreach($_messageList['msg'] as $rowID) + { + $hA = self::splitRowID($rowID); + $messageList[] = $hA['msgUID']; + } + + $this->mail_bo->moveMessages($targetFolder,$messageList,true,$folder); + $response = egw_json_response::get(); + $response->call('egw_refresh',lang('moved %1 message(s) from %2 to %3',count($messageList),$folder,$targetFolder),'mail'); + } + else + { + if(mail_bo::$debug) error_log(__METHOD__."-> No messages selected."); + } } /** @@ -2376,7 +2411,35 @@ blockquote[type=cite] { function ajax_copyMessages($_folderName, $_messageList) { if(mail_bo::$debug); error_log(__METHOD__."->".$_folderName.':'.print_r($_messageList,true)); + $_folderName = $this->mail_bo->decodeEntityFolderName($_folderName); + list($profileID,$targetFolder) = explode(self::$delimiter,$_folderName,2); + if ($_messageList=='all' || !empty($_messageList['msg'])) + { + if ($_messageList=='all') + { + // we have no folder information + $folder=null; + } + else + { + $uidA = self::splitRowID($_messageList['msg'][0]); + $folder = $uidA['folder']; // all messages in one set are supposed to be within the same folder + } + foreach($_messageList['msg'] as $rowID) + { + $hA = self::splitRowID($rowID); + $messageList[] = $hA['msgUID']; + } + + $this->mail_bo->moveMessages($targetFolder,$messageList,false,$folder); + $response = egw_json_response::get(); + $response->call('egw_refresh',lang('copied %1 message(s) from %2 to %3',count($messageList),$folder,$targetFolder),'mail'); + } + else + { + if(mail_bo::$debug) error_log(__METHOD__."-> No messages selected."); + } } } diff --git a/mail/js/app.js b/mail/js/app.js index c980233194..089206ffee 100644 --- a/mail/js/app.js +++ b/mail/js/app.js @@ -169,6 +169,19 @@ app.mail = AppJS.extend( for (var i in _status) ftree.setLabel(i,_status[i]);//alert(i +'->'+_status[i]); }, + /** + * mail_setLeaf, function to set the id and description for the folder given by status key + */ + mail_setLeaf: function(_status) { + //console.log('mail_setLeaf',_status); + var ftree = etemplate2.getByApplication('mail')[0].widgetContainer.getWidgetById('nm[foldertree]'); + for (var i in _status) + { + ftree.renameItem(i,_status[i]['id'],_status[i]['desc']); + //alert(i +'->'+_status[i]['id']+'+'+_status[i]['desc']); + } + }, + /** * mail_refreshMessageGrid, function to call to reread ofthe current folder */ @@ -583,7 +596,7 @@ app.mail = AppJS.extend( */ mail_copy: function(_action,_senders,_target) { //console.log(_action,_senders,_target); - var target = _action.id == 'drop_copy_mail' ? _target.id : _action.id.substr(5); + var target = _action.id == 'drop_copy_mail' ? _target.iface.id : _action.id.substr(5); var messages = this.mail_getFormData(_senders); //alert('mail_copy('+messages.msg.join(',')+' --> '+target+')'); // TODO: Write move/copy function which cares about doing the same stuff