Prevent double foreach in \MailSo\Imap\ResponseCollection::getFoldersResult()

This commit is contained in:
djmaze 2021-10-29 11:51:56 +02:00
parent 4b7495b7e7
commit 3184f22d6c
3 changed files with 47 additions and 61 deletions

View file

@ -48,41 +48,31 @@ class Folder
/** /**
* @throws \MailSo\Base\Exceptions\InvalidArgumentException * @throws \MailSo\Base\Exceptions\InvalidArgumentException
*/ */
function __construct(string $sFullNameRaw, string $sDelimiter = '.', array $aFlags = array()) function __construct(string $sFullNameRaw, string $sDelimiter = null, array $aFlags = array())
{ {
$sDelimiter = 'NIL' === \strtoupper($sDelimiter) ? '' : $sDelimiter; if (!\strlen($sFullNameRaw)) {
if (empty($sDelimiter))
{
$sDelimiter = '.'; // default delimiter
}
if (1 < \strlen($sDelimiter) || 0 === \strlen($sFullNameRaw))
{
throw new \MailSo\Base\Exceptions\InvalidArgumentException; throw new \MailSo\Base\Exceptions\InvalidArgumentException;
} }
$this->sFullNameRaw = $sFullNameRaw; $this->sFullNameRaw = $sFullNameRaw;
$this->sDelimiter = $sDelimiter;
$this->setDelimiter($sDelimiter);
$this->setFlags($aFlags);
}
public function setFlags(array $aFlags) : void
{
$this->aFlagsLowerCase = \array_map('strtolower', $aFlags); $this->aFlagsLowerCase = \array_map('strtolower', $aFlags);
}
$this->sFullNameRaw = 'INBOX'.$this->sDelimiter === \substr(\strtoupper($this->sFullNameRaw), 0, 5 + \strlen($this->sDelimiter)) ? public function setDelimiter(?string $sDelimiter) : void
'INBOX'.\substr($this->sFullNameRaw, 5) : $this->sFullNameRaw; {
$sDelimiter = 'NIL' === \strtoupper($sDelimiter) ? null : $sDelimiter;
if ($this->IsInbox()) $this->sDelimiter = $sDelimiter;
{ if ($sDelimiter) {
$this->sFullNameRaw = 'INBOX';
}
$this->sNameRaw = $this->sFullNameRaw;
if (0 < \strlen($this->sDelimiter))
{
$aNames = \explode($this->sDelimiter, $this->sFullNameRaw); $aNames = \explode($this->sDelimiter, $this->sFullNameRaw);
if (false !== \array_search('', $aNames))
{
throw new \MailSo\Base\Exceptions\InvalidArgumentException;
}
$this->sNameRaw = \end($aNames); $this->sNameRaw = \end($aNames);
} else {
$this->sNameRaw = $this->sFullNameRaw;
} }
} }
@ -96,7 +86,7 @@ class Folder
return $this->sFullNameRaw; return $this->sFullNameRaw;
} }
public function Delimiter() : string public function Delimiter() : ?string
{ {
return $this->sDelimiter; return $this->sDelimiter;
} }

View file

@ -469,17 +469,13 @@ class ImapClient extends \MailSo\Net\NetClient
$aReturnParams[] = 'STATUS'; $aReturnParams[] = 'STATUS';
$aReturnParams[] = $aL; $aReturnParams[] = $aL;
} }
else
{
$bUseListStatus = false;
}
if ($aReturnParams) { if ($aReturnParams) {
$aParameters[] = 'RETURN'; $aParameters[] = 'RETURN';
$aParameters[] = $aReturnParams; $aParameters[] = $aReturnParams;
} }
$aReturn = $this->SendRequestGetResponse($sCmd, $aParameters)->getFoldersResult($sCmd, $bUseListStatus); $aReturn = $this->SendRequestGetResponse($sCmd, $aParameters)->getFoldersResult($sCmd);
// RFC 5464 // RFC 5464
if (!$bIsSubscribeList && $this->IsSupported('METADATA')) { if (!$bIsSubscribeList && $this->IsSupported('METADATA')) {

View file

@ -119,7 +119,7 @@ class ResponseCollection extends \MailSo\Base\Collection
{ {
$aReturn = array(); $aReturn = array();
foreach ($this as $oResponse) { foreach ($this as $oResponse) {
if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType if (Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType
&& 4 === \count($oResponse->ResponseList) && 4 === \count($oResponse->ResponseList)
&& 'METADATA' === $oResponse->ResponseList[1] && 'METADATA' === $oResponse->ResponseList[1]
&& \is_array($oResponse->ResponseList[3])) && \is_array($oResponse->ResponseList[3]))
@ -136,17 +136,24 @@ class ResponseCollection extends \MailSo\Base\Collection
return $aReturn; return $aReturn;
} }
public function getFoldersResult(string $sStatus, bool $bUseListStatus = false) : array public function getFoldersResult(string $sStatus) : array
{ {
$aReturn = array(); $aReturn = array();
$sDelimiter = ''; $sDelimiter = '';
$bInbox = false; $bInbox = false;
foreach ($this as $oResponse) { foreach ($this as $oResponse) {
if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType && if (Enumerations\ResponseType::UNTAGGED !== $oResponse->ResponseType) {
$sStatus === $oResponse->StatusOrIndex && 5 <= count($oResponse->ResponseList)) continue;
{ }
if ('STATUS' === $oResponse->StatusOrIndex && isset($oResponse->ResponseList[2])) {
$sFullNameRaw = $oResponse->ResponseList[2];
if (!isset($aReturn[$sFullNameRaw])) {
$aReturn[$sFullNameRaw] = new Folder($sFullNameRaw);
}
$aReturn[$sFullNameRaw]->setStatusFromResponse($oResponse);
}
else if ($sStatus === $oResponse->StatusOrIndex && 5 <= count($oResponse->ResponseList)) {
try try
{ {
/** /**
@ -169,14 +176,21 @@ class ResponseCollection extends \MailSo\Base\Collection
* $oResponse->ResponseList[3] = Delimiter * $oResponse->ResponseList[3] = Delimiter
* $oResponse->ResponseList[4] = FullNameRaw * $oResponse->ResponseList[4] = FullNameRaw
*/ */
$oFolder = new Folder($sFullNameRaw, if (!isset($aReturn[$sFullNameRaw])) {
$oResponse->ResponseList[3], $oResponse->ResponseList[2]); $oFolder = new Folder($sFullNameRaw,
$oResponse->ResponseList[3], $oResponse->ResponseList[2]);
$aReturn[$sFullNameRaw] = $oFolder;
} else {
$oFolder = $aReturn[$sFullNameRaw];
$oFolder->setDelimiter($oResponse->ResponseList[3]);
$oFolder->setFlags($oResponse->ResponseList[2]);
}
if ($oFolder->IsInbox()) { if ($oFolder->IsInbox()) {
$bInbox = true; $bInbox = true;
} }
if (empty($sDelimiter)) { if (!$sDelimiter) {
$sDelimiter = $oFolder->Delimiter(); $sDelimiter = $oFolder->Delimiter();
} }
@ -197,24 +211,10 @@ class ResponseCollection extends \MailSo\Base\Collection
} }
} }
if (!$bInbox && !empty($sDelimiter) && !isset($aReturn['INBOX'])) { if (!$bInbox && !isset($aReturn['INBOX'])) {
$aReturn['INBOX'] = new Folder('INBOX', $sDelimiter); $aReturn['INBOX'] = new Folder('INBOX', $sDelimiter);
} }
if ($bUseListStatus) {
foreach ($this as $oResponse) {
if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType &&
'STATUS' === $oResponse->StatusOrIndex &&
isset($oResponse->ResponseList[2]))
{
$sFolderNameRaw = $oResponse->ResponseList[2];
if (isset($aReturn[$sFolderNameRaw])) {
$aReturn[$sFolderNameRaw]->setStatusFromResponse($oResponse);
}
}
}
}
return $aReturn; return $aReturn;
} }
@ -223,7 +223,7 @@ class ResponseCollection extends \MailSo\Base\Collection
$aReturn = array(); $aReturn = array();
foreach ($this as $oResponse) { foreach ($this as $oResponse) {
$iOffset = ($bReturnUid && 'UID' === $oResponse->StatusOrIndex && !empty($oResponse->ResponseList[2]) && $sStatus === $oResponse->ResponseList[2]) ? 1 : 0; $iOffset = ($bReturnUid && 'UID' === $oResponse->StatusOrIndex && !empty($oResponse->ResponseList[2]) && $sStatus === $oResponse->ResponseList[2]) ? 1 : 0;
if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType if (Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType
&& ($sStatus === $oResponse->StatusOrIndex || $iOffset) && ($sStatus === $oResponse->StatusOrIndex || $iOffset)
&& \is_array($oResponse->ResponseList) && \is_array($oResponse->ResponseList)
&& 2 < count($oResponse->ResponseList)) && 2 < count($oResponse->ResponseList))
@ -261,7 +261,7 @@ class ResponseCollection extends \MailSo\Base\Collection
$aReturn = array(); $aReturn = array();
foreach ($this as $oResponse) { foreach ($this as $oResponse) {
$iOffset = ($bReturnUid && 'UID' === $oResponse->StatusOrIndex && !empty($oResponse->ResponseList[2]) && $sStatus === $oResponse->ResponseList[2]) ? 1 : 0; $iOffset = ($bReturnUid && 'UID' === $oResponse->StatusOrIndex && !empty($oResponse->ResponseList[2]) && $sStatus === $oResponse->ResponseList[2]) ? 1 : 0;
if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType if (Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType
&& ($sStatus === $oResponse->StatusOrIndex || $iOffset) && ($sStatus === $oResponse->StatusOrIndex || $iOffset)
&& \is_array($oResponse->ResponseList) && \is_array($oResponse->ResponseList)
&& 2 < \count($oResponse->ResponseList)) && 2 < \count($oResponse->ResponseList))
@ -285,7 +285,7 @@ class ResponseCollection extends \MailSo\Base\Collection
{ {
$oResult = new FolderInformation($sFolderName, $bIsWritable); $oResult = new FolderInformation($sFolderName, $bIsWritable);
foreach ($this as $oResponse) { foreach ($this as $oResponse) {
if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType) { if (Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType) {
if (!$oResult->setStatusFromResponse($oResponse)) { if (!$oResult->setStatusFromResponse($oResponse)) {
// OK untagged responses // OK untagged responses
if (\is_array($oResponse->OptionalResponse)) { if (\is_array($oResponse->OptionalResponse)) {
@ -372,7 +372,7 @@ class ResponseCollection extends \MailSo\Base\Collection
{ {
$aResult = array(); $aResult = array();
foreach ($this as $oResponse) { foreach ($this as $oResponse) {
if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType if (Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType
&& ('ESEARCH' === $oResponse->StatusOrIndex || 'ESORT' === $oResponse->StatusOrIndex) && ('ESEARCH' === $oResponse->StatusOrIndex || 'ESORT' === $oResponse->StatusOrIndex)
&& \is_array($oResponse->ResponseList) && \is_array($oResponse->ResponseList)
&& isset($oResponse->ResponseList[2], $oResponse->ResponseList[2][0], $oResponse->ResponseList[2][1]) && isset($oResponse->ResponseList[2], $oResponse->ResponseList[2][0], $oResponse->ResponseList[2][1])