Move some MailSo\Imap\ImapClient code to the new MailSo\Imap\ResponseCollection

This commit is contained in:
djmaze 2020-03-21 12:55:39 +01:00
parent 0d54a372df
commit b9c019e05c
3 changed files with 586 additions and 707 deletions

View file

@ -21,25 +21,25 @@ class ResponseException extends \MailSo\Imap\Exceptions\Exception
/**
* @var array
*/
private $aResponses;
private $oResponses;
public function __construct(array $aResponses = array(), string $sMessage = '', int $iCode = 0, ?\Throwable $oPrevious = null)
public function __construct(?ResponseCollection $oResponses = null, string $sMessage = '', int $iCode = 0, ?\Throwable $oPrevious = null)
{
parent::__construct($sMessage, $iCode, $oPrevious);
if (is_array($aResponses))
{
$this->aResponses = $aResponses;
}
$this->oResponses = $oResponses;
}
public function GetResponses() : array
public function GetResponses() : ?ResponseCollection
{
return $this->aResponses;
return $this->oResponses;
}
public function GetLastResponse() : ?Response
{
return 0 < count($this->aResponses) ? $this->aResponses[count($this->aResponses) - 1] : null;
if ($this->oResponses && \count($this->oResponses)) {
return $this->oResponses[count($this->oResponses) - 1];
}
return null;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,415 @@
<?php
/*
* This file is part of MailSo.
*
* (c) 2014 Usenko Timur
* (c) 2020 Dj Maze
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace MailSo\Imap;
/**
* @category MailSo
* @package Imap
*/
class ResponseCollection extends \MailSo\Base\Collection
{
public static function NewInstance() : self
{
return new self();
}
public function append($oResponse, bool $bToTop = false) : void
{
assert($oResponse instanceof Response);
parent::append($oResponse, $bToTop);
}
public function getLast() : ?Response
{
$iLast = \count($this);
return $iLast ? $this[$iLast-1] : null;
}
public function validate() : self
{
$oItem = $this->getLast();
if (!$oItem) {
throw new Exceptions\ResponseNotFoundException();
}
if ($oItem->ResponseType !== Enumerations\ResponseType::CONTINUATION) {
if (!$oItem->IsStatusResponse) {
throw new Exceptions\InvalidResponseException($this);
}
if (Enumerations\ResponseStatus::OK !== $oItem->StatusOrIndex) {
throw new Exceptions\NegativeResponseException($this);
}
}
return $this;
}
public function getFetchResult() : array
{
$aReturn = array();
foreach ($this as $oResponse) {
if (FetchResponse::IsValidFetchImapResponse($oResponse)) {
if (FetchResponse::IsNotEmptyFetchImapResponse($oResponse)) {
$aReturn[] = FetchResponse::NewInstance($oResponse);
} else if ($this->oLogger) {
$this->oLogger->Write('Skipped Imap Response! ['.$oResponse->ToLine().']', \MailSo\Log\Enumerations\Type::NOTICE);
}
}
}
return $aReturn;
}
public function getFoldersResult(string $sStatus, bool $bUseListStatus = false) : array
{
$aReturn = array();
$sDelimiter = '';
$bInbox = false;
foreach ($this as $oResponse) {
if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType &&
$sStatus === $oResponse->StatusOrIndex && 5 === count($oResponse->ResponseList))
{
try
{
$oFolder = Folder::NewInstance($oResponse->ResponseList[4],
$oResponse->ResponseList[3], $oResponse->ResponseList[2]);
if ($oFolder->IsInbox()) {
$bInbox = true;
}
if (empty($sDelimiter)) {
$sDelimiter = $oFolder->Delimiter();
}
$aReturn[] = $oFolder;
}
catch (\MailSo\Base\Exceptions\InvalidArgumentException $oException)
{
// TODO: writeLogException not accessible
error_log('ResponseCollection::getFoldersResult: '.$oException->getMessage());
// $this->writeLogException($oException, \MailSo\Log\Enumerations\Type::WARNING, false);
}
}
}
if (!$bInbox && !empty($sDelimiter)) {
$aReturn[] = Folder::NewInstance('INBOX', $sDelimiter);
}
if ($bUseListStatus) {
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]))
{
$sFolderNameRaw = $oResponse->ResponseList[2];
$oCurrentFolder = null;
foreach ($aReturn as $oFolder) {
if ($oFolder && $sFolderNameRaw === $oFolder->FullNameRaw()) {
$oCurrentFolder =& $oFolder;
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);
}
}
}
return $aReturn;
}
public function getMessageSimpleSearchResult(string $sStatus, bool $bReturnUid) : array
{
$aReturn = array();
foreach ($this as $oResponse) {
$iOffset = ($bReturnUid && 'UID' === $oResponse->StatusOrIndex && !empty($oResponse->ResponseList[2]) && $sStatus === $oResponse->ResponseList[2]) ? 1 : 0;
if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType
&& ($sStatus === $oResponse->StatusOrIndex || $iOffset)
&& \is_array($oResponse->ResponseList)
&& 2 < count($oResponse->ResponseList))
{
$iLen = \count($oResponse->ResponseList);
for ($iIndex = 2 + $iOffset; $iIndex < $iLen; ++$iIndex) {
$aReturn[] = (int) $oResponse->ResponseList[$iIndex];
}
}
}
return \array_reverse($aReturn);
}
public function getMessageSimpleSortResult(string $sStatus, bool $bReturnUid) : array
{
$aReturn = array();
foreach ($oResult as $oResponse) {
$iOffset = ($bReturnUid && 'UID' === $oResponse->StatusOrIndex && !empty($oResponse->ResponseList[2]) && $sStatus === $oResponse->ResponseList[2]) ? 1 : 0;
if (Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType
&& ($sStatus === $oResponse->StatusOrIndex || $iOffset)
&& \is_array($oResponse->ResponseList)
&& 2 < \count($oResponse->ResponseList))
{
$iLen = \count($oResponse->ResponseList);
for ($iIndex = 2 + $iOffset; $iIndex < $iLen; ++$iIndex) {
$aReturn[] = (int) $oResponse->ResponseList[$iIndex];
}
}
}
return $aReturn;
}
public function getMessageSimpleThreadResult($sStatus, $bReturnUid) : array
{
$aReturn = array();
foreach ($aResult as $oResponse) {
$iOffset = ($bReturnUid && 'UID' === $oResponse->StatusOrIndex && !empty($oResponse->ResponseList[2]) && $sStatus === $oResponse->ResponseList[2]) ? 1 : 0;
if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType
&& ($sStatus === $oResponse->StatusOrIndex || $iOffset)
&& \is_array($oResponse->ResponseList)
&& 2 < \count($oResponse->ResponseList))
{
$iLen = \count($oResponse->ResponseList);
for ($iIndex = 2 + $iOffset; $iIndex < $iLen; ++$iIndex) {
$aNewValue = $this->validateThreadItem($oResponse->ResponseList[$iIndex]);
if (false !== $aNewValue) {
$aReturn[] = $aNewValue;
}
}
}
}
return $aReturn;
}
public function getCurrentFolderInformation(string $sFolderName, bool $bIsWritable) : FolderInformation
{
$oResult = FolderInformation::NewInstance($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) && \count($oResponse->OptionalResponse) > 1) {
if ('PERMANENTFLAGS' === $oResponse->OptionalResponse[0] &&
is_array($oResponse->OptionalResponse[1]))
{
$oResult->PermanentFlags = $oResponse->OptionalResponse[1];
}
else if ('UIDVALIDITY' === $oResponse->OptionalResponse[0] &&
isset($oResponse->OptionalResponse[1]))
{
$oResult->Uidvalidity = $oResponse->OptionalResponse[1];
}
else if ('UNSEEN' === $oResponse->OptionalResponse[0] &&
isset($oResponse->OptionalResponse[1]) &&
is_numeric($oResponse->OptionalResponse[1]))
{
$oResult->Unread = (int) $oResponse->OptionalResponse[1];
}
else if ('UIDNEXT' === $oResponse->OptionalResponse[0] &&
isset($oResponse->OptionalResponse[1]))
{
$oResult->Uidnext = $oResponse->OptionalResponse[1];
}
else if ('HIGHESTMODSEQ' === $oResponse->OptionalResponse[0] &&
isset($oResponse->OptionalResponse[1]) &&
\is_numeric($oResponse->OptionalResponse[1]))
{
$oResult->HighestModSeq = \trim($oResponse->OptionalResponse[1]);
}
}
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;
}
}
}
}
return $oResult;
}
public function getNamespaceResult() : NamespaceResult
{
foreach ($this as $oResponse) {
if (Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType &&
'NAMESPACE' === $oResponse->StatusOrIndex)
{
$oReturn = NamespaceResult::NewInstance();
$oReturn->InitByImapResponse($oResponse);
return $oReturn;
}
}
throw new Exceptions\ResponseException();
}
public function getQuotaResult() : array
{
$aReturn = array(0, 0);
foreach ($this as $oResponse) {
if (Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType
&& 'QUOTA' === $oResponse->StatusOrIndex
&& \is_array($oResponse->ResponseList)
&& isset($oResponse->ResponseList[3])
&& \is_array($oResponse->ResponseList[3])
&& 2 < \count($oResponse->ResponseList[3])
&& 'STORAGE' === \strtoupper($oResponse->ResponseList[3][0])
&& \is_numeric($oResponse->ResponseList[3][1])
&& \is_numeric($oResponse->ResponseList[3][2])
)
{
$aReturn = array(
(int) $oResponse->ResponseList[3][1],
(int) $oResponse->ResponseList[3][2],
0,
0
);
if (5 < \count($oResponse->ResponseList[3])
&& 'MESSAGE' === \strtoupper($oResponse->ResponseList[3][3])
&& \is_numeric($oResponse->ResponseList[3][4])
&& \is_numeric($oResponse->ResponseList[3][5])
)
{
$aReturn[2] = (int) $oResponse->ResponseList[3][4];
$aReturn[3] = (int) $oResponse->ResponseList[3][5];
}
}
}
return $aReturn;
}
public function getSimpleESearchOrESortResult(string $sRequestTag, bool $bReturnUid) : array
{
$aResult = array();
foreach ($this as $oResponse) {
if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType
&& ('ESEARCH' === $oResponse->StatusOrIndex || 'ESORT' === $oResponse->StatusOrIndex)
&& \is_array($oResponse->ResponseList)
&& isset($oResponse->ResponseList[2], $oResponse->ResponseList[2][0], $oResponse->ResponseList[2][1])
&& 'TAG' === $oResponse->ResponseList[2][0] && $sRequestTag === $oResponse->ResponseList[2][1]
&& (!$bReturnUid || ($bReturnUid && !empty($oResponse->ResponseList[3]) && 'UID' === $oResponse->ResponseList[3]))
)
{
$iStart = 3;
foreach ($oResponse->ResponseList as $iIndex => $mItem) {
if ($iIndex >= $iStart) {
switch ($mItem)
{
case 'ALL':
case 'MAX':
case 'MIN':
case 'COUNT':
if (isset($oResponse->ResponseList[$iIndex + 1])) {
$aResult[$mItem] = $oResponse->ResponseList[$iIndex + 1];
}
break;
}
}
}
}
}
return $aResult;
}
public function getStatusFolderInformationResult() : array
{
$aReturn = array();
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;
}
}
}
}
return $aReturn;
}
/**
* @param mixed $mValue
*
* @return mixed
*/
private function validateThreadItem($mValue)
{
$mResult = false;
if (\is_numeric($mValue)) {
$mResult = (int) $mValue;
if (0 >= $mResult) {
$mResult = false;
}
} else if (\is_array($mValue)) {
if (1 === \count($mValue) && \is_numeric($mValue[0])) {
$mResult = (int) $mValue[0];
if (0 >= $mResult) {
$mResult = false;
}
} else {
$mResult = array();
foreach ($mValue as $mValueItem) {
$mTemp = $this->validateThreadItem($mValueItem);
if (false !== $mTemp) {
$mResult[] = $mTemp;
}
}
}
}
return $mResult;
}
}