Merge STATUS related code into a trait

This commit is contained in:
djmaze 2021-10-27 13:54:55 +02:00
parent d952ec5930
commit 8d07ab87fa
6 changed files with 187 additions and 126 deletions

View file

@ -17,6 +17,9 @@ namespace MailSo\Imap;
*/
class Folder
{
// RFC5258 Response data STATUS items when using LIST-EXTENDED
use Traits\Status;
/**
* @var string
*/

View file

@ -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;

View file

@ -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();
}
/**

View file

@ -0,0 +1,149 @@
<?php
/*
* This file is part of MailSo.
*
* (c) 2021 DJMaze
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace MailSo\Imap\Traits;
/**
* @category MailSo
* @package Imap
* @subpackage Traits
*
* https://datatracker.ietf.org/doc/html/rfc3501#section-6.3.10
* https://datatracker.ietf.org/doc/html/rfc4551#section-3.6
* https://datatracker.ietf.org/doc/html/rfc8474#section-4
*/
trait Status
{
public
/**
* The number of messages in the mailbox.
* This response is named EXISTS as a result of a SELECT or EXAMINE command.
* @var int
*/
$MESSAGES,
/**
* The number of messages with the \Recent flag set.
* This response also occurs as a result of a SELECT or EXAMINE command.
* @var int
*/
$RECENT,
/**
* The next unique identifier value of the mailbox.
* A 32-bit value
* This response also occurs as a result of a SELECT or EXAMINE command.
* @var int
*/
$UIDNEXT,
/**
* The unique identifier validity value of the mailbox.
* This response also occurs as a result of a SELECT or EXAMINE command.
* @var int
*/
$UIDVALIDITY,
/**
* The number of messages which do not have the \Seen flag set.
* This response also occurs as a result of a SELECT or EXAMINE command,
* but then it is the message sequence number of the first unseen message.
* @var int
*/
$UNSEEN,
/**
* RFC4551
* The highest mod-sequence value of all messages in the mailbox.
* This response also occurs as a result of a SELECT or EXAMINE command.
* @var int 1*DIGIT Positive unsigned 64-bit integer
*/
$HIGHESTMODSEQ,
/**
* RFC8474
* A server-allocated unique identifier for the mailbox.
* This response also occurs as a result of a CREATE, SELECT or EXAMINE command.
* @var string
*/
$MAILBOXID;
public function getStatusItems() : array
{
return \array_filter(\get_object_vars($this), function($v, $k){
return isset($v) && \property_exists(__TRAIT__, $k);
}, ARRAY_FILTER_USE_BOTH);
}
public function setStatus(string $name, $value) : bool
{
if ('EXISTS' === $name) {
$name = 'MESSAGES';
}
if (\property_exists(__TRAIT__, $name)) {
if ('MAILBOXID' !== $name) {
$value = (int) $value;
}
$this->$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;
}
}

View file

@ -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)

View file

@ -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),