From d0210bd09a1780d51a87354327a04ef9e8ddbb17 Mon Sep 17 00:00:00 2001 From: djmaze Date: Wed, 27 Oct 2021 15:30:19 +0200 Subject: [PATCH] No need to call folderInformationMultiply at boot when LIST-STATUS is supported --- dev/App/User.js | 2 +- dev/Model/FolderCollection.js | 2 + dev/Stores/User/Folder.js | 1 + .../app/libraries/MailSo/Imap/Folder.php | 21 ------- .../app/libraries/MailSo/Imap/ImapClient.php | 55 +++++++++++-------- .../app/libraries/MailSo/Mail/Folder.php | 15 +++++ .../MailSo/Mail/FolderCollection.php | 6 ++ .../app/libraries/MailSo/Mail/MailClient.php | 31 ++++++----- .../libraries/RainLoop/Actions/Folders.php | 23 ++++---- .../libraries/RainLoop/Actions/Response.php | 24 ++++---- 10 files changed, 97 insertions(+), 83 deletions(-) diff --git a/dev/App/User.js b/dev/App/User.js index a07425f92..cc7c37594 100644 --- a/dev/App/User.js +++ b/dev/App/User.js @@ -855,7 +855,7 @@ class AppUser extends AbstractApp { this.folderInformation(cF); } this.quota(); - this.folderInformationMultiply(true); + FolderUserStore.listStatusSupported() || this.folderInformationMultiply(true); }, 1000); setTimeout(() => Remote.appDelayStart(()=>0), 35000); diff --git a/dev/Model/FolderCollection.js b/dev/Model/FolderCollection.js index 251458f61..eeebdf9e2 100644 --- a/dev/Model/FolderCollection.js +++ b/dev/Model/FolderCollection.js @@ -40,6 +40,7 @@ export class FolderCollectionModel extends AbstractCollectionModel this.IsMetadataSupported this.IsThreadsSupported this.IsSortSupported + this.IsExtendedSupported this.Namespace; this.Optimized this.SystemFolders @@ -147,6 +148,7 @@ export class FolderCollectionModel extends AbstractCollectionModel FolderUserStore.folderListOptimized(!!this.Optimized); FolderUserStore.sortSupported(!!this.IsSortSupported); FolderUserStore.metadataSupported(!!this.IsMetadataSupported); + FolderUserStore.listStatusSupported(!!this.IsListStatusSupported); FolderUserStore.sentFolder(normalizeFolder(SettingsGet('SentFolder'))); FolderUserStore.draftFolder(normalizeFolder(SettingsGet('DraftFolder'))); diff --git a/dev/Stores/User/Folder.js b/dev/Stores/User/Folder.js index 4ad414fc9..a7d6a4f48 100644 --- a/dev/Stores/User/Folder.js +++ b/dev/Stores/User/Folder.js @@ -24,6 +24,7 @@ export const FolderUserStore = new class { */ sortSupported: false, metadataSupported: false, + listStatusSupported: false, // sortMode: '', sentFolder: '', diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Folder.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Folder.php index 0fd4d0f63..038c7a964 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Folder.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Folder.php @@ -45,11 +45,6 @@ class Folder */ private $aFlagsLowerCase; - /** - * @var array - */ - private $aExtended = array(); - /** * RFC 5464 */ @@ -132,22 +127,6 @@ class Folder return 'INBOX' === \strtoupper($this->sFullNameRaw) || \in_array('\\inbox', $this->aFlagsLowerCase); } - /** - * @param mixed $mData - */ - public function SetExtended(string $sName, $mData) : void - { - $this->aExtended[$sName] = $mData; - } - - /** - * @return mixed - */ - public function GetExtended(string $sName) - { - return isset($this->aExtended[$sName]) ? $this->aExtended[$sName] : null; - } - /** * @param mixed $mData */ diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ImapClient.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ImapClient.php index 50cef14d8..a009b1e0b 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ImapClient.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ImapClient.php @@ -441,43 +441,51 @@ class ImapClient extends \MailSo\Net\NetClient */ private function specificFolderList(bool $bIsSubscribeList, string $sParentFolderName = '', string $sListPattern = '*', bool $bUseListStatus = false) : array { - $sCmd = 'LSUB'; - if (!$bIsSubscribeList) - { - $sCmd = 'LIST'; + $sCmd = 'LIST'; + + $aParameters = array(); + $aReturnParams = array(); + + if ($bIsSubscribeList) { + $sCmd = 'LSUB'; + } else if ($this->IsSupported('LIST-EXTENDED')) { + // RFC 5258 + $aReturnParams[] = 'SUBSCRIBED'; +// $aReturnParams[] = 'CHILDREN'; + if ($bIsSubscribeList) { + $aParameters[] = ['SUBSCRIBED'/*,'REMOTE','RECURSIVEMATCH'*/]; + } else { +// $aParameters[0] = '()'; + } } - $sListPattern = \strlen(\trim($sListPattern)) ? $sListPattern : '*'; - - $aParameters = array( - $this->EscapeString($sParentFolderName), - $this->EscapeString($sListPattern) - ); + $aParameters[] = $this->EscapeString($sParentFolderName); + $aParameters[] = $this->EscapeString(\strlen(\trim($sListPattern)) ? $sListPattern : '*'); if ($bUseListStatus && !$bIsSubscribeList && $this->IsSupported('LIST-STATUS')) { + // RFC 5819 $aL = array( Enumerations\FolderStatus::MESSAGES, Enumerations\FolderStatus::UNSEEN, Enumerations\FolderStatus::UIDNEXT ); -// if ($this->IsSupported('CONDSTORE')) -// { -// $aL[] = Enumerations\FolderStatus::HIGHESTMODSEQ; -// } + if ($this->IsSupported('CONDSTORE')) { + $aL[] = Enumerations\FolderStatus::HIGHESTMODSEQ; + } - $aParameters[] = 'RETURN'; - $aParameters[] = array('STATUS', $aL); + $aReturnParams[] = 'STATUS'; + $aReturnParams[] = $aL; } else { $bUseListStatus = false; - // RFC5258 - if ($this->IsSupported('LIST-EXTENDED')) { - $aParameters[] = 'RETURN'; - $aParameters[] = array('SUBSCRIBED'/*,'CHILDREN'*/); - } + } + + if ($aReturnParams) { + $aParameters[] = 'RETURN'; + $aParameters[] = $aReturnParams; } $aReturn = $this->SendRequestGetResponse($sCmd, $aParameters)->getFoldersResult($sCmd, $bUseListStatus); @@ -1127,7 +1135,10 @@ class ImapClient extends \MailSo\Net\NetClient break; } - unset($oResponse); + // RFC 5530 + if (\is_array($oResponse->OptionalResponse) && 'CLIENTBUG' === $oResponse->OptionalResponse[0]) { + // The server has detected a client bug. + } } } diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Folder.php b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Folder.php index 9c159ec97..76308486d 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Folder.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Folder.php @@ -283,6 +283,20 @@ class Folder implements \JsonSerializable public function jsonSerialize() { +/* + $aExtended = null; + $aStatus = $this->oImapFolder->getStatusItems(); + if ($aStatus && isset($aStatus['MESSAGES'], $aStatus['UNSEEN'], $aStatus['UIDNEXT'])) { + $aExtended = array( + 'MessageCount' => (int) $aStatus['MESSAGES'], + 'MessageUnseenCount' => (int) $aStatus['UNSEEN'], + 'UidNext' => (int) $aStatus['UIDNEXT'], +// 'Hash' => $this->MailClient()->GenerateFolderHash( +// $this->FullNameRaw(), $aStatus['MESSAGES'], $aStatus['UIDNEXT'], +// empty($aStatus['HIGHESTMODSEQ']) ? 0 : $aStatus['HIGHESTMODSEQ']) + ); + } +*/ return array( '@Object' => 'Object/Folder', 'Name' => $this->Name(), @@ -294,6 +308,7 @@ class Folder implements \JsonSerializable 'Exists' => $this->bExists, 'Selectable' => $this->IsSelectable(), 'Flags' => $this->FlagsLowerCase(), +// 'Extended' => $aExtended, 'Metadata' => $this->oImapFolder->Metadata() ); } diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/FolderCollection.php b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/FolderCollection.php index 055ba64b8..666e5ec34 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/FolderCollection.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/FolderCollection.php @@ -42,6 +42,11 @@ class FolderCollection extends \MailSo\Base\Collection */ public $IsSortSupported = false; + /** + * @var bool + */ + public $IsListStatusSupported = false; + /** * @var bool */ @@ -161,6 +166,7 @@ class FolderCollection extends \MailSo\Base\Collection 'IsMetadataSupported' => $this->IsMetadataSupported, 'IsThreadsSupported' => $this->IsThreadsSupported, 'IsSortSupported' => $this->IsSortSupported, + 'IsListStatusSupported' => $this->IsListStatusSupported, 'Optimized' => $this->Optimized, 'CountRec' => $this->CountRec(), 'SystemFolders' => empty($this->SystemFolders) ? null : $this->SystemFolders diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php index 2a2ed65b4..483f464b9 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php @@ -153,7 +153,7 @@ class MailClient if (\is_array($aCustomUids)) { - if (0 < \count($aCustomUids)) + if (\count($aCustomUids)) { $this->oImapClient->MessageStoreFlag(implode(',', $aCustomUids), true, array($sMessageFlag), $sStoreAction); } @@ -254,7 +254,7 @@ class MailClient ); $aFetchResponse = $this->oImapClient->Fetch(array(\MailSo\Imap\Enumerations\FetchType::BODYSTRUCTURE), $iIndex, $bIndexIsUid); - if (0 < \count($aFetchResponse) && isset($aFetchResponse[0])) + if (\count($aFetchResponse) && isset($aFetchResponse[0])) { $oBodyStructure = $aFetchResponse[0]->GetFetchBodyStructure(); if ($oBodyStructure) @@ -271,7 +271,7 @@ class MailClient } $aSignatureParts = $oBodyStructure->SearchByContentType('application/pgp-signature'); - if (is_array($aSignatureParts) && 0 < \count($aSignatureParts)) + if (is_array($aSignatureParts) && \count($aSignatureParts)) { foreach ($aSignatureParts as $oPart) { @@ -287,7 +287,7 @@ class MailClient } $aFetchResponse = $this->oImapClient->Fetch($aFetchItems, $iIndex, $bIndexIsUid); - if (0 < \count($aFetchResponse)) + if (\count($aFetchResponse)) { $oMessage = Message::NewFetchResponseInstance( $sFolderName, $aFetchResponse[0], $oBodyStructure); @@ -632,7 +632,7 @@ class MailClient $bSelect = false; - if (0 < \count($aUids)) + if (\count($aUids)) { if (!$bSelect) { @@ -803,7 +803,7 @@ class MailClient $mMatch = array(); \preg_match_all('/('.$sReg.'):([^\s]*)/i', $sSearch, $mMatch); - if (\is_array($mMatch) && isset($mMatch[1]) && \is_array($mMatch[1]) && 0 < \count($mMatch[1])) + if (\is_array($mMatch) && isset($mMatch[1]) && \is_array($mMatch[1]) && \count($mMatch[1])) { if (\is_array($mMatch[0])) { @@ -1128,7 +1128,7 @@ class MailClient else { $mMap = $this->threadArrayMap($mItem); - if (0 < \count($mMap)) + if (\count($mMap)) { $aNew = \array_merge($aNew, $mMap); } @@ -1150,7 +1150,7 @@ class MailClient { $aResult[] = $aMap; } - else if (0 < \count($aMap)) + else if (\count($aMap)) { $aResult[] = $aMap[0]; } @@ -1313,7 +1313,7 @@ class MailClient $mFirst = \array_shift($aItem); if (!empty($mFirst)) { - $aTemp[$mFirst] = 0 < \count($aItem) ? $aItem : $mFirst; + $aTemp[$mFirst] = \count($aItem) ? $aItem : $mFirst; } } } @@ -1361,7 +1361,7 @@ class MailClient */ public function MessageListByRequestIndexOrUids(MessageCollection $oMessageCollection, array $aRequestIndexOrUids, bool $bIndexAsUid, bool $bSimple = false) { - if (0 < \count($aRequestIndexOrUids)) + if (\count($aRequestIndexOrUids)) { $aFetchResponse = $this->oImapClient->Fetch(array( \MailSo\Imap\Enumerations\FetchType::INDEX, @@ -1375,7 +1375,7 @@ class MailClient $this->getEnvelopeOrHeadersRequestString() ), \MailSo\Base\Utils::PrepareFetchSequence($aRequestIndexOrUids), $bIndexAsUid); - if (0 < \count($aFetchResponse)) + if (\count($aFetchResponse)) { $aFetchIndexArray = array(); foreach ($aFetchResponse as /* @var $oFetchResponseItem \MailSo\Imap\FetchResponse */ $oFetchResponseItem) @@ -1653,7 +1653,7 @@ class MailClient $aSearchedUids = $this->GetUids($oCacher, $sSearch, $sFilter, $oMessageCollection->FolderName, $oMessageCollection->FolderHash); - if (0 < \count($aSearchedUids)) + if (\count($aSearchedUids)) { $aFlippedSearchedUids = \array_flip($aSearchedUids); @@ -1694,7 +1694,7 @@ class MailClient $oMessageCollection->MessageUnseenCount = $iMessageUnseenCount; $oMessageCollection->MessageResultCount = \count($aUids); - if (0 < \count($aUids)) + if (\count($aUids)) { $aRequestUids = \array_slice($aUids, $iOffset, $iLimit); $this->MessageListByRequestIndexOrUids($oMessageCollection, $aRequestUids, true); @@ -1934,8 +1934,8 @@ class MailClient } } - $aFolders = $this->oImapClient->FolderList($sParent, $sListPattern); -// $aFolders = $this->oImapClient->FolderStatusList($sParent, $sListPattern); +// $aFolders = $this->oImapClient->FolderList($sParent, $sListPattern); + $aFolders = $this->oImapClient->FolderStatusList($sParent, $sListPattern); if (!$aFolders) { return null; } @@ -1959,6 +1959,7 @@ class MailClient $oFolderCollection->IsMetadataSupported = $this->oImapClient->IsSupported('METADATA'); $oFolderCollection->IsThreadsSupported = $this->IsThreadsSupported(); $oFolderCollection->IsSortSupported = $this->oImapClient->IsSupported('SORT'); + $oFolderCollection->IsListStatusSupported = $this->oImapClient->IsSupported('LIST-STATUS'); $oFolderCollection->Optimized = $iCount !== \count($aMailFoldersHelper); $aSortedByLenImapFolders = array(); diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Folders.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Folders.php index 456880c0f..a4fd5aaea 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Folders.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Folders.php @@ -10,6 +10,14 @@ use \MailSo\Imap\Enumerations\FolderType; trait Folders { + private function getFolderCollection(bool $HideUnsubscribed) : ?\MailSo\Mail\FolderCollection + { + return $this->MailClient()->Folders('', '*', + $HideUnsubscribed, + (int) $this->Config()->Get('labs', 'imap_folder_list_limit', 200) + ); + } + public function DoFolders() : array { $oAccount = $this->initMailClientConnection(); @@ -20,13 +28,9 @@ trait Folders $HideUnsubscribed = (bool) $oSettingsLocal->GetConf('HideUnsubscribed', $HideUnsubscribed); } - $oFolderCollection = $this->MailClient()->Folders('', - '*', - $HideUnsubscribed, - (int) $this->Config()->Get('labs', 'imap_folder_list_limit', 200) - ); + $oFolderCollection = $this->getFolderCollection($HideUnsubscribed); - if ($oFolderCollection instanceof \MailSo\Mail\FolderCollection) + if ($oFolderCollection) { $this->Plugins()->RunHook('filter.folders-post', array($oAccount, $oFolderCollection)); @@ -126,10 +130,7 @@ trait Folders if ($bDoItAgain) { - $oFolderCollection = $this->MailClient()->Folders('', '*', - $HideUnsubscribed, - (int) $this->Config()->Get('labs', 'imap_folder_list_limit', 200) - ); + $oFolderCollection = $this->getFolderCollection($HideUnsubscribed); if ($oFolderCollection) { @@ -406,7 +407,7 @@ trait Folders $aFolders = \array_unique($aFolders); foreach ($aFolders as $sFolder) { - if (0 < \strlen($sFolder) && 'INBOX' !== \strtoupper($sFolder)) + if (\strlen($sFolder) && 'INBOX' !== \strtoupper($sFolder)) { try { diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Response.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Response.php index 17e44d598..dde960ea9 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Response.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Response.php @@ -404,19 +404,17 @@ trait Response if ($mResponse instanceof \MailSo\Mail\Folder) { $aExtended = null; - -// $mStatus = $mResponse->Status(); -// if (\is_array($mStatus) && isset($mStatus['MESSAGES'], $mStatus['UNSEEN'], $mStatus['UIDNEXT'])) -// { -// $aExtended = array( -// 'MessageCount' => (int) $mStatus['MESSAGES'], -// 'MessageUnseenCount' => (int) $mStatus['UNSEEN'], -// 'UidNext' => (int) $mStatus['UIDNEXT'], -// 'Hash' => $this->MailClient()->GenerateFolderHash( -// $mResponse->FullNameRaw(), $mStatus['MESSAGES'], $mStatus['UIDNEXT'], -// empty($mStatus['HIGHESTMODSEQ']) ? '' : $mStatus['HIGHESTMODSEQ']) -// ); -// } + $aStatus = $mResponse->Status(); + if ($aStatus && isset($aStatus['MESSAGES'], $aStatus['UNSEEN'], $aStatus['UIDNEXT'])) { + $aExtended = array( + 'MessageCount' => (int) $aStatus['MESSAGES'], + 'MessageUnseenCount' => (int) $aStatus['UNSEEN'], + 'UidNext' => (int) $aStatus['UIDNEXT'], + 'Hash' => $this->MailClient()->GenerateFolderHash( + $mResponse->FullNameRaw(), $aStatus['MESSAGES'], $aStatus['UIDNEXT'], + empty($aStatus['HIGHESTMODSEQ']) ? 0 : $aStatus['HIGHESTMODSEQ']) + ); + } if (null === $this->aCheckableFolder) {