diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Folder.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Folder.php index 867fcfb6c..0fd4d0f63 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Folder.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Folder.php @@ -17,6 +17,9 @@ namespace MailSo\Imap; */ class Folder { + // RFC5258 Response data STATUS items when using LIST-EXTENDED + use Traits\Status; + /** * @var 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 e081c7169..dcedd1860 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 @@ -17,6 +17,8 @@ namespace MailSo\Imap; */ class FolderInformation { + use Traits\Status; + /** * @var string */ @@ -43,38 +45,6 @@ class FolderInformation */ public $Exists = null; - /** - * https://datatracker.ietf.org/doc/html/rfc3501#section-7.3.2 - * @var int - */ - public $Recent = null; - - /** - * rfc3501 2.3.1.1 - * A 32-bit value - * @var int - */ - public $Uidvalidity = null; - - /** - * @var int - */ - public $Unread = null; - - /** - * rfc3501 2.3.1.1 - * A 32-bit value - * @var int - */ - public $Uidnext = null; - - /** - * rfc4551 - * 1*DIGIT Positive unsigned 64-bit integer - * @var int - */ - public $HighestModSeq = null; - function __construct(string $sFolderName, bool $bIsWritable) { $this->FolderName = $sFolderName; diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ResponseCollection.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ResponseCollection.php index 20b85354f..67cd91acf 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ResponseCollection.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/ResponseCollection.php @@ -209,39 +209,15 @@ class ResponseCollection extends \MailSo\Base\Collection foreach ($this as $oResponse) { if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType && 'STATUS' === $oResponse->StatusOrIndex && - isset($oResponse->ResponseList[2]) && - isset($oResponse->ResponseList[3]) && - \is_array($oResponse->ResponseList[3])) + isset($oResponse->ResponseList[2])) { $sFolderNameRaw = $oResponse->ResponseList[2]; - - $oCurrentFolder = null; foreach ($aReturn as $oFolder) { if ($oFolder && $sFolderNameRaw === $oFolder->FullNameRaw()) { - $oCurrentFolder =& $oFolder; + $oFolder->setStatusFromResponse($oResponse); break; } } - - if (null !== $oCurrentFolder) { - $sName = null; - $aStatus = array(); - - foreach ($oResponse->ResponseList[3] as $sArrayItem) { - if (null === $sName) { - $sName = $sArrayItem; - } else { - $aStatus[$sName] = $sArrayItem; - $sName = null; - } - } - - if (0 < count($aStatus)) { - $oCurrentFolder->SetExtended('STATUS', $aStatus); - } - } - - unset($oCurrentFolder); } } } @@ -309,59 +285,36 @@ class ResponseCollection extends \MailSo\Base\Collection return $aReturn; } + /** + * Called by selectOrExamineFolder + */ public function getCurrentFolderInformation(string $sFolderName, bool $bIsWritable) : FolderInformation { $oResult = new FolderInformation($sFolderName, $bIsWritable); foreach ($this as $oResponse) { if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType) { - if (\count($oResponse->ResponseList) > 2 && - 'FLAGS' === $oResponse->ResponseList[1] && \is_array($oResponse->ResponseList[2])) - { - $oResult->Flags = $oResponse->ResponseList[2]; - } - - if (\is_array($oResponse->OptionalResponse)) { - if (\count($oResponse->OptionalResponse) > 1) { - if ('PERMANENTFLAGS' === $oResponse->OptionalResponse[0] - && is_array($oResponse->OptionalResponse[1])) - { - $oResult->PermanentFlags = $oResponse->OptionalResponse[1]; + if (!$oResult->setStatusFromResponse($oResponse)) { + // OK untagged responses + if (\is_array($oResponse->OptionalResponse)) { + if (\count($oResponse->OptionalResponse) > 1) { + if ('PERMANENTFLAGS' === $oResponse->OptionalResponse[0] && \is_array($oResponse->OptionalResponse[1])) { + $oResult->PermanentFlags = $oResponse->OptionalResponse[1]; + } + } else if ('READ-ONLY' === $oResponse->OptionalResponse[0]) { +// $oResult->IsWritable = false; + } else if ('READ-WRITE' === $oResponse->OptionalResponse[0]) { +// $oResult->IsWritable = true; + } else if ('NOMODSEQ' === $key) { + // https://datatracker.ietf.org/doc/html/rfc4551#section-3.1.2 } - else if ('UIDVALIDITY' === $oResponse->OptionalResponse[0]) - { - $oResult->Uidvalidity = (int) $oResponse->OptionalResponse[1]; - } - else if ('UNSEEN' === $oResponse->OptionalResponse[0]) - { - $oResult->Unread = (int) $oResponse->OptionalResponse[1]; - } - else if ('UIDNEXT' === $oResponse->OptionalResponse[0]) - { - $oResult->Uidnext = (int) $oResponse->OptionalResponse[1]; - } - else if ('HIGHESTMODSEQ' === $oResponse->OptionalResponse[0]) - { - $oResult->HighestModSeq = (int) $oResponse->OptionalResponse[1]; - } - } else if ('READ-ONLY' === $oResponse->OptionalResponse[0]) { -// $oResult->IsWritable = false; - } else if ('READ-WRITE' === $oResponse->OptionalResponse[0]) { -// $oResult->IsWritable = true; } - } - if (\count($oResponse->ResponseList) > 2 && - \is_string($oResponse->ResponseList[2]) && - \is_numeric($oResponse->ResponseList[1])) - { - switch ($oResponse->ResponseList[2]) - { - case 'EXISTS': - $oResult->Exists = (int) $oResponse->ResponseList[1]; - break; - case 'RECENT': - $oResult->Recent = (int) $oResponse->ResponseList[1]; - break; + // untagged responses + else if (\count($oResponse->ResponseList) > 2) { + if ('FLAGS' === $oResponse->ResponseList[1] && \is_array($oResponse->ResponseList[2])) + { + $oResult->Flags = $oResponse->ResponseList[2]; + } } } } @@ -456,24 +409,11 @@ class ResponseCollection extends \MailSo\Base\Collection public function getStatusFolderInformationResult() : array { - $aReturn = array(); + $oInfo = new FolderInformation('', false); foreach ($this as $oResponse) { - if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType && - 'STATUS' === $oResponse->StatusOrIndex && isset($oResponse->ResponseList[3]) && - \is_array($oResponse->ResponseList[3])) - { - $sName = null; - foreach ($oResponse->ResponseList[3] as $sArrayItem) { - if (null === $sName) { - $sName = $sArrayItem; - } else { - $aReturn[$sName] = $sArrayItem; - $sName = null; - } - } - } + $oInfo->setStatusFromResponse($oResponse); } - return $aReturn; + return $oInfo->getStatusItems(); } /** 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 new file mode 100644 index 000000000..d517b474b --- /dev/null +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Traits/Status.php @@ -0,0 +1,149 @@ +$name = $value; + return true; + } + return false; + } + + /** + * SELECT https://datatracker.ietf.org/doc/html/rfc3501#section-6.3.1 + * EXAMINE https://datatracker.ietf.org/doc/html/rfc3501#section-6.3.2 + * STATUS https://datatracker.ietf.org/doc/html/rfc3501#section-6.3.10 + * + * getCurrentFolderInformation + * ResponseList[2] => EXISTS | RECENT + * OptionalResponse[0] => UNSEEN + * getStatusFolderInformationResult + * OptionalResponse[0] => HIGHESTMODSEQ + * ResponseList[1] => STATUS + * getFoldersResult LIST-EXTENDED + * ResponseList[1] => STATUS + */ + public function setStatusFromResponse(\MailSo\Imap\Response $oResponse) : bool + { + $bResult = false; + + // OK untagged responses + if (\is_array($oResponse->OptionalResponse)) { + if (\count($oResponse->OptionalResponse) > 1) { + $bResult = $this->setStatus($oResponse->OptionalResponse[0], $oResponse->OptionalResponse[1]); + } + } + + // untagged responses + else if (\count($oResponse->ResponseList) > 2) { + // LIST or STATUS command + if ('STATUS' === $oResponse->ResponseList[1] + && isset($oResponse->ResponseList[3]) + && \is_array($oResponse->ResponseList[3])) { + $c = \count($oResponse->ResponseList[3]); + for ($i = 0; $i < $c; $i += 2) { + $bResult |= $this->setStatus( + $oResponse->ResponseList[3][$i], + $oResponse->ResponseList[3][$i+1] + ); + } + } + // SELECT or EXAMINE command + else if (\is_numeric($oResponse->ResponseList[1]) && \is_string($oResponse->ResponseList[2])) { + $bResult = $this->setStatus($oResponse->ResponseList[2], $oResponse->ResponseList[1]); + } + } + + return $bResult; + } + +} 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 604bfdaa7..9c159ec97 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 @@ -175,12 +175,9 @@ class Folder implements \JsonSerializable return $this->bExists && $this->oImapFolder->IsSelectable(); } - /** - * @return mixed - */ - public function Status() + public function Status() : array { - return $this->oImapFolder->GetExtended('STATUS'); + return $this->oImapFolder->getStatusItems(); } public function IsInbox() : bool @@ -191,6 +188,7 @@ class Folder implements \JsonSerializable public function GetFolderListType() : int { $aFlags = $this->oImapFolder->FlagsLowerCase(); + // RFC 6154 // $aFlags[] = \strtolower($this->oImapFolder->GetMetadata(MetadataKeys::SPECIALUSE)); switch (true) 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 b320bc8c7..2a2ed65b4 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 @@ -144,7 +144,7 @@ class MailClient } } - if ($oFolderInfo && 0 < $oFolderInfo->Exists) + if ($oFolderInfo && 0 < $oFolderInfo->MESSAGES) { $sStoreAction = $bSetAction ? \MailSo\Imap\Enumerations\StoreAction::ADD_FLAGS_SILENT @@ -1935,6 +1935,7 @@ class MailClient } $aFolders = $this->oImapClient->FolderList($sParent, $sListPattern); +// $aFolders = $this->oImapClient->FolderStatusList($sParent, $sListPattern); if (!$aFolders) { return null; } @@ -2210,7 +2211,7 @@ class MailClient $this->oImapClient->FolderSelect($sFolderFullNameRaw); $oFolderInformation = $this->oImapClient->FolderCurrentInformation(); - if ($oFolderInformation && $oFolderInformation->Exists && 0 < $oFolderInformation->Exists) // STATUS? + if ($oFolderInformation && 0 < $oFolderInformation->MESSAGES) { $this->oImapClient->MessageStoreFlag('1:*', false, array(\MailSo\Imap\Enumerations\MessageFlag::DELETED),