Use UIDVALIDITY when HIGHESTMODSEQ not available, maybe solves #745

This commit is contained in:
the-djmaze 2022-12-05 11:09:42 +01:00
parent d48b3a74fc
commit f82574a472
3 changed files with 81 additions and 107 deletions

View file

@ -214,7 +214,7 @@ class Folder implements \JsonSerializable
'UidNext' => (int) $aStatus['UIDNEXT'], 'UidNext' => (int) $aStatus['UIDNEXT'],
// 'Hash' => $this->MailClient()->GenerateFolderHash( // 'Hash' => $this->MailClient()->GenerateFolderHash(
// $this->FullName(), $aStatus['MESSAGES'], $aStatus['UIDNEXT'], // $this->FullName(), $aStatus['MESSAGES'], $aStatus['UIDNEXT'],
// empty($aStatus['HIGHESTMODSEQ']) ? 0 : $aStatus['HIGHESTMODSEQ']) // empty($aStatus['HIGHESTMODSEQ']) ? $aStatus['UIDVALIDITY'] : $aStatus['HIGHESTMODSEQ'])
); );
} }
*/ */

View file

@ -417,7 +417,7 @@ class MailClient
\max(0, $oFolderStatus->UIDNEXT ?: 0), \max(0, $oFolderStatus->UIDNEXT ?: 0),
\max(0, $oFolderStatus->HIGHESTMODSEQ ?: 0), \max(0, $oFolderStatus->HIGHESTMODSEQ ?: $oFolderStatus->UIDVALIDITY),
$oFolderStatus->APPENDLIMIT ?: $this->oImapClient->AppendLimit(), $oFolderStatus->APPENDLIMIT ?: $this->oImapClient->AppendLimit(),
@ -820,147 +820,121 @@ class MailClient
$oInfo = $this->oImapClient->FolderStatusAndSelect($oParams->sFolderName); $oInfo = $this->oImapClient->FolderStatusAndSelect($oParams->sFolderName);
$oMessageCollection->FolderInfo = $oInfo; $oMessageCollection->FolderInfo = $oInfo;
$aUids = array();
$aAllThreads = []; $aAllThreads = [];
$bUseSortIfSupported = $oParams->bUseSortIfSupported && $this->oImapClient->IsSupported('SORT');
$bUseThreads = $oParams->bUseThreads ? $bUseThreads = $oParams->bUseThreads ?
($this->oImapClient->IsSupported('THREAD=REFS') || $this->oImapClient->IsSupported('THREAD=REFERENCES') || $this->oImapClient->IsSupported('THREAD=ORDEREDSUBJECT')) : false; ($this->oImapClient->IsSupported('THREAD=REFS') || $this->oImapClient->IsSupported('THREAD=REFERENCES') || $this->oImapClient->IsSupported('THREAD=ORDEREDSUBJECT')) : false;
if ($oParams->iThreadUid && !$bUseThreads) {
if ($oParams->iThreadUid && !$bUseThreads)
{
throw new \InvalidArgumentException('THREAD not supported'); throw new \InvalidArgumentException('THREAD not supported');
} }
if (!$oParams->oCacher || !($oParams->oCacher instanceof \MailSo\Cache\CacheClient)) if (!$oParams->oCacher || !($oParams->oCacher instanceof \MailSo\Cache\CacheClient)) {
{
$oParams->oCacher = null; $oParams->oCacher = null;
} }
$oMessageCollection->FolderHash = $this->GenerateFolderHash( $oMessageCollection->FolderHash = $this->GenerateFolderHash(
$oParams->sFolderName, $oInfo->MESSAGES, $oInfo->UIDNEXT, $oInfo->HIGHESTMODSEQ $oParams->sFolderName, $oInfo->MESSAGES, $oInfo->UIDNEXT, $oInfo->HIGHESTMODSEQ ?: $oInfo->UIDVALIDITY
); );
if (!$oParams->iThreadUid) if (!$oParams->iThreadUid) {
{
$oMessageCollection->NewMessages = $this->getFolderNextMessageInformation( $oMessageCollection->NewMessages = $this->getFolderNextMessageInformation(
$oParams->sFolderName, $oParams->iPrevUidNext, $oInfo->UIDNEXT $oParams->sFolderName, $oParams->iPrevUidNext, $oInfo->UIDNEXT
); );
} }
$bSearch = false; if ($oInfo->MESSAGES) {
$bMessageListOptimization = 0 < \MailSo\Config::$MessageListCountLimitTrigger && if (0 < \MailSo\Config::$MessageListCountLimitTrigger && \MailSo\Config::$MessageListCountLimitTrigger < $oInfo->MESSAGES) {
\MailSo\Config::$MessageListCountLimitTrigger < $oInfo->MESSAGES; if ($this->oLogger) {
$this->oLogger->Write('List optimization (count: '.$oInfo->MESSAGES.
if ($bMessageListOptimization) ', limit:'.\MailSo\Config::$MessageListCountLimitTrigger.')');
{
$bUseSortIfSupported = false;
$bUseThreads = false;
}
if ($oInfo->MESSAGES && !$bMessageListOptimization)
{
if ($bUseThreads) {
$aAllThreads = $this->MessageListThreadsMap($oMessageCollection->FolderName, $oMessageCollection->FolderHash, $oParams->oCacher);
// $iThreadLimit = \MailSo\Config::$LargeThreadLimit;
if ($oParams->iThreadUid)
{
$aUids = [$oParams->iThreadUid];
// Only show the selected thread messages
foreach ($aAllThreads as $aMap) {
if (\in_array($oParams->iThreadUid, $aMap)) {
$aUids = $aMap;
break;
}
}
} }
else if (\strlen($sSearch)) {
{ $aUids = $this->GetUids($oParams, $sSearch,
$aUids = $this->GetUids($oParams, '', $oMessageCollection->FolderName, $oMessageCollection->FolderHash);
$oMessageCollection->FolderName, $oMessageCollection->FolderHash, $bUseSortIfSupported, $oParams->sSort);
// Remove all threaded UID's except the most recent of each thread $oMessageCollection->MessageResultCount = \count($aUids);
$threadedUids = []; if ($oMessageCollection->MessageResultCount) {
foreach ($aAllThreads as $aMap) { $this->MessageListByRequestIndexOrUids(
unset($aMap[\array_key_last($aMap)]); $oMessageCollection,
$threadedUids = \array_merge($threadedUids, $aMap); new SequenceSet(\array_slice($aUids, $oParams->iOffset, $oParams->iLimit))
);
} }
$aUids = \array_diff($aUids, $threadedUids); } else {
$oMessageCollection->MessageResultCount = $oInfo->MESSAGES;
if (1 < $oInfo->MESSAGES) {
$end = \max(1, $oInfo->MESSAGES - $oParams->iOffset);
$start = \max(1, $end - $oParams->iLimit + 1);
$aRequestIndexes = \range($start, $end);
} else {
$aRequestIndexes = \array_slice([1], $oParams->iOffset, 1);
}
$this->MessageListByRequestIndexOrUids($oMessageCollection, new SequenceSet($aRequestIndexes, false));
} }
} else { } else {
$aUids = $this->GetUids($oParams, '', $aUids = [];
$oMessageCollection->FolderName, $oMessageCollection->FolderHash, $bUseSortIfSupported, $oParams->sSort); $bUseSortIfSupported = $oParams->bUseSortIfSupported && $this->oImapClient->IsSupported('SORT');
} if ($bUseThreads) {
$aAllThreads = $this->MessageListThreadsMap($oMessageCollection->FolderName, $oMessageCollection->FolderHash, $oParams->oCacher);
if ($aUids && \strlen($sSearch)) // $iThreadLimit = \MailSo\Config::$LargeThreadLimit;
{ if ($oParams->iThreadUid) {
$aSearchedUids = $this->GetUids($oParams, $sSearch, $aUids = [$oParams->iThreadUid];
$oMessageCollection->FolderName, $oMessageCollection->FolderHash); // Only show the selected thread messages
if ($bUseThreads && !$oParams->iThreadUid) { foreach ($aAllThreads as $aMap) {
$matchingThreadUids = []; if (\in_array($oParams->iThreadUid, $aMap)) {
foreach ($aAllThreads as $aMap) { $aUids = $aMap;
if (\array_intersect($aSearchedUids, $aMap)) { break;
$matchingThreadUids = \array_merge($matchingThreadUids, $aMap);
} }
}
} else {
$aUids = $this->GetUids($oParams, '',
$oMessageCollection->FolderName, $oMessageCollection->FolderHash, $bUseSortIfSupported, $oParams->sSort);
// Remove all threaded UID's except the most recent of each thread
$threadedUids = [];
foreach ($aAllThreads as $aMap) {
unset($aMap[\array_key_last($aMap)]);
$threadedUids = \array_merge($threadedUids, $aMap);
}
$aUids = \array_diff($aUids, $threadedUids);
} }
$aUids = \array_filter($aUids, function($iUid) use ($aSearchedUids, $matchingThreadUids) {
return \in_array($iUid, $aSearchedUids) || \in_array($iUid, $matchingThreadUids);
});
} else { } else {
$aUids = \array_filter($aUids, function($iUid) use ($aSearchedUids) { $aUids = $this->GetUids($oParams, '',
return \in_array($iUid, $aSearchedUids); $oMessageCollection->FolderName, $oMessageCollection->FolderHash, $bUseSortIfSupported, $oParams->sSort);
});
} }
}
$oMessageCollection->MessageResultCount = \count($aUids); if ($aUids && \strlen($sSearch)) {
$aSearchedUids = $this->GetUids($oParams, $sSearch,
if (\count($aUids)) $oMessageCollection->FolderName, $oMessageCollection->FolderHash);
{ if ($bUseThreads && !$oParams->iThreadUid) {
$this->MessageListByRequestIndexOrUids( $matchingThreadUids = [];
$oMessageCollection, foreach ($aAllThreads as $aMap) {
new SequenceSet(\array_slice($aUids, $oParams->iOffset, $oParams->iLimit)) if (\array_intersect($aSearchedUids, $aMap)) {
); $matchingThreadUids = \array_merge($matchingThreadUids, $aMap);
} }
} }
else if ($oInfo->MESSAGES) $aUids = \array_filter($aUids, function($iUid) use ($aSearchedUids, $matchingThreadUids) {
{ return \in_array($iUid, $aSearchedUids) || \in_array($iUid, $matchingThreadUids);
if ($this->oLogger) });
{ } else {
$this->oLogger->Write('List optimization (count: '.$oInfo->MESSAGES. $aUids = \array_filter($aUids, function($iUid) use ($aSearchedUids) {
', limit:'.\MailSo\Config::$MessageListCountLimitTrigger.')'); return \in_array($iUid, $aSearchedUids);
} });
}
if (\strlen($sSearch)) }
{
$aUids = $this->GetUids($oParams, $sSearch,
$oMessageCollection->FolderName, $oMessageCollection->FolderHash);
$oMessageCollection->MessageResultCount = \count($aUids); $oMessageCollection->MessageResultCount = \count($aUids);
if ($oMessageCollection->MessageResultCount) {
if (\count($aUids)) {
$this->MessageListByRequestIndexOrUids( $this->MessageListByRequestIndexOrUids(
$oMessageCollection, $oMessageCollection,
new SequenceSet(\array_slice($aUids, $oParams->iOffset, $oParams->iLimit)) new SequenceSet(\array_slice($aUids, $oParams->iOffset, $oParams->iLimit))
); );
} }
} }
else } else if ($this->oLogger) {
{ $this->oLogger->Write('No messages in '.$oMessageCollection->FolderName);
$oMessageCollection->MessageResultCount = $oInfo->MESSAGES;
if (1 < $oInfo->MESSAGES) {
$end = \max(1, $oInfo->MESSAGES - $oParams->iOffset);
$start = \max(1, $end - $oParams->iLimit + 1);
$aRequestIndexes = \range($start, $end);
} else {
$aRequestIndexes = \array_slice([1], $oParams->iOffset, 1);
}
$this->MessageListByRequestIndexOrUids($oMessageCollection, new SequenceSet($aRequestIndexes, false));
}
} }
if ($aAllThreads && !$oParams->iThreadUid) if ($aAllThreads && !$oParams->iThreadUid) {
{
foreach ($oMessageCollection as $oMessage) { foreach ($oMessageCollection as $oMessage) {
$iUid = $oMessage->Uid(); $iUid = $oMessage->Uid();
// Find thread and set it. // Find thread and set it.

View file

@ -256,7 +256,7 @@ trait Response
$mResponse->FullName(), $mResponse->FullName(),
$aStatus['MESSAGES'], $aStatus['MESSAGES'],
$aStatus['UIDNEXT'], $aStatus['UIDNEXT'],
empty($aStatus['HIGHESTMODSEQ']) ? 0 : $aStatus['HIGHESTMODSEQ'] empty($aStatus['HIGHESTMODSEQ']) ? $aStatus['UIDVALIDITY'] : $aStatus['HIGHESTMODSEQ']
); );
} }