diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/Folders.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/Folders.php index 5f0c0da2f..573634157 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/Folders.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/Folders.php @@ -119,6 +119,10 @@ trait Folders } if ($this->IsSupported('OBJECTID')) { $aStatusItems[] = FolderResponseStatus::MAILBOXID; +/* + } else if ($this->IsSupported('X-DOVECOT')) { + $aFetchItems[] = 'X-GUID'; +*/ } $oFolderInfo = $this->oCurrentFolderInfo; @@ -341,6 +345,9 @@ trait Folders // $oResult->IsWritable = true; } else if ('NOMODSEQ' === $key) { // 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 if ($this->IsSupported('OBJECTID')) { - $aTypes[] = FolderStatus::MAILBOXID; + $aL[] = FolderStatus::MAILBOXID; +/* + } else if ($this->IsSupported('X-DOVECOT')) { + $aL[] = 'X-GUID'; +*/ } $aReturnParams[] = 'STATUS'; diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/Messages.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/Messages.php index 56f4028c4..f2052e7c6 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/Messages.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/Messages.php @@ -78,6 +78,23 @@ trait Messages 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); diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Enumerations/FetchType.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Enumerations/FetchType.php index 395644833..f3388cd57 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Enumerations/FetchType.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Enumerations/FetchType.php @@ -53,6 +53,9 @@ abstract class FetchType const BINARY_SIZE = 'BINARY.SIZE'; // RFC 4551 const MODSEQ = 'MODSEQ'; + // RFC 8474 + const EMAILID = 'EMAILID'; + const THREADID = 'THREADID'; public static function BuildBodyCustomHeaderRequest(array $aHeaders, bool $bPeek = true) : string { diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/FolderInformation.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/FolderInformation.php index 7e323749d..b5fe6a367 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/FolderInformation.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/FolderInformation.php @@ -63,6 +63,7 @@ class FolderInformation implements \JsonSerializable public function jsonSerialize() { return array( + 'id' => $this->MAILBOXID, 'Name' => $this->FolderName, 'Flags' => $this->Flags, 'PermanentFlags' => $this->PermanentFlags, @@ -73,7 +74,6 @@ class FolderInformation implements \JsonSerializable 'UidValidity' => $this->UIDVALIDITY, 'Highestmodseq' => $this->HIGHESTMODSEQ, 'Appendlimit' => $this->APPENDLIMIT, - 'Mailboxid' => $this->MAILBOXID, */ ); } diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ImapClient.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ImapClient.php index 2d254fe0c..2b2e8f140 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ImapClient.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ImapClient.php @@ -293,6 +293,9 @@ class ImapClient extends \MailSo\Net\NetClient if (!$this->aCapabilityItems) { $this->setCapabilities($this->SendRequestGetResponse('CAPABILITY')); } +/* + $this->aCapabilityItems[] = 'X-DOVECOT'; +*/ return $this->aCapabilityItems; } diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Traits/Status.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Traits/Status.php index 425f5e84f..814093894 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Traits/Status.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Traits/Status.php @@ -96,6 +96,8 @@ trait Status { if ('EXISTS' === $name) { $name = 'MESSAGES'; + } else if ('X-GUID' === $name) { + $name = 'MAILBOXID'; } if (\property_exists(__TRAIT__, $name)) { if ('MAILBOXID' !== $name) { diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Folder.php b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Folder.php index 6e62b7195..f0ee21c81 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Folder.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Folder.php @@ -229,7 +229,12 @@ class Folder implements \JsonSerializable 'Flags' => $this->FlagsLowerCase(), // 'Extended' => $aExtended, // '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 ); } } diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Message.php b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Message.php index c1f0e9e5e..5edba72ab 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Message.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Message.php @@ -36,6 +36,12 @@ class Message implements \JsonSerializable $sHeaderDate = '', $aFlagsLowerCase = [], + /** + * https://www.rfc-editor.org/rfc/rfc8474#section-5 + */ + $sEmailId = '', + $sThreadId = '', + /** * @var \MailSo\Mime\EmailCollection */ @@ -287,16 +293,21 @@ class Message implements \JsonSerializable $oBodyStructure = $oFetchResponse->GetFetchBodyStructure(); } - $sInternalDate = $oFetchResponse->GetFetchValue(FetchType::INTERNALDATE); $aFlags = $oFetchResponse->GetFetchValue(FetchType::FLAGS); $oMessage->sFolder = $sFolder; $oMessage->iUid = (int) $oFetchResponse->GetFetchValue(FetchType::UID); $oMessage->iSize = (int) $oFetchResponse->GetFetchValue(FetchType::RFC822_SIZE); $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 = - \MailSo\Base\DateTimeHelper::ParseInternalDateString($sInternalDate); + $oMessage->sEmailId = $oFetchResponse->GetFetchValue(FetchType::EMAILID) +// ?: $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()) : ''; @@ -660,9 +671,13 @@ class Message implements \JsonSerializable 'Flags' => $this->aFlagsLowerCase, // 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, 'receivedAt' => \gmdate('Y-m-d\\TH:i:s\\Z', $this->iInternalTimeStampInUTC) -// 'keywords' => \array_fill_keys($this->aFlagsLowerCase, true) ); } } diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Response.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Response.php index c5bbaf65a..b5582f010 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Response.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Response.php @@ -269,17 +269,12 @@ trait Response $aResult = $mResponse->jsonSerialize(); $aStatus = $mResponse->Status(); - if ($aStatus && isset($aStatus['MESSAGES'], $aStatus['UNSEEN'], $aStatus['UIDNEXT'])) { - $aResult = \array_merge( - $aResult, - [ - 'totalEmails' => (int) $aStatus['MESSAGES'], - 'unreadEmails' => (int) $aStatus['UNSEEN'], - 'UidNext' => (int) $aStatus['UIDNEXT'], - 'Hash' => $this->MailClient()->GenerateFolderHash( - $mResponse->FullName(), $aStatus['MESSAGES'], $aStatus['UIDNEXT'], - empty($aStatus['HIGHESTMODSEQ']) ? 0 : $aStatus['HIGHESTMODSEQ']) - ] + if ($aStatus && isset($aStatus['MESSAGES'], $aStatus['UIDNEXT'])) { + $aResult['Hash'] = $this->MailClient()->GenerateFolderHash( + $mResponse->FullName(), + $aStatus['MESSAGES'], + $aStatus['UIDNEXT'], + empty($aStatus['HIGHESTMODSEQ']) ? 0 : $aStatus['HIGHESTMODSEQ'] ); }