mirror of
https://github.com/the-djmaze/snappymail.git
synced 2025-01-01 12:32:40 +08:00
Message List without deleted messages (experemental)
Small fixes
This commit is contained in:
parent
6c28b24aaf
commit
aebd47393c
3 changed files with 294 additions and 9 deletions
|
@ -1081,10 +1081,11 @@ class MailClient
|
|||
/**
|
||||
* @param string $sSearch
|
||||
* @param int $iTimeZoneOffset = 0
|
||||
* @param bool $bAddNotDeleted = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getImapSearchCriterias($sSearch, $iTimeZoneOffset = 0)
|
||||
private function getImapSearchCriterias($sSearch, $iTimeZoneOffset = 0, $bAddNotDeleted = false)
|
||||
{
|
||||
$aCriteriasResult = array();
|
||||
if (0 < \strlen(\trim($sSearch)))
|
||||
|
@ -1309,7 +1310,11 @@ class MailClient
|
|||
$sCriteriasResult = \trim(\implode(' ', $aCriteriasResult));
|
||||
if ('' === $sCriteriasResult)
|
||||
{
|
||||
$sCriteriasResult = 'ALL';
|
||||
$sCriteriasResult = $bAddNotDeleted ? 'UNDELETED' : 'ALL';
|
||||
}
|
||||
else if ($bAddNotDeleted)
|
||||
{
|
||||
$sCriteriasResult .= ' UNDELETED';
|
||||
}
|
||||
|
||||
return $sCriteriasResult;
|
||||
|
@ -1470,7 +1475,7 @@ class MailClient
|
|||
if ($oCacher && $oCacher->IsInited())
|
||||
{
|
||||
$sSerializedHash =
|
||||
'ThreadsMap/'.
|
||||
'ThreadsMap/UNDELETED/'.
|
||||
$this->oImapClient->GetLogginedUser().'@'.
|
||||
$this->oImapClient->GetConnectedHost().':'.
|
||||
$this->oImapClient->GetConnectedPort().'/'.
|
||||
|
@ -1492,7 +1497,7 @@ class MailClient
|
|||
$aThreadUids = array();
|
||||
try
|
||||
{
|
||||
$aThreadUids = $this->oImapClient->MessageSimpleThread();
|
||||
$aThreadUids = $this->oImapClient->MessageSimpleThread('UNDELETED');
|
||||
}
|
||||
catch (\MailSo\Imap\Exceptions\RuntimeException $oException)
|
||||
{
|
||||
|
@ -1638,6 +1643,283 @@ class MailClient
|
|||
$bCacher = false;
|
||||
$bSearch = false;
|
||||
|
||||
if (0 < $iMessageRealCount)
|
||||
{
|
||||
$bIndexAsUid = false;
|
||||
$aIndexOrUids = array();
|
||||
|
||||
$bSearch = 0 < \strlen($sSearch);
|
||||
|
||||
if ($bSearch || !$bUseThreadSortIfSupported)
|
||||
{
|
||||
$bIndexAsUid = true;
|
||||
$aIndexOrUids = null;
|
||||
|
||||
$sSearchCriterias = $this->getImapSearchCriterias($sSearch, 0, true);
|
||||
|
||||
if ($iMessageCacheCount < $iMessageRealCount && $oCacher && $oCacher->IsInited())
|
||||
{
|
||||
$sSerializedHash =
|
||||
($bUseSortIfSupported ? 'S': 'N').'/'.
|
||||
($bUseThreadSortIfSupported ? 'T': 'N').'/'.
|
||||
$this->oImapClient->GetLogginedUser().'@'.
|
||||
$this->oImapClient->GetConnectedHost().':'.
|
||||
$this->oImapClient->GetConnectedPort().'/'.
|
||||
$oMessageCollection->FolderName.'/'.
|
||||
$sSearchCriterias;
|
||||
|
||||
$sSerializedLog = '"'.$oMessageCollection->FolderName.'" / '.$sSearchCriterias.'';
|
||||
|
||||
$sSerialized = $oCacher->Get($sSerializedHash);
|
||||
if (!empty($sSerialized))
|
||||
{
|
||||
$aSerialized = @\unserialize($sSerialized);
|
||||
if (\is_array($aSerialized) && isset($aSerialized['FolderHash'], $aSerialized['Uids']) &&
|
||||
\is_array($aSerialized['Uids']) &&
|
||||
$oMessageCollection->FolderHash === $aSerialized['FolderHash'])
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Get Serialized UIDS from cache ('.$sSerializedLog.') [count:'.\count($aSerialized['Uids']).']');
|
||||
}
|
||||
|
||||
$aIndexOrUids = $aSerialized['Uids'];
|
||||
$bCacher = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!\is_array($aIndexOrUids))
|
||||
{
|
||||
if ($bUseSortIfSupported && !$bUseThreadSortIfSupported)
|
||||
{
|
||||
if ($bESortSupported)
|
||||
{
|
||||
$aESorthData = $this->oImapClient->MessageSimpleESort(array('ARRIVAL'), $sSearchCriterias, array('ALL'), $bIndexAsUid, '');
|
||||
if (isset($aESorthData['ALL']))
|
||||
{
|
||||
$aIndexOrUids = \MailSo\Base\Utils::ParseFetchSequence($aESorthData['ALL']);
|
||||
$aIndexOrUids = \array_reverse($aIndexOrUids);
|
||||
}
|
||||
|
||||
unset($aESorthData);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aIndexOrUids = $this->oImapClient->MessageSimpleSort(array('REVERSE ARRIVAL'), $sSearchCriterias, $bIndexAsUid);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!\MailSo\Base\Utils::IsAscii($sSearch))
|
||||
{
|
||||
try
|
||||
{
|
||||
if ($bESearchSupported)
|
||||
{
|
||||
$aESearchData = $this->oImapClient->MessageSimpleESearch($sSearchCriterias, array('ALL'), $bIndexAsUid, '', 'UTF-8');
|
||||
if (isset($aESearchData['ALL']))
|
||||
{
|
||||
$aIndexOrUids = \MailSo\Base\Utils::ParseFetchSequence($aESearchData['ALL']);
|
||||
$aIndexOrUids = \array_reverse($aIndexOrUids);
|
||||
}
|
||||
unset($aESearchData);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aIndexOrUids = $this->oImapClient->MessageSimpleSearch($sSearchCriterias, $bIndexAsUid, 'UTF-8');
|
||||
}
|
||||
}
|
||||
catch (\MailSo\Imap\Exceptions\NegativeResponseException $oException)
|
||||
{
|
||||
$oException = null;
|
||||
$aIndexOrUids = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (null === $aIndexOrUids)
|
||||
{
|
||||
if ($bESearchSupported)
|
||||
{
|
||||
$aESearchData = $this->oImapClient->MessageSimpleESearch($sSearchCriterias, array('ALL'), $bIndexAsUid);
|
||||
if (isset($aESearchData['ALL']))
|
||||
{
|
||||
$aIndexOrUids = \MailSo\Base\Utils::ParseFetchSequence($aESearchData['ALL']);
|
||||
$aIndexOrUids = \array_reverse($aIndexOrUids);
|
||||
}
|
||||
|
||||
unset($aESearchData);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aIndexOrUids = $this->oImapClient->MessageSimpleSearch($sSearchCriterias, $bIndexAsUid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($bUseThreadSortIfSupported && 1 < $iMessageCount)
|
||||
{
|
||||
$bIndexAsUid = true;
|
||||
$aThreads = $this->MessageListThreadsMap(
|
||||
$oMessageCollection->FolderName,
|
||||
$oMessageCollection->FolderHash,
|
||||
$oCacher);
|
||||
|
||||
$aIndexOrUids = $this->compileLineThreadUids($aThreads, $aLastCollapsedThreadUids, $aExpandedThreadsUids, 0);
|
||||
$iMessageCount = \count($aIndexOrUids);
|
||||
}
|
||||
else
|
||||
{
|
||||
$bIndexAsUid = false;
|
||||
$aIndexOrUids = array(1);
|
||||
if (1 < $iMessageCount)
|
||||
{
|
||||
$aIndexOrUids = \array_reverse(\range(1, $iMessageCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($bIndexAsUid && !$bCacher && \is_array($aIndexOrUids) && $oCacher && $oCacher->IsInited() && 0 < \strlen($sSerializedHash))
|
||||
{
|
||||
$oCacher->Set($sSerializedHash, \serialize(array(
|
||||
'FolderHash' => $oMessageCollection->FolderHash,
|
||||
'Uids' => $aIndexOrUids
|
||||
)));
|
||||
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Save Serialized UIDS to cache ('.$sSerializedLog.') [count:'.\count($aIndexOrUids).']');
|
||||
}
|
||||
}
|
||||
|
||||
if (\is_array($aIndexOrUids))
|
||||
{
|
||||
$oMessageCollection->MessageCount = $iMessageRealCount;
|
||||
$oMessageCollection->MessageUnseenCount = $iMessageUnseenCount;
|
||||
$oMessageCollection->MessageResultCount = 0 === \strlen($sSearch)
|
||||
? $iMessageCount : \count($aIndexOrUids);
|
||||
|
||||
if (0 < count($aIndexOrUids))
|
||||
{
|
||||
$iOffset = (0 > $iOffset) ? 0 : $iOffset;
|
||||
$aRequestIndexOrUids = \array_slice($aIndexOrUids, $iOffset, $iLimit);
|
||||
|
||||
$this->MessageListByRequestIndexOrUids($oMessageCollection, $aRequestIndexOrUids, $bIndexAsUid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$aLastCollapsedThreadUidsForPage = array();
|
||||
|
||||
if (!$bSearch && $bUseThreadSortIfSupported && 0 < \count($aThreads))
|
||||
{
|
||||
$oMessageCollection->ForeachList(function (/* @var $oMessage \MailSo\Mail\Message */ $oMessage) use (
|
||||
$aThreads, $aLastCollapsedThreadUids, &$aLastCollapsedThreadUidsForPage)
|
||||
{
|
||||
$iUid = $oMessage->Uid();
|
||||
if (in_array($iUid, $aLastCollapsedThreadUids))
|
||||
{
|
||||
$aLastCollapsedThreadUidsForPage[] = $iUid;
|
||||
}
|
||||
|
||||
if (isset($aThreads[$iUid]) && \is_array($aThreads[$iUid]) && 0 < \count($aThreads[$iUid]))
|
||||
{
|
||||
$oMessage->SetThreads($aThreads[$iUid]);
|
||||
$oMessage->SetThreadsLen(\count($aThreads[$iUid]));
|
||||
}
|
||||
else if (!isset($aThreads[$iUid]))
|
||||
{
|
||||
foreach ($aThreads as $iKeyUid => $mSubItem)
|
||||
{
|
||||
if (is_array($mSubItem) && in_array($iUid, $mSubItem))
|
||||
{
|
||||
$oMessage->SetParentThread($iKeyUid);
|
||||
$oMessage->SetThreadsLen(\count($mSubItem));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$oMessageCollection->LastCollapsedThreadUids = $aLastCollapsedThreadUidsForPage;
|
||||
}
|
||||
|
||||
return $oMessageCollection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*
|
||||
* @param string $sFolderName
|
||||
* @param int $iOffset = 0
|
||||
* @param int $iLimit = 10
|
||||
* @param string $sSearch = ''
|
||||
* @param string $sPrevUidNext = ''
|
||||
* @param mixed $oCacher = null
|
||||
* @param string $sCachePrefix = ''
|
||||
* @param bool $bUseSortIfSupported = false
|
||||
* @param bool $bUseThreadSortIfSupported = false
|
||||
* @param array $aExpandedThreadsUids = array()
|
||||
* @param bool $bUseESearchOrESortRequest = false
|
||||
*
|
||||
* @return \MailSo\Mail\MessageCollection
|
||||
*
|
||||
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
|
||||
* @throws \MailSo\Net\Exceptions\Exception
|
||||
* @throws \MailSo\Imap\Exceptions\Exception
|
||||
*/
|
||||
public function MessageListDepr($sFolderName, $iOffset = 0, $iLimit = 10, $sSearch = '', $sPrevUidNext = '',
|
||||
$oCacher = null, $bUseSortIfSupported = false, $bUseThreadSortIfSupported = false, $aExpandedThreadsUids = array(),
|
||||
$bUseESearchOrESortRequest = false)
|
||||
{
|
||||
$sSearch = \trim($sSearch);
|
||||
if (!\MailSo\Base\Validator::RangeInt($iOffset, 0) ||
|
||||
!\MailSo\Base\Validator::RangeInt($iLimit, 0, 999) ||
|
||||
!is_string($sSearch))
|
||||
{
|
||||
throw new \MailSo\Base\Exceptions\InvalidArgumentException();
|
||||
}
|
||||
|
||||
$this->oImapClient->FolderExamine($sFolderName);
|
||||
|
||||
$oMessageCollection = MessageCollection::NewInstance();
|
||||
$oMessageCollection->FolderName = $sFolderName;
|
||||
$oMessageCollection->Offset = $iOffset;
|
||||
$oMessageCollection->Limit = $iLimit;
|
||||
$oMessageCollection->Search = $sSearch;
|
||||
|
||||
$aLastCollapsedThreadUids = array();
|
||||
|
||||
$aThreads = array();
|
||||
$iMessageCount = 0;
|
||||
$iMessageRealCount = 0;
|
||||
$iMessageUnseenCount = 0;
|
||||
$iMessageCacheCount = 100;
|
||||
$sUidNext = '0';
|
||||
$sSerializedHash = '';
|
||||
$bESearchSupported = $bUseESearchOrESortRequest ? $this->oImapClient->IsSupported('ESEARCH') : false;
|
||||
$bUseSortIfSupported = $bUseSortIfSupported ? $this->oImapClient->IsSupported('SORT') : false;
|
||||
$bESortSupported = $bUseSortIfSupported && $bUseESearchOrESortRequest ? $this->oImapClient->IsSupported('ESORT') : false;
|
||||
$bUseThreadSortIfSupported = $bUseThreadSortIfSupported ?
|
||||
($this->oImapClient->IsSupported('THREAD=REFS') || $this->oImapClient->IsSupported('THREAD=REFERENCES') || $this->oImapClient->IsSupported('THREAD=ORDEREDSUBJECT')) : false;
|
||||
|
||||
if (!$oCacher || !($oCacher instanceof \MailSo\Cache\CacheClient))
|
||||
{
|
||||
$oCacher = null;
|
||||
}
|
||||
|
||||
$this->initFolderValues($sFolderName, $iMessageRealCount, $iMessageUnseenCount, $sUidNext);
|
||||
$iMessageCount = $iMessageRealCount;
|
||||
|
||||
$oMessageCollection->FolderHash = self::GenerateHash($sFolderName, $iMessageRealCount, $iMessageUnseenCount, $sUidNext);
|
||||
$oMessageCollection->UidNext = $sUidNext;
|
||||
$oMessageCollection->NewMessages = $this->getFolderNextMessageInformation($sFolderName, $sPrevUidNext, $sUidNext);
|
||||
|
||||
$bCacher = false;
|
||||
$bSearch = false;
|
||||
|
||||
if (0 < $iMessageRealCount)
|
||||
{
|
||||
$bIndexAsUid = false;
|
||||
|
|
|
@ -797,7 +797,7 @@ class Actions
|
|||
'][GUID:'.\MailSo\Log\Logger::Guid().']');
|
||||
|
||||
$this->oLogger->Write(
|
||||
' ['.$oHttp->GetMethod().'] '.$oHttp->GetScheme().'://'.$oHttp->GetHost(false, false).$oHttp->GetServer('REQUEST_URI', ''),
|
||||
'['.$oHttp->GetMethod().'] '.$oHttp->GetScheme().'://'.$oHttp->GetHost(false, false).$oHttp->GetServer('REQUEST_URI', ''),
|
||||
\MailSo\Log\Enumerations\Type::NOTE, 'REQUEST');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -146,8 +146,10 @@ class Service
|
|||
return $this;
|
||||
}
|
||||
|
||||
$bIndex = true;
|
||||
if (0 < \count($aPaths) && !empty($aPaths[0]) && !$bAdmin && 'index' !== $aPaths[0])
|
||||
{
|
||||
$bIndex = false;
|
||||
$sMethodName = 'Service'.$aPaths[0];
|
||||
if (\method_exists($this->oServiceActions, $sMethodName) &&
|
||||
\is_callable(array($this->oServiceActions, $sMethodName)))
|
||||
|
@ -157,10 +159,11 @@ class Service
|
|||
}
|
||||
else if (!$this->oActions->Plugins()->RunAdditionalPart($aPaths[0], $aPaths))
|
||||
{
|
||||
$this->oActions->Logger()->Write('Unknown request', \MailSo\Log\Enumerations\Type::WARNING, 'RESPONSE');
|
||||
$bIndex = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if ($bIndex)
|
||||
{
|
||||
@header('Content-Type: text/html; charset=utf-8');
|
||||
$this->oHttp->ServerNoCache();
|
||||
|
@ -206,9 +209,9 @@ class Service
|
|||
|
||||
$sResult .= '<!--';
|
||||
$sResult .= ' [version:'.APP_VERSION;
|
||||
$sResult .= '][time:'.substr(\microtime(true) - APP_START, 0, 6);
|
||||
$sResult .= '][time:'.\substr(\microtime(true) - APP_START, 0, 6);
|
||||
$sResult .= '][cached:'.($bCached ? 'true' : 'false');
|
||||
$sResult .= '][session:'.md5(\RainLoop\Utils::GetShortToken());
|
||||
$sResult .= '][session:'.\md5(\RainLoop\Utils::GetShortToken());
|
||||
$sResult .= '] -->';
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue