From de5e5ba478e6ef9e15b4c23f272c46f5cfad1d2a Mon Sep 17 00:00:00 2001 From: Klaus Leithoff Date: Tue, 4 Jun 2013 15:29:53 +0000 Subject: [PATCH] use same method to cache headers as felamimail; same cache store! try to gain control about the get_row calls --- mail/inc/class.mail_bo.inc.php | 105 ++++++++++++++++++++++++++++++++- mail/inc/class.mail_ui.inc.php | 11 ++-- mail/js/app.js | 14 ++++- 3 files changed, 121 insertions(+), 9 deletions(-) diff --git a/mail/inc/class.mail_bo.inc.php b/mail/inc/class.mail_bo.inc.php index 52e786a7ed..f111302bff 100644 --- a/mail/inc/class.mail_bo.inc.php +++ b/mail/inc/class.mail_bo.inc.php @@ -1081,7 +1081,8 @@ class mail_bo $queryString = implode(',', $sortResult); // fetch the data for the selected messages if (self::$debug) $starttime = microtime(true); - $headersNew = $this->icServer->getSummary($queryString, $rByUid); + //$headersNew = $this->icServer->getSummary($queryString, $rByUid); + $headersNew = $this->_getSummary($queryString, $rByUid); if (PEAR::isError($headersNew) && empty($queryString)) { $headersNew = array(); @@ -2723,6 +2724,20 @@ class mail_bo $this->flagMessages($_flag, array_slice($_messageUID,$h),($_folder?$_folder:$this->sessionData['mailbox'])); } } + $summary = egw_cache::getCache(egw_cache::INSTANCE,'email','summaryCache'.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($summary[$this->icServer->ImapServerId][(!empty($currentFolder)?$currentFolder: $this->sessionData['mailbox'])][$_uid])) + { + $cachemodified = true; + unset($summary[$this->icServer->ImapServerId][(!empty($currentFolder)?$currentFolder: $this->sessionData['mailbox'])][$_uid]); + } + } + if ($cachemodified) + { + egw_cache::setCache(egw_cache::INSTANCE,'email','summaryCache'.trim($GLOBALS['egw_info']['user']['account_id']),$summary,$expiration=60*60*1); + } $this->sessionData['folderStatus'][$this->profileID][$this->sessionData['mailbox']]['uidValidity'] = 0; $this->saveSessionData(); @@ -2781,6 +2796,21 @@ class mail_bo $this->icServer->expunge(); } } + $summary = egw_cache::getCache(egw_cache::INSTANCE,'email','summaryCache'.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($summary[$this->icServer->ImapServerId][(!empty($currentFolder)?$currentFolder: $this->sessionData['mailbox'])][$_uid])) + { + $cachemodified = true; + unset($summary[$this->icServer->ImapServerId][(!empty($currentFolder)?$currentFolder: $this->sessionData['mailbox'])][$_uid]); + } + } + if ($cachemodified) + { + egw_cache::setCache(egw_cache::INSTANCE,'email','summaryCache'.trim($GLOBALS['egw_info']['user']['account_id']),$summary,$expiration=60*60*1); + } + //error_log(__METHOD__.__LINE__.array2string($retUid)); return ($returnUIDs ? $retUid : true); } @@ -2966,6 +2996,65 @@ class mail_bo return $structure[$this->icServer->ImapServerId][$_folder][$_uid]; } + /** + * _getSummary + * fetch the summary for the mails, requested by queryString + * @param string/int $queryString the messageuid(s), + * @param boolean $byUid=true, is the messageuid given by UID or ID + * @param boolean $_ignoreCache=false, use or disregard cache, when fetching + * @param string $_folder='', if given search within that folder for the given $queryString, else use sessionData['mailbox'], or servers getCurrentMailbox + * @return array an array with the mail headers requested + */ + function _getSummary($queryString, $byUid=true, $_ignoreCache=false, $_folder = '') + { + static $summary; + if (empty($_folder)) $_folder = ($this->sessionData['mailbox']? $this->sessionData['mailbox'] : $this->icServer->getCurrentMailbox()); + //error_log(__METHOD__.__LINE__.'User:'.trim($GLOBALS['egw_info']['user']['account_id'])." UID: $_uid, ".$this->icServer->ImapServerId.','.$_folder); + if (is_null($summary)) $summary = egw_cache::getCache(egw_cache::INSTANCE,'email','summaryCache'.trim($GLOBALS['egw_info']['user']['account_id']),$callback=null,$callback_params=array(),$expiration=60*60*1); + $_uids = explode(',', $queryString); + $uidsCached = (is_array($summary[$this->icServer->ImapServerId][$_folder])?array_keys($summary[$this->icServer->ImapServerId][$_folder]):array()); + $toFetch = array_diff($_uids,(array)$uidsCached); + if (!empty($toFetch)) + { + //error_log(__METHOD__.__LINE__.':'.$GLOBALS['egw_info']['user']['account_id'].'::'.$this->icServer->ImapServerId.'::'. $_folder.':QS:'.$queryString.'->'.array2string(array_keys((array)$summary[$this->icServer->ImapServerId][$_folder]))); + error_log(__METHOD__.__LINE__.' fetch Summary for'.':'.$GLOBALS['egw_info']['user']['account_id'].'::'.$this->icServer->ImapServerId.'::'. $_folder.'::for headers with uids ToFetch:'.implode(',',$toFetch)); + if (!isset($summary[$this->icServer->ImapServerId])) $summary[$this->icServer->ImapServerId]=array(); + if (!isset($summary[$this->icServer->ImapServerId][$_folder])) $summary[$this->icServer->ImapServerId][$_folder]=array(); + $result = $this->icServer->getSummary(implode(',',$toFetch), $byUid); + foreach ($result as $sum) + { + //error_log(__METHOD__.__LINE__.'::'.$sum['UID'].':'.$sum['SUBJECT']); + $summary[$this->icServer->ImapServerId][$_folder][$sum['UID']]=$sum; + } + } + foreach ($_uids as $_uid) + { + $fetched=false; + //error_log(__METHOD__.__LINE__." UID: $_uid, ".$this->icServer->ImapServerId.','.$_folder.'->'.array2string($summary[$this->icServer->ImapServerId][$_folder][$_uid])); + if (isset($summary[$this->icServer->ImapServerId]) && !empty($summary[$this->icServer->ImapServerId]) && + isset($summary[$this->icServer->ImapServerId][$_folder]) && !empty($summary[$this->icServer->ImapServerId][$_folder]) && + isset($summary[$this->icServer->ImapServerId][$_folder][$_uid]) && !empty($summary[$this->icServer->ImapServerId][$_folder][$_uid])) + { + if ($_ignoreCache===false) + { + //error_log(__METHOD__.__LINE__.' Using cache for structure on Server:'.$this->icServer->ImapServerId.' for uid:'.$_uid." in Folder:".$_folder.'->'.array2string($structure[$this->icServer->ImapServerId][$_folder][$_uid])); + $rv[] = $summary[$this->icServer->ImapServerId][$_folder][$_uid]; + $fetched=true; + } + } + if ($fetched==false) + { + error_log(__METHOD__.__LINE__.' fetch Summary for Header of Mail with:'.$_uid); + $result = $this->icServer->getSummary($_uid, $byUid); + $summary[$this->icServer->ImapServerId][$_folder][$_uid] = $result[0]; + $rv[] = $summary[$this->icServer->ImapServerId][$_folder][$_uid]; + } + } + egw_cache::setCache(egw_cache::INSTANCE,'email','summaryCache'.trim($GLOBALS['egw_info']['user']['account_id']),$summary,$expiration=60*60*1); + //error_log(__METHOD__.__LINE__.' Using query for summary on Server:'.$this->icServer->ImapServerId.' for uid:'.$_uid." in Folder:".$_folder.'->'.array2string($structure[$this->icServer->ImapServerId][$_folder][$_uid])); + return $rv; + } + /** * _getSubStructure * fetch the substructure of a mail, by given structure and partid @@ -3392,6 +3481,20 @@ class mail_bo } } if (self::$debug) _debug_array($structure); + if ($_preserveSeen==false) + { + $summary = egw_cache::getCache(egw_cache::INSTANCE,'email','summaryCache'.trim($GLOBALS['egw_info']['user']['account_id']),$callback=null,$callback_params=array(),$expiration=60*60*1); + $cachemodified = false; + if (isset($summary[$this->icServer->ImapServerId][$this->sessionData['mailbox']][$_uid])) + { + $cachemodified = true; + unset($summary[$this->icServer->ImapServerId][$this->sessionData['mailbox']][$_uid]); + } + if ($cachemodified) + { + egw_cache::setCache(egw_cache::INSTANCE,'email','summaryCache'.trim($GLOBALS['egw_info']['user']['account_id']),$summary,$expiration=60*60*1); + } + } switch($structure->type) { case 'APPLICATION': return array( diff --git a/mail/inc/class.mail_ui.inc.php b/mail/inc/class.mail_ui.inc.php index d7144ec854..196bd7ed5e 100644 --- a/mail/inc/class.mail_ui.inc.php +++ b/mail/inc/class.mail_ui.inc.php @@ -89,11 +89,12 @@ class mail_ui * * @param int $icServerID */ - function changeProfile($_icServerID) + function changeProfile($_icServerID,$unsetCache=false) { + //if (self::$icServerID != $_icServerID) $unsetCache = true; + if (mail_bo::$debug) error_log(__METHOD__.__LINE__.'->'.self::$icServerID.'<->'.$_icServerID); self::$icServerID = $_icServerID; - if (mail_bo::$debug) error_log(__METHOD__.__LINE__.'->'.self::$icServerID); - emailadmin_bo::unsetCachedObjects(self::$icServerID); + if ($unsetCache) emailadmin_bo::unsetCachedObjects(self::$icServerID); $this->mail_bo = mail_bo::getInstance(false,self::$icServerID); if (mail_bo::$debug) error_log(__METHOD__.__LINE__.' Fetched IC Server:'.self::$icServerID.'/'.$this->mail_bo->profileID.':'.function_backtrace()); // no icServer Object: something failed big time @@ -260,7 +261,7 @@ class mail_ui _debug_array('Connection Reset triggered:'.$connectionReset.' for Profile with ID:'.$icServerID); emailadmin_bo::unsetCachedObjects($icServerID); - +/* if (mail_bo::$idna2) { _debug_array('Umlautdomains supported (see Example below)'); @@ -268,7 +269,7 @@ class mail_ui $encDom = mail_bo::$idna2->encode($dom); _debug_array(array('source'=>$dom,'result'=>array('encoded'=>$encDom,'decoded'=>mail_bo::$idna2->decode($encDom)))); } - +*/ if ($preferences->preferences['prefcontroltestconnection'] == 'reset') exit; echo "

