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 e35a1f21c..77bb81db9 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 @@ -118,7 +118,7 @@ trait Messages * @throws \MailSo\Net\Exceptions\Exception * @throws \MailSo\Imap\Exceptions\Exception */ - public function MessageAppendStream(string $sFolderName, $rMessageAppendStream, int $iStreamSize, array $aFlagsList = null, int &$iUid = null, int $iDateTime = 0) : ?int + public function MessageAppendStream(string $sFolderName, $rMessageAppendStream, int $iStreamSize, array $aFlagsList = null, int $iDateTime = 0) : ?int { $aParams = array( $this->EscapeFolderName($sFolderName), @@ -138,27 +138,34 @@ trait Messages $this->SendRequestGetResponse('APPEND', $aParams); + return $this->writeMessageStream($rMessageAppendStream); + } + + private function writeMessageStream($rMessageStream) : ?int + { $this->writeLog('Write to connection stream', LogType::NOTE); - \MailSo\Base\Utils::MultipleStreamWriter($rMessageAppendStream, array($this->ConnectionResource())); + \MailSo\Base\Utils::MultipleStreamWriter($rMessageStream, array($this->ConnectionResource())); $this->sendRaw(''); - $oResponse = $this->getResponse(); - - if (null !== $iUid) { - $oLast = $oResponse->getLast(); - if ($oLast - && ResponseType::TAGGED === $oLast->ResponseType - && \is_array($oLast->OptionalResponse) - && !empty($oLast->OptionalResponse[2]) - && \is_numeric($oLast->OptionalResponse[2]) - && 'APPENDUID' === \strtoupper($oLast->OptionalResponse[0]) + $oResponses = $this->getResponse(); + /** + * Can be tagged + S: A003 OK [APPENDUID 1 2001] APPEND completed + * Or untagged + S: * OK [APPENDUID 1 2001] Replacement Message ready + */ + foreach ($oResponses as $oResponse) { + if (\is_array($oResponse->OptionalResponse) + && !empty($oResponse->OptionalResponse[2]) + && \is_numeric($oResponse->OptionalResponse[2]) + && 'APPENDUID' === \strtoupper($oResponse->OptionalResponse[0]) ) { - $iUid = (int) $oLast->OptionalResponse[2]; + return (int) $oResponse->OptionalResponse[2]; } } - return $iUid; + return null; } /** @@ -206,6 +213,55 @@ trait Messages ); } + /** + * RFC 8508 REPLACE + * Replaces message in specified folder + * When $iUid < 1 it only appends the message + * + * @param resource $rMessageStream + * + * @throws \MailSo\Base\Exceptions\InvalidArgumentException + * @throws \MailSo\Net\Exceptions\Exception + * @throws \MailSo\Imap\Exceptions\Exception + */ + public function MessageReplaceStream(string $sFolderName, int $iUid, $rMessageStream, int $iStreamSize, array $aFlagsList = null, int $iDateTime = 0) : ?int + { + if (1 > $iUid || !$this->IsSupported('REPLACE')) { + $this->FolderSelect($sFolderName); + $iNewUid = $this->MessageAppendStream($sFolderName, $rMessageStream, $iStreamSize, $aFlagsList, $iDateTime); + if ($iUid) { + $oRange = new SequenceSet([$iUid]); + $this->MessageStoreFlag($oRange, + array(\MailSo\Imap\Enumerations\MessageFlag::DELETED), + \MailSo\Imap\Enumerations\StoreAction::ADD_FLAGS_SILENT + ); + $this->FolderExpunge($oRange); + } + return $iNewUid; + } + + $aParams = array( + $iUid, + $this->EscapeFolderName($sFolderName), + $aFlagsList + ); + if (0 < $iDateTime) { + $aParams[] = $this->EscapeString(\gmdate('d-M-Y H:i:s', $iDateTime).' +0000'); + } + +/* + // RFC 3516 || RFC 6855 section-4 + if ($this->IsSupported('BINARY') || $this->IsSupported('UTF8=ACCEPT')) { + $aParams[] = '~{'.$iStreamSize.'}'; + } +*/ + $aParams[] = '{'.$iStreamSize.'}'; + + $this->SendRequestGetResponse('UID REPLACE', $aParams); + + return $this->writeMessageStream($rMessageStream); + } + /** * @throws \MailSo\Base\Exceptions\InvalidArgumentException * @throws \MailSo\Net\Exceptions\Exception diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php index 4d33b8b31..fc1499462 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php @@ -401,8 +401,8 @@ class MailClient throw new \MailSo\Base\Exceptions\InvalidArgumentException; } - $this->oImapClient->MessageAppendStream( - $sFolderToSave, $rMessageStream, $iMessageStreamSize, $aAppendFlags, $iUid); + $iUid = $this->oImapClient->MessageAppendStream( + $sFolderToSave, $rMessageStream, $iMessageStreamSize, $aAppendFlags); return $this; } diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/KolabAddressBook.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/KolabAddressBook.php index 1ac1f3489..fdf930841 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/KolabAddressBook.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/KolabAddressBook.php @@ -141,10 +141,14 @@ class KolabAddressBook implements AddressBookInterface $oContact->PopulateDisplayAndFullNameValue(); $iUID = $oContact->IdContact; - $sUUID = $oContact->GetUID(); $oPrevMessage = $this->MailClient()->Message($this->FolderName(), $iUID); - $oVCard = $oPrevMessage ? $this->fetchXCardFromMessage($oPrevMessage) : null; + if ($oPrevMessage) { + $oVCard = $this->fetchXCardFromMessage($oPrevMessage); + } else { + $oVCard = null; + $iUID = 0; + } $oMessage = new \MailSo\Mime\Message(); @@ -162,7 +166,7 @@ class KolabAddressBook implements AddressBookInterface } } - $oMessage->SetSubject($sUUID); + $oMessage->SetSubject($oContact->GetUID()); // $oMessage->SetDate(\time()); $oMessage->Headers->AddByName('X-Kolab-Type', 'application/x-vnd.kolab.contact'); $oMessage->Headers->AddByName('X-Kolab-Mime-Version', '3.0'); @@ -185,25 +189,13 @@ class KolabAddressBook implements AddressBookInterface $oPart->Body = $oContact->ToXCard($oVCard/*, $oLogger*/); $oMessage->SubParts->append($oPart); - if ($oPrevMessage) { - // Replace Message - if (false && $this->ImapClient()->IsSupported('REPLACE')) { - // UID REPLACE - } else { - $this->MailClient()->MessageDelete( - $this->FolderName(), - new \MailSo\Imap\SequenceSet([$iUID]) - ); - } - } - // Store Message $rMessageStream = \MailSo\Base\ResourceRegistry::CreateMemoryResource(); $iMessageStreamSize = \MailSo\Base\Utils::MultipleStreamWriter( $oMessage->ToStream(false), array($rMessageStream), 8192, true, true); if (false !== $iMessageStreamSize) { \rewind($rMessageStream); - $this->ImapClient()->MessageAppendStream($this->sFolderName, $rMessageStream, $iMessageStreamSize); + $this->ImapClient()->MessageReplaceStream($this->sFolderName, $iUID, $rMessageStream, $iMessageStreamSize); } return true; @@ -211,10 +203,14 @@ class KolabAddressBook implements AddressBookInterface public function DeleteContacts(string $sEmail, array $aContactIds) : bool { - $this->MailClient()->MessageDelete( - $this->FolderName(), - new \MailSo\Imap\SequenceSet($aContactIds) - ); + try { + $this->MailClient()->MessageDelete( + $this->FolderName(), + new \MailSo\Imap\SequenceSet($aContactIds) + ); + return true; + } catch (\Throwable $e) { + } return false; }