From 5acbcad35dc90c9131bed09c8e70ce7dfb3dfc95 Mon Sep 17 00:00:00 2001 From: Klaus Leithoff Date: Thu, 31 Jul 2014 10:22:47 +0000 Subject: [PATCH] cache subscribedFolders Call to be used in getfolderStatus; control param if to fetch subscribed Info on getFolderStatus at all; own getMailboxCounters wrapper, instead of getFolderStatus, if one needs the counters only --- emailadmin/inc/class.emailadmin_imap.inc.php | 23 +++++++++ .../inc/class.emailadmin_imapbase.inc.php | 48 ++++++++++++++----- mail/inc/class.mail_ui.inc.php | 22 +++++---- 3 files changed, 72 insertions(+), 21 deletions(-) diff --git a/emailadmin/inc/class.emailadmin_imap.inc.php b/emailadmin/inc/class.emailadmin_imap.inc.php index c1b813c312..9db68d5db2 100644 --- a/emailadmin/inc/class.emailadmin_imap.inc.php +++ b/emailadmin/inc/class.emailadmin_imap.inc.php @@ -458,6 +458,29 @@ class emailadmin_imap extends Horde_Imap_Client_Socket implements defaultimap return $suF; } + /** + * getMailboxCounters + * + * @param array/string $mailbox + * @return array with counters + */ + function getMailboxCounters($mailbox) + { + try + { + $status = $this->status($mailbox); + foreach ($status as $key => $v) + { + $_status[strtoupper($key)]=$v; + } + return $_status; + } + catch (Exception $e) + { + return false; + } + } + /** * getStatus * diff --git a/emailadmin/inc/class.emailadmin_imapbase.inc.php b/emailadmin/inc/class.emailadmin_imapbase.inc.php index 3b3299815e..4ad544e7cd 100644 --- a/emailadmin/inc/class.emailadmin_imapbase.inc.php +++ b/emailadmin/inc/class.emailadmin_imapbase.inc.php @@ -1106,10 +1106,10 @@ class emailadmin_imapbase * @param _folderName string the foldername * @param ignoreStatusCache bool ignore the cache used for counters * @param basicInfoOnly bool retrieve only names and stuff returned by getMailboxes - * + * @param fetchSubscribedInfo bool fetch Subscribed Info on folder * @return array */ - function getFolderStatus($_folderName,$ignoreStatusCache=false,$basicInfoOnly=false) + function getFolderStatus($_folderName,$ignoreStatusCache=false,$basicInfoOnly=false,$fetchSubscribedInfo=true) { if (self::$debug) error_log(__METHOD__.' ('.__LINE__.') '." called with:$_folderName,$ignoreStatusCache,$basicInfoOnly"); if (!is_string($_folderName) || empty($_folderName)) // something is wrong. Do not proceed @@ -1196,8 +1196,13 @@ class emailadmin_imapbase return $retValue; } // fetch all in one go for one request, instead of querying them one by one + // cache it for a minute 60*60*1 // this should reduce communication to the imap server static $subscribedFolders; + if ($fetchSubscribedInfo && is_null($subscribedFolders)||empty($subscribedFolders[$this->profileID])) + { + $subscribedFolders = egw_cache::getCache(egw_cache::INSTANCE,'email','subscribedFolders'.trim($GLOBALS['egw_info']['user']['account_id']),null,array(),$expiration=60*60*1); + } static $nameSpace; static $prefix; if (is_null($nameSpace) || empty($nameSpace[$this->profileID])) $nameSpace[$this->profileID] = $this->_getNameSpaces(); @@ -1212,16 +1217,20 @@ class emailadmin_imapbase } if (is_null($prefix) || empty($prefix[$this->profileID]) || empty($prefix[$this->profileID][$_folderName])) $prefix[$this->profileID][$_folderName] = $this->getFolderPrefixFromNamespace($nameSpace[$this->profileID], $_folderName); - //$subscribedFolders[$this->profileID] = $this->icServer->listSubscribedMailboxes('', $_folderName); - if (is_null($subscribedFolders) || empty($subscribedFolders[$this->profileID])) $subscribedFolders[$this->profileID] = $this->icServer->listSubscribedMailboxes(); + if ($fetchSubscribedInfo && is_null($subscribedFolders) || empty($subscribedFolders[$this->profileID])) + { + $subscribedFolders[$this->profileID] = $this->icServer->listSubscribedMailboxes(); + egw_cache::setCache(egw_cache::INSTANCE,'email','subscribedFolders'.trim($GLOBALS['egw_info']['user']['account_id']),$subscribedFolders,$expiration=60*60*1); + } - if(is_array($subscribedFolders[$this->profileID]) && in_array($_folderName,$subscribedFolders[$this->profileID])) { + if($fetchSubscribedInfo && is_array($subscribedFolders[$this->profileID]) && in_array($_folderName,$subscribedFolders[$this->profileID])) { $retValue['subscribed'] = true; } try { - $folderStatus = $this->_getStatus($_folderName,$ignoreStatusCache); + //$folderStatus = $this->_getStatus($_folderName,$ignoreStatusCache); + $folderStatus = $this->getMailBoxCounters($_folderName,false); $retValue['messages'] = $folderStatus['MESSAGES']; $retValue['recent'] = $folderStatus['RECENT']; $retValue['uidnext'] = $folderStatus['UIDNEXT']; @@ -2180,6 +2189,14 @@ class emailadmin_imapbase return true; } + /** + * subscribe: do the subscription or unsubscribe on a given folder + * returns a boolean on success or failure. + * + * @param string $_folderName + * @param boolean $_status subscribe on true, unsubscribe on false + * @return boolean + */ function subscribe($_folderName, $_status) { if (self::$debug) error_log(__METHOD__."::".($_status?"":"un")."subscribe:".$_folderName); @@ -2280,7 +2297,7 @@ class emailadmin_imapbase $inboxData->shortDisplayName = lang('INBOX'); $inboxData->subscribed = true; if($_getCounters == true) { - $inboxData->counter = self::getMailBoxCounters('INBOX'); + $inboxData->counter = $this->getMailBoxCounters('INBOX'); } // force unsubscribed by preference showAllFoldersInFolderPane if ($_subscribedOnly == true && @@ -2335,6 +2352,7 @@ class emailadmin_imapbase foreach ($subscribedMailboxes as $k => $finfo) { //error_log(__METHOD__.__LINE__.$k.':#:'.array2string($finfo)); + $subscribedFoldersForCache[$this->icServer->ImapServerId][$k]= $folderBasicInfo[$this->icServer->ImapServerId][$k]=array( 'MAILBOX'=>$finfo['MAILBOX'], 'ATTRIBUTES'=>$finfo['ATTRIBUTES'], @@ -2446,6 +2464,10 @@ class emailadmin_imapbase 'delimiter'=>$mbx['delimiter'],//lowercase for some reason??? 'SUBSCRIBED'=>$mbx['SUBSCRIBED'],//seeded by getMailboxes ); + if ($mbx['SUBSCRIBED'] && !isset($subscribedFoldersForCache[$this->icServer->ImapServerId][$mbx['MAILBOX']])) + { + $subscribedFoldersForCache[$this->icServer->ImapServerId][$mbx['MAILBOX']] = $folderBasicInfo[$this->icServer->ImapServerId][$mbx['MAILBOX']]; + } } if ($mbx['SUBSCRIBED'] && (empty($foldersNameSpace[$type]['subscribed']) || !in_array($mbx['MAILBOX'],$foldersNameSpace[$type]['subscribed']))) { @@ -2589,6 +2611,8 @@ class emailadmin_imapbase } */ } + //subscribed folders may be used in getFolderStatus + egw_cache::setCache(egw_cache::INSTANCE,'email','subscribedFolders'.trim($GLOBALS['egw_info']['user']['account_id']),$subscribedFoldersForCache,$expiration=60*60*1); //echo "
FolderNameSpace To Process:";_debug_array($foldersNameSpace); $autoFolderObjects = array(); foreach( array('personal', 'others', 'shared') as $type) { @@ -2726,14 +2750,15 @@ class emailadmin_imapbase * * function to retrieve the counters for a given folder * @param string $folderName - * @return mixed false or array of counters array(MESSAGES,UNSEEN,RECENT,UIDNEXT,UIDVALIDITY) + * @param boolean $_returnObject return the counters as object rather than an array + * @return mixed false or array of counters array(MESSAGES,UNSEEN,RECENT,UIDNEXT,UIDVALIDITY) or object */ - function getMailBoxCounters($folderName) + function getMailBoxCounters($folderName,$_returnObject=true) { try { - $folderStatus = $this->_getStatus($folderName); - //error_log(__METHOD__.' ('.__LINE__.') '." FolderStatus:".array2string($folderStatus)); + $folderStatus = $this->icServer->getMailboxCounters($folderName); + //error_log(__METHOD__.' ('.__LINE__.') '.$folderName.": FolderStatus:".array2string($folderStatus).function_backtrace()); } catch (Exception $e) { @@ -2741,6 +2766,7 @@ class emailadmin_imapbase return false; } if(is_array($folderStatus)) { + if ($_returnObject===false) return $folderStatus; $status = new stdClass; $status->messages = $folderStatus['MESSAGES']; $status->unseen = $folderStatus['UNSEEN']; diff --git a/mail/inc/class.mail_ui.inc.php b/mail/inc/class.mail_ui.inc.php index fb22138d9f..dfb4a080fb 100644 --- a/mail/inc/class.mail_ui.inc.php +++ b/mail/inc/class.mail_ui.inc.php @@ -873,8 +873,10 @@ class mail_ui if ($levelCt>$cmblevelsCt+1) $fetchCounters=false; } //error_log(__METHOD__.__LINE__.' fc:'.$fetchCounters.'/'.$_fetchCounters.'('.$levelCt.'/'.$cmblevelsCt.')'.' for:'.array2string($key)); - $fS = $this->mail_bo->getFolderStatus($key,false,($fetchCounters?false:true)); - //error_log(__METHOD__.__LINE__.array2string($fS)); + $fS = $this->mail_bo->getFolderStatus($key,false,($fetchCounters?false:true),false); + //error_log(__METHOD__.__LINE__.'Object:'.array2string($obj)); + //error_log(__METHOD__.__LINE__.'Status:'.array2string($fS)); + //error_log(__METHOD__.__LINE__."-------------------------"); $fFP = $folderParts = explode($obj->delimiter, $key); if (in_array($key,$userDefinedFunctionFolders)) $obj->shortDisplayName = lang($obj->shortDisplayName); //get rightmost folderpart @@ -3321,7 +3323,7 @@ class mail_ui if ($profileID != $this->mail_bo->profileID) continue; // only current connection if ($folderName) { - $fS = $this->mail_bo->getFolderStatus($folderName,false); + $fS = $this->mail_bo->getFolderStatus($folderName,false,false,false); if (in_array($fS['shortDisplayName'],mail_bo::$autoFolders)) $fS['shortDisplayName']=lang($fS['shortDisplayName']); //error_log(__METHOD__.__LINE__.array2string($fS)); if ($fS['unseen']) @@ -3563,7 +3565,7 @@ class mail_ui if (!empty($folderName)) { $parentFolder=(!empty($folderName)?$folderName:'INBOX'); - $folderInfo = $this->mail_bo->getFolderStatus($parentFolder,false); + $folderInfo = $this->mail_bo->getFolderStatus($parentFolder,false,false,false); if ($folderInfo['unseen']) { $folderInfo['shortDisplayName'] = $folderInfo['shortDisplayName'].' ('.$folderInfo['unseen'].')'; @@ -3627,7 +3629,7 @@ class mail_ui strpos($parentFolder,$folderName)===false)))) // indicates that we move the older up the tree within its own branch { //error_log(__METHOD__.__LINE__."$folderName, $parentFolder, $_newName"); - $oldFolderInfo = $this->mail_bo->getFolderStatus($folderName,false); + $oldFolderInfo = $this->mail_bo->getFolderStatus($folderName,false,false,false); //error_log(__METHOD__.__LINE__.array2string($oldFolderInfo)); if (!empty($oldFolderInfo['attributes']) && stripos(array2string($oldFolderInfo['attributes']),'\hasnochildren')=== false) { @@ -3672,7 +3674,7 @@ class mail_ui $msg = $e->getMessage(); } $this->mail_bo->reopen($parentFolder); - $this->mail_bo->getFolderStatus($parentFolder,false); + $this->mail_bo->getFolderStatus($parentFolder,false,false,false); //error_log(__METHOD__.__LINE__.array2string($fS)); if ($hasChildren) { @@ -3704,8 +3706,8 @@ class mail_ui { translation::add_app('mail'); - $oldFolderInfo = $this->mail_bo->getFolderStatus($oldParentFolder,false); - $folderInfo = $this->mail_bo->getFolderStatus($parentFolder,false); + $oldFolderInfo = $this->mail_bo->getFolderStatus($oldParentFolder,false,false,false); + $folderInfo = $this->mail_bo->getFolderStatus($parentFolder,false,false,false); $refreshData = array( $profileID.self::$delimiter.$oldParentFolder=>$oldFolderInfo['shortDisplayName'], $profileID.self::$delimiter.$parentFolder=>$folderInfo['shortDisplayName']); @@ -3754,7 +3756,7 @@ class mail_ui //error_log(__METHOD__.__LINE__."$folderName, implode($del,$pA), $_newName"); $oA = array(); $subFolders = array(); - $oldFolderInfo = $this->mail_bo->getFolderStatus($folderName,false); + $oldFolderInfo = $this->mail_bo->getFolderStatus($folderName,false,false,false); //error_log(__METHOD__.__LINE__.array2string($oldFolderInfo)); if (!empty($oldFolderInfo['attributes']) && stripos(array2string($oldFolderInfo['attributes']),'\hasnochildren')=== false) { @@ -4013,7 +4015,7 @@ class mail_ui } if ($rememberServerID != $this->mail_bo->profileID) { - $oldFolderInfo = $this->mail_bo->getFolderStatus($trashFolder,false); + $oldFolderInfo = $this->mail_bo->getFolderStatus($trashFolder,false,false,false); $response = egw_json_response::get(); $response->call('egw.message',lang('empty trash')); $response->call('app.mail.mail_reloadNode',array($icServerID.self::$delimiter.$trashFolder=>$oldFolderInfo['shortDisplayName']));