".lang('IMAP Server')."

"; diff --git a/mail/js/app.js b/mail/js/app.js index 9d920c9d79..80a8956781 100644 --- a/mail/js/app.js +++ b/mail/js/app.js @@ -50,8 +50,11 @@ app.mail = AppJS.extend( { if (_reset == true) { + //var nm = etemplate2.getByApplication('mail')[0].widgetContainer.getWidgetById('nm'); + //if (this.mail_currentlyFocussed!='') nm.refresh([this.mail_currentlyFocussed],'delete');//egw.dataDeleteUID(this.mail_currentlyFocussed); if (this.mail_currentlyFocussed!='') egw.dataDeleteUID(this.mail_currentlyFocussed); for(var k = 0; k < this.mail_selectedMails.length; k++) egw.dataDeleteUID(this.mail_selectedMails[k]); + //nm.refresh(this.mail_selectedMails,'delete'); } this.mail_selectedMails = []; this.mail_currentlyFocussed = ''; @@ -177,7 +180,7 @@ app.mail = AppJS.extend( console.log("mail_preview",nextmatch, selected); // Empty values, just in case selected is empty (user cleared selection) var dataElem = {data:{subject:"",fromaddress:"",toaddress:"",date:"",subject:""}}; - if(typeof selected != 'undefined' && selected.length > 0) + if(typeof selected != 'undefined' && selected.length == 1) { var _id = this.mail_fetchCurrentlyFocussed(selected); dataElem = egw.dataGetUIDdata(_id); @@ -259,7 +262,9 @@ app.mail = AppJS.extend( var activeFolders = tree_wdg.getTreeNodeOpenItems(nodeToRefresh,mode2use); //alert(activeFolders.join('#,#')); this.mail_queueRefreshFolderList(activeFolders); - + // maybe to use the mode forced as trigger for grid reload and using the grids own autorefresh + // would solve the refresh issue more accurately + //if (mode == "forced") this.mail_refreshMessageGrid(); this.mail_refreshMessageGrid(); } catch(e) { } // ignore the error; maybe the template is not loaded yet }, @@ -858,7 +863,10 @@ app.mail = AppJS.extend( // as the "onNodeSelect" function! var request = new egw_json_request('mail.mail_ui.ajax_moveMessages',[target, messages]); request.sendRequest(false); - for (var i = 0; i < messages['msg'].length; i++) egw.dataDeleteUID(messages['msg'][i]); + var nm = etemplate2.getByApplication('mail')[0].widgetContainer.getWidgetById('nm'); + this.mail_setRowClass(_senders,'deleted'); + nm.refresh(messages['msg'],'delete') + //for (var i = 0; i < messages['msg'].length; i++) egw.dataDeleteUID(messages['msg'][i]); this.mail_refreshMessageGrid(); }, /**