Cleanup request Folders response

This commit is contained in:
djmaze 2021-11-24 15:18:13 +01:00
parent e27fb46500
commit 7afbc05d18
7 changed files with 78 additions and 135 deletions

View file

@ -25,7 +25,6 @@ export class AbstractCollectionModel extends Array
if (json) { if (json) {
if ('Collection/'+this.name.replace('Model', '') === json['@Object']) { if ('Collection/'+this.name.replace('Model', '') === json['@Object']) {
Object.entries(json).forEach(([key, value]) => '@' !== key[0] && (result[key] = value)); Object.entries(json).forEach(([key, value]) => '@' !== key[0] && (result[key] = value));
// json[@Count]
json = json['@Collection']; json = json['@Collection'];
} }
if (isArray(json)) { if (isArray(json)) {

View file

@ -1,7 +1,7 @@
import { AbstractCollectionModel } from 'Model/AbstractCollection'; import { AbstractCollectionModel } from 'Model/AbstractCollection';
import { UNUSED_OPTION_VALUE } from 'Common/Consts'; import { UNUSED_OPTION_VALUE } from 'Common/Consts';
import { isArray, pInt, getKeyByValue } from 'Common/Utils'; import { isArray, getKeyByValue } from 'Common/Utils';
import { ClientSideKeyName, FolderType, FolderMetadataKeys } from 'Common/EnumsUser'; import { ClientSideKeyName, FolderType, FolderMetadataKeys } from 'Common/EnumsUser';
import * as Cache from 'Common/Cache'; import * as Cache from 'Common/Cache';
import { Settings, SettingsGet } from 'Common/Globals'; import { Settings, SettingsGet } from 'Common/Globals';
@ -113,10 +113,7 @@ export class FolderCollectionModel extends AbstractCollectionModel
} }
storeIt() { storeIt() {
const cnt = pInt(this.CountRec); FolderUserStore.displaySpecSetting(Settings.app('folderSpecLimit') < this.CountRec);
FolderUserStore.displaySpecSetting(0 >= cnt
|| Math.max(10, Math.min(100, pInt(Settings.app('folderSpecLimit')))) < cnt);
if (SystemFolders && if (SystemFolders &&
!('' + !('' +
@ -214,7 +211,7 @@ export class FolderModel extends AbstractModel {
selected: false, selected: false,
edited: false, edited: false,
subscribed: true, subscribed: true,
checkable: false, checkable: false, // Check for new messages
deleteAccess: false, deleteAccess: false,
nameForEdit: '', nameForEdit: '',

View file

@ -17,9 +17,9 @@ namespace MailSo\Base;
*/ */
abstract class Collection extends \ArrayObject implements \JsonSerializable abstract class Collection extends \ArrayObject implements \JsonSerializable
{ {
function __construct($input = array(), int $flags = 0, string $iterator_class = "ArrayIterator") function __construct($input = array(), int $flags = 0, string $iterator_class = 'ArrayIterator')
{ {
parent::__construct(); parent::__construct(/*[], $flags, $iterator_class*/);
foreach ($input as $item) { foreach ($input as $item) {
$this->append($item); $this->append($item);
} }
@ -79,7 +79,6 @@ abstract class Collection extends \ArrayObject implements \JsonSerializable
$aNames = \explode('\\', \get_class($this)); $aNames = \explode('\\', \get_class($this));
return array( return array(
'@Object' => 'Collection/' . \end($aNames), '@Object' => 'Collection/' . \end($aNames),
'@Count' => $this->count(),
'@Collection' => $this->getArrayCopy() '@Collection' => $this->getArrayCopy()
); );
} }

View file

@ -67,7 +67,9 @@ class ResponseCollection extends \MailSo\Base\Collection
} }
if (\is_array($aList) && \count($aList)) { if (\is_array($aList) && \count($aList)) {
return \array_map('strtoupper', $aList); $aList = \array_map('strtoupper', $aList);
\sort($aList);
return $aList;
} }
} }
return null; return null;

View file

@ -17,34 +17,12 @@ namespace MailSo\Mail;
*/ */
class FolderCollection extends \MailSo\Base\Collection class FolderCollection extends \MailSo\Base\Collection
{ {
/**
* @var string
*/
public $Namespace = '';
/**
* @var string
*/
public $FoldersHash = '';
/**
* @var bool
*/
public $IsThreadsSupported = false;
/** /**
* @var bool * @var bool
*/ */
public $Optimized = false; public $Optimized = false;
/** public $TotalCount = 0;
* @var array
*/
public $SystemFolders = array();
public $quotaUsage = 0;
public $quotaLimit = 0;
public $capabilities = array();
public function append($oFolder, bool $bToTop = false) : void public function append($oFolder, bool $bToTop = false) : void
{ {
@ -54,45 +32,20 @@ class FolderCollection extends \MailSo\Base\Collection
public function GetByFullName(string $sFullName) : ?Folder public function GetByFullName(string $sFullName) : ?Folder
{ {
$mResult = null; foreach ($this as $oFolder) {
foreach ($this as $oFolder) if ($oFolder->FullName() === $sFullName) {
{ return $oFolder;
if ($oFolder->FullName() === $sFullName)
{
$mResult = $oFolder;
break;
} }
else if ($oFolder->HasSubFolders())
{ if ($oFolder->HasSubFolders()) {
$mResult = $oFolder->SubFolders(true)->GetByFullName($sFullName); $mResult = $oFolder->SubFolders(true)->GetByFullName($sFullName);
if ($mResult) if ($mResult) {
{ return $mResult;
break;
} }
} }
} }
return $mResult; return null;
}
public function CountRec() : int
{
$iResult = $this->Count();
foreach ($this as $oFolder)
{
if ($oFolder)
{
$oSub = $oFolder->SubFolders();
$iResult += $oSub ? $oSub->CountRec() : 0;
}
}
return $iResult;
}
public function GetNamespace() : string
{
return $this->Namespace;
} }
public function FindDelimiter() : string public function FindDelimiter() : string
@ -108,18 +61,11 @@ class FolderCollection extends \MailSo\Base\Collection
return $oFolder ? $oFolder->Delimiter() : '/'; return $oFolder ? $oFolder->Delimiter() : '/';
} }
public function SetNamespace(string $sNamespace) : self
{
$this->Namespace = $sNamespace;
return $this;
}
public function AddWithPositionSearch(Folder $oMailFolder) : void public function AddWithPositionSearch(Folder $oMailFolder) : void
{ {
foreach ($this as $oItemFolder) foreach ($this as $oItemFolder)
{ {
if (0 === \strpos($oMailFolder->FullName(), $oItemFolder->FullName().$oItemFolder->Delimiter())) if (\str_starts_with($oMailFolder->FullName(), $oItemFolder->FullName().$oItemFolder->Delimiter()))
{ {
$oItemFolder->SubFolders(true)->AddWithPositionSearch($oMailFolder); $oItemFolder->SubFolders(true)->AddWithPositionSearch($oMailFolder);
return; return;
@ -128,19 +74,4 @@ class FolderCollection extends \MailSo\Base\Collection
$this->append($oMailFolder); $this->append($oMailFolder);
} }
public function jsonSerialize()
{
return \array_merge(parent::jsonSerialize(), array(
'Namespace' => $this->GetNamespace(),
'FoldersHash' => $this->FoldersHash ?: '',
'IsThreadsSupported' => $this->IsThreadsSupported,
'quotaUsage' => $this->quotaUsage,
'quotaLimit' => $this->quotaLimit,
'Optimized' => $this->Optimized,
'CountRec' => $this->CountRec(),
'SystemFolders' => empty($this->SystemFolders) ? null : $this->SystemFolders,
'Capabilities' => \array_values($this->capabilities)
));
}
} }

View file

@ -61,6 +61,11 @@ class MailClient
return $this->oImapClient->IsLoggined(); return $this->oImapClient->IsLoggined();
} }
public function Capabilities() : array
{
return $this->oImapClient->Capability();
}
private function getEnvelopeOrHeadersRequestStringForSimpleList() : string private function getEnvelopeOrHeadersRequestStringForSimpleList() : string
{ {
return \MailSo\Imap\Enumerations\FetchType::BuildBodyCustomHeaderRequest(array( return \MailSo\Imap\Enumerations\FetchType::BuildBodyCustomHeaderRequest(array(
@ -1204,12 +1209,8 @@ class MailClient
public function Folders(string $sParent, string $sListPattern, bool $bUseListSubscribeStatus, int $iOptimizationLimit, bool $bUseListStatus) : ?FolderCollection public function Folders(string $sParent, string $sListPattern, bool $bUseListSubscribeStatus, int $iOptimizationLimit, bool $bUseListStatus) : ?FolderCollection
{ {
$aCapabilities = \array_filter($this->oImapClient->Capability(), function($item){
return !\preg_match('/^(IMAP|AUTH|LOGIN|SASL)/', $item);
});
$aImapSubscribedFoldersHelper = null; $aImapSubscribedFoldersHelper = null;
if (\in_array('LIST-EXTENDED', $aCapabilities)) { if ($this->oImapClient->IsSupported('LIST-EXTENDED')) {
$bUseListSubscribeStatus = false; $bUseListSubscribeStatus = false;
} else if ($bUseListSubscribeStatus) { } else if ($bUseListSubscribeStatus) {
//\error_log('RFC5258 not supported, using LSUB'); //\error_log('RFC5258 not supported, using LSUB');
@ -1228,13 +1229,7 @@ class MailClient
} }
} }
$bUseListStatus = $bUseListStatus && \in_array('LIST-STATUS', $aCapabilities); $bUseListStatus = $bUseListStatus && $this->oImapClient->IsSupported('LIST-STATUS');
if (!$bUseListStatus) {
$key = \array_search('LIST-STATUS', $aCapabilities);
if (false !== $key) {
unset($aCapabilities[$key]);
}
}
$aFolders = $bUseListStatus $aFolders = $bUseListStatus
? $this->oImapClient->FolderStatusList($sParent, $sListPattern) ? $this->oImapClient->FolderStatusList($sParent, $sListPattern)
@ -1244,9 +1239,7 @@ class MailClient
} }
$oFolderCollection = new FolderCollection; $oFolderCollection = new FolderCollection;
$oFolderCollection->IsThreadsSupported = $this->IsThreadsSupported();
$oFolderCollection->Optimized = 10 < $iOptimizationLimit && \count($aFolders) > $iOptimizationLimit; $oFolderCollection->Optimized = 10 < $iOptimizationLimit && \count($aFolders) > $iOptimizationLimit;
$oFolderCollection->capabilities = $aCapabilities;
$sINBOX = 'INBOX'; $sINBOX = 'INBOX';
$aSortedByLenImapFolders = array(); $aSortedByLenImapFolders = array();
@ -1303,7 +1296,11 @@ class MailClient
$aSortedByLenImapFolders["\x00".$sINBOX] = $aSortedByLenImapFolders[$sINBOX]; $aSortedByLenImapFolders["\x00".$sINBOX] = $aSortedByLenImapFolders[$sINBOX];
unset($aSortedByLenImapFolders[$sINBOX]); unset($aSortedByLenImapFolders[$sINBOX]);
} }
/*
// TODO: use active language
$collator = new \Collator('en_US');
\uksort($aSortedByLenImapFolders, static fn($a, $b) => $collator->compare($a, $b));
*/
\uksort($aSortedByLenImapFolders, 'strnatcasecmp'); \uksort($aSortedByLenImapFolders, 'strnatcasecmp');
foreach ($aSortedByLenImapFolders as $oMailFolder) foreach ($aSortedByLenImapFolders as $oMailFolder)
@ -1311,13 +1308,9 @@ class MailClient
$oFolderCollection->AddWithPositionSearch($oMailFolder); $oFolderCollection->AddWithPositionSearch($oMailFolder);
} }
unset($aSortedByLenImapFolders); $oFolderCollection->TotalCount = \count($aSortedByLenImapFolders);
$oNamespace = $this->oImapClient->GetNamespace(); unset($aSortedByLenImapFolders);
if ($oNamespace)
{
$oFolderCollection->SetNamespace($oNamespace->GetPersonalNamespace());
}
return $oFolderCollection; return $oFolderCollection;
} }
@ -1530,6 +1523,12 @@ class MailClient
return $this; return $this;
} }
public function GetNamespace() : string
{
$oNamespace = $this->oImapClient->GetNamespace();
return $oNamespace ? $oNamespace->GetPersonalNamespace() : '';
}
/** /**
* RFC 5464 * RFC 5464
*/ */

View file

@ -12,27 +12,11 @@ trait Folders
private function getFolderCollection(bool $HideUnsubscribed) : ?\MailSo\Mail\FolderCollection private function getFolderCollection(bool $HideUnsubscribed) : ?\MailSo\Mail\FolderCollection
{ {
$oFolderCollection = $this->MailClient()->Folders('', '*', return $this->MailClient()->Folders('', '*',
$HideUnsubscribed, $HideUnsubscribed,
(int) $this->Config()->Get('labs', 'imap_folder_list_limit', 200), (int) $this->Config()->Get('labs', 'imap_folder_list_limit', 200),
(bool) $this->Config()->Get('labs', 'imap_use_list_status', true) (bool) $this->Config()->Get('labs', 'imap_use_list_status', true)
); );
if ($oFolderCollection) {
$oAccount = $this->getAccountFromToken();
if ($this->GetCapa(false, Capa::QUOTA, $oAccount)) {
try {
// $aQuota = $this->MailClient()->Quota();
$aQuota = $this->MailClient()->QuotaRoot();
$oFolderCollection->quotaUsage = $aQuota ? $aQuota[0] * 1024 : null;
$oFolderCollection->quotaLimit = $aQuota ? $aQuota[1] * 1024 : null;
} catch (\Throwable $oException) {
// ignore
}
}
}
return $oFolderCollection;
} }
public function DoFolders() : array public function DoFolders() : array
@ -49,13 +33,14 @@ trait Folders
if ($oFolderCollection) if ($oFolderCollection)
{ {
$sNamespace = $this->MailClient()->GetNamespace();
$this->Plugins()->RunHook('filter.folders-post', array($oAccount, $oFolderCollection)); $this->Plugins()->RunHook('filter.folders-post', array($oAccount, $oFolderCollection));
$oSettingsLocal = $this->SettingsProvider(true)->Load($oAccount); $oSettingsLocal = $this->SettingsProvider(true)->Load($oAccount);
$aSystemFolders = array(); $aSystemFolders = array();
$this->recFoldersTypes($oAccount, $oFolderCollection, $aSystemFolders); $this->recFoldersTypes($oAccount, $oFolderCollection, $aSystemFolders);
$oFolderCollection->SystemFolders = $aSystemFolders;
if (!$this->Config()->Get('labs', 'use_imap_sort', true)) { if (!$this->Config()->Get('labs', 'use_imap_sort', true)) {
$oFolderCollection->capabilities = \array_filter($oFolderCollection->capabilities, function($item){ $oFolderCollection->capabilities = \array_filter($oFolderCollection->capabilities, function($item){
@ -67,8 +52,7 @@ trait Folders
{ {
$bDoItAgain = false; $bDoItAgain = false;
$sNamespace = $oFolderCollection->GetNamespace(); $sParent = \substr($sNamespace, 0, -1);
$sParent = empty($sNamespace) ? '' : \substr($sNamespace, 0, -1);
$sDelimiter = $oFolderCollection->FindDelimiter(); $sDelimiter = $oFolderCollection->FindDelimiter();
@ -157,17 +141,49 @@ trait Folders
{ {
$aSystemFolders = array(); $aSystemFolders = array();
$this->recFoldersTypes($oAccount, $oFolderCollection, $aSystemFolders); $this->recFoldersTypes($oAccount, $oFolderCollection, $aSystemFolders);
$oFolderCollection->SystemFolders = $aSystemFolders;
} }
} }
} }
if ($oFolderCollection) if ($oFolderCollection)
{ {
$oFolderCollection->FoldersHash = \md5(\implode("\x0", $this->recFoldersNames($oFolderCollection))); $this->Plugins()->RunHook('filter.folders-complete', array($oAccount, $oFolderCollection));
}
$this->Plugins()->RunHook('filter.folders-complete', array($oAccount, $oFolderCollection)); $aQuota = null;
if ($this->GetCapa(false, Capa::QUOTA, $this->getAccountFromToken())) {
try {
// $aQuota = $this->MailClient()->Quota();
$aQuota = $this->MailClient()->QuotaRoot();
} catch (\Throwable $oException) {
// ignore
}
}
$aCapabilities = \array_filter($this->MailClient()->Capabilities(), function($item){
return !\preg_match('/^(IMAP|AUTH|LOGIN|SASL)/', $item);
});
if (!$this->Config()->Get('labs', 'imap_use_list_status', true)) {
$key = \array_search('LIST-STATUS', $aCapabilities);
if (false !== $key) {
unset($aCapabilities[$key]);
}
}
$oFolderCollection = \array_merge(
$oFolderCollection->jsonSerialize(),
array(
'quotaUsage' => $aQuota ? $aQuota[0] * 1024 : null,
'quotaLimit' => $aQuota ? $aQuota[1] * 1024 : null,
'Namespace' => $sNamespace,
'FoldersHash' => \md5(\implode("\x0", $this->recFoldersNames($oFolderCollection))),
'IsThreadsSupported' => $this->MailClient()->IsThreadsSupported(),
'Optimized' => $oFolderCollection->Optimized,
'CountRec' => $oFolderCollection->TotalCount,
'SystemFolders' => empty($aSystemFolders) ? null : $aSystemFolders,
'Capabilities' => \array_values($aCapabilities)
)
);
}
} }
return $this->DefaultResponse(__FUNCTION__, $oFolderCollection); return $this->DefaultResponse(__FUNCTION__, $oFolderCollection);