mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-07 16:37:02 +03:00
Improved support RFC8474 (MAILBOXID, EMAILID, THREADID) for RFC8621 section 4.1.1
This commit is contained in:
parent
a43fadb4e8
commit
a073e7f308
9 changed files with 69 additions and 18 deletions
|
|
@ -119,6 +119,10 @@ trait Folders
|
||||||
}
|
}
|
||||||
if ($this->IsSupported('OBJECTID')) {
|
if ($this->IsSupported('OBJECTID')) {
|
||||||
$aStatusItems[] = FolderResponseStatus::MAILBOXID;
|
$aStatusItems[] = FolderResponseStatus::MAILBOXID;
|
||||||
|
/*
|
||||||
|
} else if ($this->IsSupported('X-DOVECOT')) {
|
||||||
|
$aFetchItems[] = 'X-GUID';
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
$oFolderInfo = $this->oCurrentFolderInfo;
|
$oFolderInfo = $this->oCurrentFolderInfo;
|
||||||
|
|
@ -341,6 +345,9 @@ trait Folders
|
||||||
// $oResult->IsWritable = true;
|
// $oResult->IsWritable = true;
|
||||||
} else if ('NOMODSEQ' === $key) {
|
} else if ('NOMODSEQ' === $key) {
|
||||||
// https://datatracker.ietf.org/doc/html/rfc4551#section-3.1.2
|
// https://datatracker.ietf.org/doc/html/rfc4551#section-3.1.2
|
||||||
|
} else if ('MAILBOXID' === $key) {
|
||||||
|
// https://www.rfc-editor.org/rfc/rfc8474#section-4.2
|
||||||
|
$oResult->MAILBOXID = $oResponse->OptionalResponse[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -409,7 +416,11 @@ trait Folders
|
||||||
}
|
}
|
||||||
// RFC 8474
|
// RFC 8474
|
||||||
if ($this->IsSupported('OBJECTID')) {
|
if ($this->IsSupported('OBJECTID')) {
|
||||||
$aTypes[] = FolderStatus::MAILBOXID;
|
$aL[] = FolderStatus::MAILBOXID;
|
||||||
|
/*
|
||||||
|
} else if ($this->IsSupported('X-DOVECOT')) {
|
||||||
|
$aL[] = 'X-GUID';
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
$aReturnParams[] = 'STATUS';
|
$aReturnParams[] = 'STATUS';
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,23 @@ trait Messages
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ($this->IsSupported('OBJECTID')) {
|
||||||
|
$aFetchItems[] = FetchType::EMAILID;
|
||||||
|
$aFetchItems[] = FetchType::THREADID;
|
||||||
|
} else if ($this->IsSupported('X-GM-EXT-1')) {
|
||||||
|
// https://developers.google.com/gmail/imap/imap-extensions
|
||||||
|
$aFetchItems[] = 'X-GM-MSGID';
|
||||||
|
$aFetchItems[] = 'X-GM-THRID';
|
||||||
|
/*
|
||||||
|
} else if ($this->IsSupported('X-DOVECOT')) {
|
||||||
|
$aFetchItems[] = 'X-GUID';
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if ($this->IsSupported('X-GM-EXT-1') && \in_array(FetchType::FLAGS, $aFetchItems)) {
|
||||||
|
$aFetchItems[] = 'X-GM-LABELS';
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
$aParams = array($sIndexRange, $aFetchItems);
|
$aParams = array($sIndexRange, $aFetchItems);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,9 @@ abstract class FetchType
|
||||||
const BINARY_SIZE = 'BINARY.SIZE';
|
const BINARY_SIZE = 'BINARY.SIZE';
|
||||||
// RFC 4551
|
// RFC 4551
|
||||||
const MODSEQ = 'MODSEQ';
|
const MODSEQ = 'MODSEQ';
|
||||||
|
// RFC 8474
|
||||||
|
const EMAILID = 'EMAILID';
|
||||||
|
const THREADID = 'THREADID';
|
||||||
|
|
||||||
public static function BuildBodyCustomHeaderRequest(array $aHeaders, bool $bPeek = true) : string
|
public static function BuildBodyCustomHeaderRequest(array $aHeaders, bool $bPeek = true) : string
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ class FolderInformation implements \JsonSerializable
|
||||||
public function jsonSerialize()
|
public function jsonSerialize()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
|
'id' => $this->MAILBOXID,
|
||||||
'Name' => $this->FolderName,
|
'Name' => $this->FolderName,
|
||||||
'Flags' => $this->Flags,
|
'Flags' => $this->Flags,
|
||||||
'PermanentFlags' => $this->PermanentFlags,
|
'PermanentFlags' => $this->PermanentFlags,
|
||||||
|
|
@ -73,7 +74,6 @@ class FolderInformation implements \JsonSerializable
|
||||||
'UidValidity' => $this->UIDVALIDITY,
|
'UidValidity' => $this->UIDVALIDITY,
|
||||||
'Highestmodseq' => $this->HIGHESTMODSEQ,
|
'Highestmodseq' => $this->HIGHESTMODSEQ,
|
||||||
'Appendlimit' => $this->APPENDLIMIT,
|
'Appendlimit' => $this->APPENDLIMIT,
|
||||||
'Mailboxid' => $this->MAILBOXID,
|
|
||||||
*/
|
*/
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -293,6 +293,9 @@ class ImapClient extends \MailSo\Net\NetClient
|
||||||
if (!$this->aCapabilityItems) {
|
if (!$this->aCapabilityItems) {
|
||||||
$this->setCapabilities($this->SendRequestGetResponse('CAPABILITY'));
|
$this->setCapabilities($this->SendRequestGetResponse('CAPABILITY'));
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
$this->aCapabilityItems[] = 'X-DOVECOT';
|
||||||
|
*/
|
||||||
return $this->aCapabilityItems;
|
return $this->aCapabilityItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,8 @@ trait Status
|
||||||
{
|
{
|
||||||
if ('EXISTS' === $name) {
|
if ('EXISTS' === $name) {
|
||||||
$name = 'MESSAGES';
|
$name = 'MESSAGES';
|
||||||
|
} else if ('X-GUID' === $name) {
|
||||||
|
$name = 'MAILBOXID';
|
||||||
}
|
}
|
||||||
if (\property_exists(__TRAIT__, $name)) {
|
if (\property_exists(__TRAIT__, $name)) {
|
||||||
if ('MAILBOXID' !== $name) {
|
if ('MAILBOXID' !== $name) {
|
||||||
|
|
|
||||||
|
|
@ -229,7 +229,12 @@ class Folder implements \JsonSerializable
|
||||||
'Flags' => $this->FlagsLowerCase(),
|
'Flags' => $this->FlagsLowerCase(),
|
||||||
// 'Extended' => $aExtended,
|
// 'Extended' => $aExtended,
|
||||||
// 'PermanentFlags' => $this->oImapFolder->PermanentFlags,
|
// 'PermanentFlags' => $this->oImapFolder->PermanentFlags,
|
||||||
'Metadata' => $this->oImapFolder->Metadata()
|
'Metadata' => $this->oImapFolder->Metadata(),
|
||||||
|
'UidNext' => $this->oImapFolder->UIDNEXT,
|
||||||
|
// RFC 8621
|
||||||
|
'totalEmails' => $this->oImapFolder->MESSAGES,
|
||||||
|
'unreadEmails' => $this->oImapFolder->UNSEEN,
|
||||||
|
'id' => $this->oImapFolder->MAILBOXID
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,12 @@ class Message implements \JsonSerializable
|
||||||
$sHeaderDate = '',
|
$sHeaderDate = '',
|
||||||
$aFlagsLowerCase = [],
|
$aFlagsLowerCase = [],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://www.rfc-editor.org/rfc/rfc8474#section-5
|
||||||
|
*/
|
||||||
|
$sEmailId = '',
|
||||||
|
$sThreadId = '',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \MailSo\Mime\EmailCollection
|
* @var \MailSo\Mime\EmailCollection
|
||||||
*/
|
*/
|
||||||
|
|
@ -287,16 +293,21 @@ class Message implements \JsonSerializable
|
||||||
$oBodyStructure = $oFetchResponse->GetFetchBodyStructure();
|
$oBodyStructure = $oFetchResponse->GetFetchBodyStructure();
|
||||||
}
|
}
|
||||||
|
|
||||||
$sInternalDate = $oFetchResponse->GetFetchValue(FetchType::INTERNALDATE);
|
|
||||||
$aFlags = $oFetchResponse->GetFetchValue(FetchType::FLAGS);
|
$aFlags = $oFetchResponse->GetFetchValue(FetchType::FLAGS);
|
||||||
|
|
||||||
$oMessage->sFolder = $sFolder;
|
$oMessage->sFolder = $sFolder;
|
||||||
$oMessage->iUid = (int) $oFetchResponse->GetFetchValue(FetchType::UID);
|
$oMessage->iUid = (int) $oFetchResponse->GetFetchValue(FetchType::UID);
|
||||||
$oMessage->iSize = (int) $oFetchResponse->GetFetchValue(FetchType::RFC822_SIZE);
|
$oMessage->iSize = (int) $oFetchResponse->GetFetchValue(FetchType::RFC822_SIZE);
|
||||||
$oMessage->aFlagsLowerCase = \array_map('mb_strtolower', \array_map('\\MailSo\\Base\\Utils::Utf7ModifiedToUtf8', $aFlags ?: []));
|
$oMessage->aFlagsLowerCase = \array_map('mb_strtolower', \array_map('\\MailSo\\Base\\Utils::Utf7ModifiedToUtf8', $aFlags ?: []));
|
||||||
|
$oMessage->iInternalTimeStampInUTC = \MailSo\Base\DateTimeHelper::ParseInternalDateString(
|
||||||
|
$oFetchResponse->GetFetchValue(FetchType::INTERNALDATE)
|
||||||
|
);
|
||||||
|
|
||||||
$oMessage->iInternalTimeStampInUTC =
|
$oMessage->sEmailId = $oFetchResponse->GetFetchValue(FetchType::EMAILID)
|
||||||
\MailSo\Base\DateTimeHelper::ParseInternalDateString($sInternalDate);
|
// ?: $oFetchResponse->GetFetchValue('X-GUID')
|
||||||
|
?: $oFetchResponse->GetFetchValue('X-GM-MSGID');
|
||||||
|
$oMessage->sThreadId = $oFetchResponse->GetFetchValue(FetchType::THREADID)
|
||||||
|
?: $oFetchResponse->GetFetchValue('X-GM-THRID');
|
||||||
|
|
||||||
$sCharset = $oBodyStructure ? Utils::NormalizeCharset($oBodyStructure->SearchCharset()) : '';
|
$sCharset = $oBodyStructure ? Utils::NormalizeCharset($oBodyStructure->SearchCharset()) : '';
|
||||||
|
|
||||||
|
|
@ -660,9 +671,13 @@ class Message implements \JsonSerializable
|
||||||
'Flags' => $this->aFlagsLowerCase,
|
'Flags' => $this->aFlagsLowerCase,
|
||||||
|
|
||||||
// https://datatracker.ietf.org/doc/html/rfc8621#section-4.1.1
|
// https://datatracker.ietf.org/doc/html/rfc8621#section-4.1.1
|
||||||
|
'id' => $this->sEmailId,
|
||||||
|
// 'blobId' => $this->sEmailIdBlob,
|
||||||
|
'threadId' => $this->sThreadId,
|
||||||
|
// 'mailboxIds' => ['mailboxid'=>true],
|
||||||
|
// 'keywords' => \array_fill_keys($this->aFlagsLowerCase, true),
|
||||||
'size' => $this->iSize,
|
'size' => $this->iSize,
|
||||||
'receivedAt' => \gmdate('Y-m-d\\TH:i:s\\Z', $this->iInternalTimeStampInUTC)
|
'receivedAt' => \gmdate('Y-m-d\\TH:i:s\\Z', $this->iInternalTimeStampInUTC)
|
||||||
// 'keywords' => \array_fill_keys($this->aFlagsLowerCase, true)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -269,17 +269,12 @@ trait Response
|
||||||
$aResult = $mResponse->jsonSerialize();
|
$aResult = $mResponse->jsonSerialize();
|
||||||
|
|
||||||
$aStatus = $mResponse->Status();
|
$aStatus = $mResponse->Status();
|
||||||
if ($aStatus && isset($aStatus['MESSAGES'], $aStatus['UNSEEN'], $aStatus['UIDNEXT'])) {
|
if ($aStatus && isset($aStatus['MESSAGES'], $aStatus['UIDNEXT'])) {
|
||||||
$aResult = \array_merge(
|
$aResult['Hash'] = $this->MailClient()->GenerateFolderHash(
|
||||||
$aResult,
|
$mResponse->FullName(),
|
||||||
[
|
$aStatus['MESSAGES'],
|
||||||
'totalEmails' => (int) $aStatus['MESSAGES'],
|
$aStatus['UIDNEXT'],
|
||||||
'unreadEmails' => (int) $aStatus['UNSEEN'],
|
empty($aStatus['HIGHESTMODSEQ']) ? 0 : $aStatus['HIGHESTMODSEQ']
|
||||||
'UidNext' => (int) $aStatus['UIDNEXT'],
|
|
||||||
'Hash' => $this->MailClient()->GenerateFolderHash(
|
|
||||||
$mResponse->FullName(), $aStatus['MESSAGES'], $aStatus['UIDNEXT'],
|
|
||||||
empty($aStatus['HIGHESTMODSEQ']) ? 0 : $aStatus['HIGHESTMODSEQ'])
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue