mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-06-28 06:46:27 +00:00
Added: support all namespaces
This commit is contained in:
@@ -574,8 +574,8 @@ trait Folders
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ACL RIGHTS=texk
|
||||
/*
|
||||
// RFC 4314
|
||||
if ($this->hasCapability('ACL') || $this->CapabilityValue('RIGHTS')) {
|
||||
foreach ($oFolderCollection as $oFolder) {
|
||||
if ($oFolder->Selectable()) try {
|
||||
@@ -586,7 +586,7 @@ trait Folders
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
if (!$bInbox && !$sParentFolderName && !isset($oFolderCollection['INBOX'])) {
|
||||
$oFolderCollection['INBOX'] = new Folder('INBOX', $sDelimiter);
|
||||
}
|
||||
|
||||
@@ -24,33 +24,36 @@ trait Metadata
|
||||
* Dovecot 2.2+ supports fetching all METADATA at once (wildcard).
|
||||
* RFC 5464 doesn't specify this, but its earlier draft did, and Kolab uses it.
|
||||
*/
|
||||
private ?array $allMetadata = null;
|
||||
public function getAllMetadata() : array
|
||||
{
|
||||
$aReturn = array();
|
||||
try {
|
||||
$arguments = [
|
||||
'(DEPTH infinity)',
|
||||
$this->EscapeString('*')
|
||||
];
|
||||
$arguments[] = '(' . \implode(' ', \array_map([$this, 'EscapeString'], ['/shared', '/private'])) . ')';
|
||||
$this->SendRequest('GETMETADATA', $arguments);
|
||||
foreach ($this->yieldUntaggedResponses() as $oResponse) {
|
||||
if (isset($oResponse->ResponseList[3])
|
||||
&& \is_array($oResponse->ResponseList[3])
|
||||
&& 'METADATA' === $oResponse->ResponseList[1]
|
||||
) {
|
||||
$aMetadata = array();
|
||||
$c = \count($oResponse->ResponseList[3]);
|
||||
for ($i = 0; $i < $c; $i += 2) {
|
||||
$aMetadata[$oResponse->ResponseList[3][$i]] = $oResponse->ResponseList[3][$i+1];
|
||||
if (null === $this->allMetadata) {
|
||||
$this->allMetadata = array();
|
||||
try {
|
||||
$arguments = [
|
||||
'(DEPTH infinity)',
|
||||
$this->EscapeString('*')
|
||||
];
|
||||
$arguments[] = '(' . \implode(' ', \array_map([$this, 'EscapeString'], ['/shared', '/private'])) . ')';
|
||||
$this->SendRequest('GETMETADATA', $arguments);
|
||||
foreach ($this->yieldUntaggedResponses() as $oResponse) {
|
||||
if (isset($oResponse->ResponseList[3])
|
||||
&& \is_array($oResponse->ResponseList[3])
|
||||
&& 'METADATA' === $oResponse->ResponseList[1]
|
||||
) {
|
||||
$aMetadata = array();
|
||||
$c = \count($oResponse->ResponseList[3]);
|
||||
for ($i = 0; $i < $c; $i += 2) {
|
||||
$aMetadata[$oResponse->ResponseList[3][$i]] = $oResponse->ResponseList[3][$i+1];
|
||||
}
|
||||
$this->allMetadata[$this->toUTF8($oResponse->ResponseList[2])] = $aMetadata;
|
||||
}
|
||||
$aReturn[$this->toUTF8($oResponse->ResponseList[2])] = $aMetadata;
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
//\SnappyMail\Log::warning('IMAP', $e->getMessage());
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
//\SnappyMail\Log::warning('IMAP', $e->getMessage());
|
||||
}
|
||||
return $aReturn;
|
||||
return $this->allMetadata;
|
||||
}
|
||||
|
||||
public function getMetadata(string $sFolderName, array $aEntries, array $aOptions = []) : array
|
||||
|
||||
@@ -363,7 +363,7 @@ class ImapClient extends \MailSo\Net\NetClient
|
||||
* @throws \MailSo\Net\Exceptions\*
|
||||
* @throws \MailSo\Imap\Exceptions\*
|
||||
*/
|
||||
public function GetNamespace() : ?NamespaceResult
|
||||
public function GetNamespaces() : ?NamespaceResult
|
||||
{
|
||||
if (!$this->hasCapability('NAMESPACE')) {
|
||||
return null;
|
||||
@@ -384,17 +384,6 @@ class ImapClient extends \MailSo\Net\NetClient
|
||||
}
|
||||
}
|
||||
|
||||
public function GetPrivateNamespace() : string
|
||||
{
|
||||
$oNamespace = $this->GetNamespace();
|
||||
return $oNamespace ? $oNamespace->GetPrivateNamespace() : '';
|
||||
}
|
||||
/** Deprecated */
|
||||
public function GetPersonalNamespace() : string
|
||||
{
|
||||
return $this->GetPrivateNamespace();
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 7889
|
||||
* APPENDLIMIT=<number> indicates that the IMAP server has the same upload limit for all mailboxes.
|
||||
@@ -523,6 +512,7 @@ class ImapClient extends \MailSo\Net\NetClient
|
||||
if ($oResponse->IsStatusResponse
|
||||
&& Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType
|
||||
&& Enumerations\ResponseStatus::PREAUTH === $oResponse->StatusOrIndex
|
||||
// && (Enumerations\ResponseStatus::PREAUTH === $oResponse->StatusOrIndex || Enumerations\ResponseStatus::BYE === $oResponse->StatusOrIndex)
|
||||
) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -15,42 +15,71 @@ namespace MailSo\Imap;
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
*/
|
||||
class NamespaceResult
|
||||
class NamespaceResult implements \JsonSerializable
|
||||
{
|
||||
// prefix => separator
|
||||
private array $namespaces = [
|
||||
// '' => '.', // default
|
||||
// 'virtual.' => '.',
|
||||
// 'shared.' => '.',
|
||||
// etc.
|
||||
];
|
||||
public array
|
||||
$aPersonal = [],
|
||||
$aOtherUsers = [],
|
||||
$aShared = [];
|
||||
|
||||
function __construct(Response $oImapResponse)
|
||||
{
|
||||
// * NAMESPACE (("" ".")("virtual." ".")) (("shared." ".")) NIL\r\n
|
||||
$i = 1;
|
||||
while (isset($oImapResponse->ResponseList[++$i])) {
|
||||
$entries = $oImapResponse->ResponseList[$i];
|
||||
if ($entries) {
|
||||
foreach ($entries as $entry) {
|
||||
if (\is_array($entry) && 2 <= \count($entry)) {
|
||||
$this->namespaces[$entry[0]] = $entry[1];
|
||||
}
|
||||
if (!empty($oImapResponse->ResponseList[2])) {
|
||||
foreach ($oImapResponse->ResponseList[2] as $entry) {
|
||||
if (\is_array($entry) && 2 <= \count($entry)) {
|
||||
$this->aPersonal[] = [
|
||||
'prefix' => \array_shift($entry),
|
||||
'separator' => \array_shift($entry),
|
||||
'extension' => $entry
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($oImapResponse->ResponseList[3])) {
|
||||
foreach ($oImapResponse->ResponseList[3] as $entry) {
|
||||
if (\is_array($entry) && 2 <= \count($entry)) {
|
||||
$this->aOtherUsers[] = [
|
||||
'prefix' => \array_shift($entry),
|
||||
'separator' => \array_shift($entry),
|
||||
'extension' => $entry
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($oImapResponse->ResponseList[4])) {
|
||||
foreach ($oImapResponse->ResponseList[4] as $entry) {
|
||||
if (\is_array($entry) && 2 <= \count($entry)) {
|
||||
$this->aShared[] = [
|
||||
'prefix' => \array_shift($entry),
|
||||
'separator' => \array_shift($entry),
|
||||
'extension' => $entry
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function GetPrivateNamespace() : string
|
||||
public function GetPersonalPrefix() : string
|
||||
{
|
||||
$sName = '';
|
||||
if (isset($oImapResponse->ResponseList[2][0][0])) {
|
||||
$sName = $oImapResponse->ResponseList[2][0][0];
|
||||
$sSeparator = $oImapResponse->ResponseList[2][0][1];
|
||||
if ('INBOX'.$sSeparator === \substr(\strtoupper($sName), 0, 6)) {
|
||||
$sName = 'INBOX'.$sSeparator.\substr($sName, 6);
|
||||
$sPrefix = '';
|
||||
if (isset($this->aPersonal[0])) {
|
||||
$sPrefix = $this->aPersonal[0]['prefix'];
|
||||
$sSeparator = $this->aPersonal[0]['separator'];
|
||||
if ('INBOX'.$sSeparator === \substr(\strtoupper($sPrefix), 0, 6)) {
|
||||
$sPrefix = 'INBOX'.$sSeparator.\substr($sPrefix, 6);
|
||||
};
|
||||
}
|
||||
return $sName;
|
||||
return $sPrefix;
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return array(
|
||||
'@Object' => 'Object/Namespaces',
|
||||
'personal' => $this->aPersonal,
|
||||
'users' => $this->aOtherUsers,
|
||||
'shared' => $this->aShared,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,24 @@ trait Folders
|
||||
$HideUnsubscribed = (bool) $oSettingsLocal->GetConf('HideUnsubscribed', $HideUnsubscribed);
|
||||
}
|
||||
|
||||
$oNamespaces = $this->ImapClient()->GetNamespaces();
|
||||
$oFolderCollection = $this->MailClient()->Folders('', '*', $HideUnsubscribed);
|
||||
if (isset($oNamespaces->aOtherUsers[0])) {
|
||||
$oCollection = $this->MailClient()->Folders($oNamespaces->aOtherUsers[0]['prefix'], '*', $HideUnsubscribed);
|
||||
if ($oCollection) {
|
||||
foreach ($oCollection as $oFolder) {
|
||||
$oFolderCollection[$oFolder->FullName] = $oFolder;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($oNamespaces->aShared[0])) {
|
||||
$oCollection = $this->MailClient()->Folders($oNamespaces->aShared[0]['prefix'], '*', $HideUnsubscribed);
|
||||
if ($oCollection) {
|
||||
foreach ($oCollection as $oFolder) {
|
||||
$oFolderCollection[$oFolder->FullName] = $oFolder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($oFolderCollection) {
|
||||
$aQuota = null;
|
||||
@@ -77,7 +94,8 @@ trait Folders
|
||||
array(
|
||||
'quotaUsage' => $aQuota ? $aQuota[0] * 1024 : null,
|
||||
'quotaLimit' => $aQuota ? $aQuota[1] * 1024 : null,
|
||||
'namespace' => $this->ImapClient()->GetPrivateNamespace(),
|
||||
'namespace' => $oNamespaces->GetPersonalPrefix(),
|
||||
'namespaces' => $oNamespaces,
|
||||
'capabilities' => $aCapabilities
|
||||
)
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user