mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-04 23:17:02 +03:00
v1.3.3.451
This commit is contained in:
parent
87f10aecd6
commit
8b9afa23bd
434 changed files with 1171 additions and 660 deletions
856
rainloop/v/1.3.3.451/app/libraries/MailSo/Imap/BodyStructure.php
Normal file
856
rainloop/v/1.3.3.451/app/libraries/MailSo/Imap/BodyStructure.php
Normal file
|
|
@ -0,0 +1,856 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
*/
|
||||
class BodyStructure
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sContentType;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sCharset;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aBodyParams;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sContentID;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDescription;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sMailEncodingName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDisposition;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aDispositionParams;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sFileName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sLanguage;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sLocation;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iSize;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iTextLineCount;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPartID;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aSubParts;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*
|
||||
* @param string $sContentType
|
||||
* @param string $sCharset
|
||||
* @param array $aBodyParams
|
||||
* @param string $sContentID
|
||||
* @param string $sDescription
|
||||
* @param string $sMailEncodingName
|
||||
* @param string $sDisposition
|
||||
* @param array $aDispositionParams
|
||||
* @param string $sFileName
|
||||
* @param string $sLanguage
|
||||
* @param string $sLocation
|
||||
* @param int $iSize
|
||||
* @param int $iTextLineCount
|
||||
* @param string $sPartID
|
||||
* @param array $aSubParts
|
||||
*/
|
||||
private function __construct($sContentType, $sCharset, $aBodyParams, $sContentID,
|
||||
$sDescription, $sMailEncodingName, $sDisposition, $aDispositionParams, $sFileName,
|
||||
$sLanguage, $sLocation, $iSize, $iTextLineCount, $sPartID, $aSubParts)
|
||||
{
|
||||
$this->sContentType = $sContentType;
|
||||
$this->sCharset = $sCharset;
|
||||
$this->aBodyParams = $aBodyParams;
|
||||
$this->sContentID = $sContentID;
|
||||
$this->sDescription = $sDescription;
|
||||
$this->sMailEncodingName = $sMailEncodingName;
|
||||
$this->sDisposition = $sDisposition;
|
||||
$this->aDispositionParams = $aDispositionParams;
|
||||
$this->sFileName = $sFileName;
|
||||
$this->sLanguage = $sLanguage;
|
||||
$this->sLocation = $sLocation;
|
||||
$this->iSize = $iSize;
|
||||
$this->iTextLineCount = $iTextLineCount;
|
||||
$this->sPartID = $sPartID;
|
||||
$this->aSubParts = $aSubParts;
|
||||
}
|
||||
|
||||
/**
|
||||
* return string
|
||||
*/
|
||||
public function MailEncodingName()
|
||||
{
|
||||
return $this->sMailEncodingName;
|
||||
}
|
||||
|
||||
/**
|
||||
* return string
|
||||
*/
|
||||
public function PartID()
|
||||
{
|
||||
return (string) $this->sPartID;
|
||||
}
|
||||
|
||||
/**
|
||||
* return string
|
||||
*/
|
||||
public function FileName()
|
||||
{
|
||||
return $this->sFileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* return string
|
||||
*/
|
||||
public function ContentType()
|
||||
{
|
||||
return $this->sContentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* return int
|
||||
*/
|
||||
public function Size()
|
||||
{
|
||||
return (int) $this->iSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* return int
|
||||
*/
|
||||
public function EstimatedSize()
|
||||
{
|
||||
$fCoefficient = 1;
|
||||
switch (strtolower($this->MailEncodingName()))
|
||||
{
|
||||
case 'base64':
|
||||
$fCoefficient = 0.75;
|
||||
break;
|
||||
case 'quoted-printable':
|
||||
$fCoefficient = 0.44;
|
||||
break;
|
||||
}
|
||||
|
||||
return (int) ($this->Size() * $fCoefficient);
|
||||
}
|
||||
|
||||
/**
|
||||
* return string
|
||||
*/
|
||||
public function Charset()
|
||||
{
|
||||
return $this->sCharset;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* return string
|
||||
*/
|
||||
public function ContentID()
|
||||
{
|
||||
return (null === $this->sContentID) ? '' : $this->sContentID;
|
||||
}
|
||||
|
||||
/**
|
||||
* return bool
|
||||
*/
|
||||
public function IsInline()
|
||||
{
|
||||
return (null === $this->sDisposition) ?
|
||||
(0 < strlen($this->ContentID())) : ('inline' === strtolower($this->sDisposition));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
public function SearchPlainParts()
|
||||
{
|
||||
$aReturn = array();
|
||||
$aParts = $this->SearchByContentType('text/plain');
|
||||
foreach ($aParts as $oPart)
|
||||
{
|
||||
if (!$oPart->isAttachBodyPart())
|
||||
{
|
||||
$aReturn[] = $oPart;
|
||||
}
|
||||
}
|
||||
return $aReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
public function SearchHtmlParts()
|
||||
{
|
||||
$aReturn = array();
|
||||
$aParts = $this->SearchByContentType('text/html');
|
||||
|
||||
foreach ($aParts as $oPart)
|
||||
{
|
||||
if (!$oPart->isAttachBodyPart())
|
||||
{
|
||||
$aReturn[] = $oPart;
|
||||
}
|
||||
}
|
||||
|
||||
return $aReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
public function SearchHtmlOrPlainParts()
|
||||
{
|
||||
$mResult = $this->SearchHtmlParts();
|
||||
if (null === $mResult || (is_array($mResult) && 0 === count($mResult)))
|
||||
{
|
||||
$mResult = $this->SearchPlainParts();
|
||||
}
|
||||
|
||||
return $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function SearchCharset()
|
||||
{
|
||||
$sResult = '';
|
||||
|
||||
$mHtmlParts = $this->SearchHtmlParts();
|
||||
$mPlainParts = $this->SearchPlainParts();
|
||||
$mParts = array();
|
||||
if (is_array($mHtmlParts) && 0 < count($mHtmlParts))
|
||||
{
|
||||
$mParts = array_merge($mParts, $mHtmlParts);
|
||||
}
|
||||
|
||||
if (is_array($mPlainParts) && 0 < count($mPlainParts))
|
||||
{
|
||||
$mParts = array_merge($mParts, $mPlainParts);
|
||||
}
|
||||
|
||||
foreach ($mParts as $oPart)
|
||||
{
|
||||
$sResult = $oPart ? $oPart->Charset() : '';
|
||||
if (!empty($sResult))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 === strlen($sResult))
|
||||
{
|
||||
$aParts = $this->SearchAttachmentsParts();
|
||||
foreach ($aParts as $oPart)
|
||||
{
|
||||
if (0 === strlen($sResult))
|
||||
{
|
||||
$sResult = $oPart ? $oPart->Charset() : '';
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function isAttachBodyPart()
|
||||
{
|
||||
$bResult = (
|
||||
(null !== $this->sDisposition && 'attachment' === strtolower($this->sDisposition))
|
||||
);
|
||||
|
||||
if (!$bResult && null !== $this->sContentType)
|
||||
{
|
||||
$sContentType = strtolower($this->sContentType);
|
||||
$bResult = false === strpos($sContentType, 'multipart/') &&
|
||||
'text/html' !== $sContentType && 'text/plain' !== $sContentType;
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function SearchAttachmentsParts()
|
||||
{
|
||||
$aReturn = array();
|
||||
if ($this->isAttachBodyPart())
|
||||
{
|
||||
$aReturn[] = $this;
|
||||
}
|
||||
|
||||
if (is_array($this->aSubParts) && 0 < count($this->aSubParts))
|
||||
{
|
||||
foreach ($this->aSubParts as /* @var $oSubPart \MailSo\Imap\BodyStructure */ &$oSubPart)
|
||||
{
|
||||
$aReturn = array_merge($aReturn, $oSubPart->SearchAttachmentsParts());
|
||||
unset($oSubPart);
|
||||
}
|
||||
}
|
||||
|
||||
return $aReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sContentType
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function SearchByContentType($sContentType)
|
||||
{
|
||||
$aReturn = array();
|
||||
if (strtolower($sContentType) === $this->sContentType)
|
||||
{
|
||||
$aReturn[] = $this;
|
||||
}
|
||||
|
||||
if (is_array($this->aSubParts) && 0 < count($this->aSubParts))
|
||||
{
|
||||
foreach ($this->aSubParts as /* @var $oSubPart \MailSo\Imap\BodyStructure */ &$oSubPart)
|
||||
{
|
||||
$aReturn = array_merge($aReturn, $oSubPart->SearchByContentType($sContentType));
|
||||
}
|
||||
}
|
||||
|
||||
return $aReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sMimeIndex
|
||||
*
|
||||
* @return \MailSo\Imap\BodyStructure
|
||||
*/
|
||||
public function GetPartByMimeIndex($sMimeIndex)
|
||||
{
|
||||
$oPart = null;
|
||||
if (0 < strlen($sMimeIndex))
|
||||
{
|
||||
if ($sMimeIndex === $this->sPartID)
|
||||
{
|
||||
$oPart = $this;
|
||||
}
|
||||
|
||||
if (null === $oPart && is_array($this->aSubParts) && 0 < count($this->aSubParts))
|
||||
{
|
||||
foreach ($this->aSubParts as /* @var $oSubPart \MailSo\Imap\BodyStructure */ &$oSubPart)
|
||||
{
|
||||
$oPart = $oSubPart->GetPartByMimeIndex($sMimeIndex);
|
||||
if (null !== $oPart)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $oPart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aParams
|
||||
* @param string $sParamName
|
||||
* @param string $sCharset = \MailSo\Base\Enumerations\Charset::UTF_8
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function decodeAttrParamenter($aParams, $sParamName, $sCharset = \MailSo\Base\Enumerations\Charset::UTF_8)
|
||||
{
|
||||
$sResult = '';
|
||||
if (isset($aParams[$sParamName]))
|
||||
{
|
||||
$sResult = \MailSo\Base\Utils::DecodeHeaderValue($aParams[$sParamName], $sCharset);
|
||||
}
|
||||
else if (isset($aParams[$sParamName.'*']))
|
||||
{
|
||||
$aValueParts = explode('\'\'', $aParams[$sParamName.'*'], 2);
|
||||
if (is_array($aValueParts) && 2 === count($aValueParts))
|
||||
{
|
||||
$sCharset = isset($aValueParts[0]) ? $aValueParts[0] : \MailSo\Base\Enumerations\Charset::UTF_8;
|
||||
|
||||
$sResult = \MailSo\Base\Utils::ConvertEncoding(
|
||||
urldecode($aValueParts[1]), $sCharset, \MailSo\Base\Enumerations\Charset::UTF_8);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sResult = urldecode($aParams[$sParamName.'*']);
|
||||
}
|
||||
}
|
||||
else if (isset($aParams[$sParamName.'*0*']))
|
||||
{
|
||||
$sCharset = '';
|
||||
$aFileNames = array();
|
||||
foreach ($aParams as $sName => $sValue)
|
||||
{
|
||||
$aMatches = array();
|
||||
if ($sParamName.'*0*' === $sName)
|
||||
{
|
||||
if (0 === strlen($sCharset))
|
||||
{
|
||||
$aValueParts = explode('\'\'', $sValue, 2);
|
||||
if (is_array($aValueParts) && 2 === count($aValueParts) && 0 < strlen($aValueParts[0]))
|
||||
{
|
||||
$sCharset = $aValueParts[0];
|
||||
$sValue = $aValueParts[1];
|
||||
}
|
||||
}
|
||||
|
||||
$aFileNames[0] = $sValue;
|
||||
}
|
||||
else if ($sParamName.'*0*' !== $sName && preg_match('/^'.preg_quote($sParamName, '/').'\*([0-9]+)\*$/i', $sName, $aMatches) && 0 < strlen($aMatches[1]))
|
||||
{
|
||||
$aFileNames[(int) $aMatches[1]] = $sValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < count($aFileNames))
|
||||
{
|
||||
ksort($aFileNames, SORT_NUMERIC);
|
||||
$sResult = implode(array_values($aFileNames));
|
||||
$sResult = urldecode($sResult);
|
||||
|
||||
if (0 < strlen($sCharset))
|
||||
{
|
||||
$sResult = \MailSo\Base\Utils::ConvertEncoding($sResult,
|
||||
$sCharset, \MailSo\Base\Enumerations\Charset::UTF_8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aBodyStructure
|
||||
* @param string $sPartID = ''
|
||||
*
|
||||
* @return \MailSo\Imap\BodyStructure
|
||||
*/
|
||||
public static function NewInstance(array $aBodyStructure, $sPartID = '')
|
||||
{
|
||||
if (!is_array($aBodyStructure) || 2 > count($aBodyStructure))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$sBodyMainType = null;
|
||||
if (is_string($aBodyStructure[0]) && 'NIL' !== $aBodyStructure[0])
|
||||
{
|
||||
$sBodyMainType = $aBodyStructure[0];
|
||||
}
|
||||
|
||||
$sBodySubType = null;
|
||||
$sContentType = '';
|
||||
$aSubParts = null;
|
||||
$aBodyParams = array();
|
||||
$sName = null;
|
||||
$sCharset = null;
|
||||
$sContentID = null;
|
||||
$sDescription = null;
|
||||
$sMailEncodingName = null;
|
||||
$iSize = 0;
|
||||
$iTextLineCount = 0; // valid for rfc822/message and text parts
|
||||
$iExtraItemPos = 0; // list index of items which have no well-established position (such as 0, 1, 5, etc).
|
||||
|
||||
if (null === $sBodyMainType)
|
||||
{
|
||||
// Process multipart body structure
|
||||
if (!is_array($aBodyStructure[0]))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$sBodyMainType = 'multipart';
|
||||
$sSubPartIDPrefix = '';
|
||||
if (0 === strlen($sPartID) || '.' === $sPartID[strlen($sPartID) - 1])
|
||||
{
|
||||
// This multi-part is root part of message.
|
||||
$sSubPartIDPrefix = $sPartID;
|
||||
$sPartID .= 'TEXT';
|
||||
}
|
||||
else if (0 < strlen($sPartID))
|
||||
{
|
||||
// This multi-part is a part of another multi-part.
|
||||
$sSubPartIDPrefix = $sPartID.'.';
|
||||
}
|
||||
|
||||
$aSubParts = array();
|
||||
$iIndex = 1;
|
||||
|
||||
while ($iExtraItemPos < count($aBodyStructure) && is_array($aBodyStructure[$iExtraItemPos]))
|
||||
{
|
||||
$oPart = self::NewInstance($aBodyStructure[$iExtraItemPos], $sSubPartIDPrefix.$iIndex);
|
||||
if (null === $oPart)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// For multipart, we have no charset info in the part itself. Thus,
|
||||
// obtain charset from nested parts.
|
||||
if ($sCharset == null)
|
||||
{
|
||||
$sCharset = $oPart->Charset();
|
||||
}
|
||||
|
||||
$aSubParts[] = $oPart;
|
||||
$iExtraItemPos++;
|
||||
$iIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($iExtraItemPos < count($aBodyStructure))
|
||||
{
|
||||
if (!is_string($aBodyStructure[$iExtraItemPos]) || 'NIL' === $aBodyStructure[$iExtraItemPos])
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$sBodySubType = strtolower($aBodyStructure[$iExtraItemPos]);
|
||||
$iExtraItemPos++;
|
||||
}
|
||||
|
||||
if ($iExtraItemPos < count($aBodyStructure))
|
||||
{
|
||||
$sBodyParamList = $aBodyStructure[$iExtraItemPos];
|
||||
if (is_array($sBodyParamList))
|
||||
{
|
||||
$aBodyParams = self::getKeyValueListFromArrayList($sBodyParamList);
|
||||
}
|
||||
}
|
||||
$iExtraItemPos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Process simple (singlepart) body structure
|
||||
if (7 > count($aBodyStructure))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$sBodyMainType = strtolower($sBodyMainType);
|
||||
if (!is_string($aBodyStructure[1]) || 'NIL' === $aBodyStructure[1])
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$sBodySubType = strtolower($aBodyStructure[1]);
|
||||
|
||||
$aBodyParamList = $aBodyStructure[2];
|
||||
if (is_array($aBodyParamList))
|
||||
{
|
||||
$aBodyParams = self::getKeyValueListFromArrayList($aBodyParamList);
|
||||
if (isset($aBodyParams['charset']))
|
||||
{
|
||||
$sCharset = $aBodyParams['charset'];
|
||||
}
|
||||
|
||||
if (is_array($aBodyParams))
|
||||
{
|
||||
$sName = self::decodeAttrParamenter($aBodyParams, 'name', $sContentType);
|
||||
}
|
||||
}
|
||||
|
||||
if (null !== $aBodyStructure[3] && 'NIL' !== $aBodyStructure[3])
|
||||
{
|
||||
if (!is_string($aBodyStructure[3]))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$sContentID = $aBodyStructure[3];
|
||||
}
|
||||
|
||||
if (null !== $aBodyStructure[4] && 'NIL' !== $aBodyStructure[4])
|
||||
{
|
||||
if (!is_string($aBodyStructure[4]))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$sDescription = $aBodyStructure[4];
|
||||
}
|
||||
|
||||
if (null !== $aBodyStructure[5] && 'NIL' !== $aBodyStructure[5])
|
||||
{
|
||||
if (!is_string($aBodyStructure[5]))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
$sMailEncodingName = $aBodyStructure[5];
|
||||
}
|
||||
|
||||
if (is_numeric($aBodyStructure[6]))
|
||||
{
|
||||
$iSize = (int) $aBodyStructure[6];
|
||||
}
|
||||
else
|
||||
{
|
||||
$iSize = -1;
|
||||
}
|
||||
|
||||
if (0 === strlen($sPartID) || '.' === $sPartID[strlen($sPartID) - 1])
|
||||
{
|
||||
// This is the only sub-part of the message (otherwise, it would be
|
||||
// one of sub-parts of a multi-part, and partID would already be fully set up).
|
||||
$sPartID .= '1';
|
||||
}
|
||||
|
||||
$iExtraItemPos = 7;
|
||||
if ('text' === $sBodyMainType)
|
||||
{
|
||||
if ($iExtraItemPos < count($aBodyStructure))
|
||||
{
|
||||
if (is_numeric($aBodyStructure[$iExtraItemPos]))
|
||||
{
|
||||
$iTextLineCount = (int) $aBodyStructure[$iExtraItemPos];
|
||||
}
|
||||
else
|
||||
{
|
||||
$iTextLineCount = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$iTextLineCount = -1;
|
||||
}
|
||||
$iExtraItemPos++;
|
||||
}
|
||||
else if ('message' === $sBodyMainType && 'rfc822' === $sBodySubType)
|
||||
{
|
||||
if ($iExtraItemPos + 2 < count($aBodyStructure))
|
||||
{
|
||||
if (is_numeric($aBodyStructure[$iExtraItemPos + 2]))
|
||||
{
|
||||
$iTextLineCount = (int) $aBodyStructure[$iExtraItemPos + 2];
|
||||
}
|
||||
else
|
||||
{
|
||||
$iTextLineCount = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$iTextLineCount = -1;
|
||||
}
|
||||
|
||||
$iExtraItemPos += 3;
|
||||
}
|
||||
|
||||
$iExtraItemPos++; // skip MD5 digest of the body because most mail servers leave it NIL anyway
|
||||
}
|
||||
|
||||
$sContentType = $sBodyMainType.'/'.$sBodySubType;
|
||||
|
||||
$sDisposition = null;
|
||||
$aDispositionParams = null;
|
||||
$sFileName = null;
|
||||
|
||||
if ($iExtraItemPos < count($aBodyStructure))
|
||||
{
|
||||
$aDispList = $aBodyStructure[$iExtraItemPos];
|
||||
if (is_array($aDispList) && 1 < count($aDispList))
|
||||
{
|
||||
if (null !== $aDispList[0])
|
||||
{
|
||||
if (is_string($aDispList[0]) && 'NIL' !== $aDispList[0])
|
||||
{
|
||||
$sDisposition = $aDispList[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$aDispParamList = $aDispList[1];
|
||||
if (is_array($aDispParamList))
|
||||
{
|
||||
$aDispositionParams = self::getKeyValueListFromArrayList($aDispParamList);
|
||||
if (is_array($aDispositionParams))
|
||||
{
|
||||
$sFileName = self::decodeAttrParamenter($aDispositionParams, 'filename', $sCharset);
|
||||
}
|
||||
}
|
||||
}
|
||||
$iExtraItemPos++;
|
||||
|
||||
$sLanguage = null;
|
||||
if ($iExtraItemPos < count($aBodyStructure))
|
||||
{
|
||||
if (null !== $aBodyStructure[$iExtraItemPos] && 'NIL' !== $aBodyStructure[$iExtraItemPos])
|
||||
{
|
||||
if (is_array($aBodyStructure[$iExtraItemPos]))
|
||||
{
|
||||
$sLanguage = implode(',', $aBodyStructure[$iExtraItemPos]);
|
||||
}
|
||||
else if (is_string($aBodyStructure[$iExtraItemPos]))
|
||||
{
|
||||
$sLanguage = $aBodyStructure[$iExtraItemPos];
|
||||
}
|
||||
}
|
||||
$iExtraItemPos++;
|
||||
}
|
||||
|
||||
$sLocation = null;
|
||||
if ($iExtraItemPos < count($aBodyStructure))
|
||||
{
|
||||
if (null !== $aBodyStructure[$iExtraItemPos] && 'NIL' !== $aBodyStructure[$iExtraItemPos])
|
||||
{
|
||||
if (is_string($aBodyStructure[$iExtraItemPos]))
|
||||
{
|
||||
$sLocation = $aBodyStructure[$iExtraItemPos];
|
||||
}
|
||||
}
|
||||
$iExtraItemPos++;
|
||||
}
|
||||
|
||||
return new self(
|
||||
$sContentType,
|
||||
$sCharset,
|
||||
$aBodyParams,
|
||||
$sContentID,
|
||||
$sDescription,
|
||||
$sMailEncodingName,
|
||||
$sDisposition,
|
||||
$aDispositionParams,
|
||||
\MailSo\Base\Utils::Utf8Clear(
|
||||
null === $sFileName || 0 === strlen($sFileName) ? $sName : $sFileName),
|
||||
$sLanguage,
|
||||
$sLocation,
|
||||
$iSize,
|
||||
$iTextLineCount,
|
||||
$sPartID,
|
||||
$aSubParts
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aBodyStructure
|
||||
* @param string $sPartID
|
||||
*
|
||||
* @return \MailSo\Imap\BodyStructure|null
|
||||
*/
|
||||
public static function NewInstanceFromRfc822SubPart(array $aBodyStructure, $sSubPartID)
|
||||
{
|
||||
$oBody = null;
|
||||
$aBodySubStructure = self::findPartByIndexInArray($aBodyStructure, $sSubPartID);
|
||||
if ($aBodySubStructure && is_array($aBodySubStructure) && isset($aBodySubStructure[8]))
|
||||
{
|
||||
$oBody = self::NewInstance($aBodySubStructure[8], $sSubPartID);
|
||||
}
|
||||
|
||||
return $oBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aList
|
||||
* @param string $sPartID
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
private static function findPartByIndexInArray(array $aList, $sPartID)
|
||||
{
|
||||
$bFind = false;
|
||||
$aPath = explode('.', ''.$sPartID);
|
||||
$aCurrentPart = $aList;
|
||||
foreach ($aPath as $iPos => $iNum)
|
||||
{
|
||||
$iIndex = intval($iNum) - 1;
|
||||
if (0 <= $iIndex && 0 < $iPos ? isset($aCurrentPart[8][$iIndex]) : isset($aCurrentPart[$iIndex]))
|
||||
{
|
||||
$aCurrentPart = 0 < $iPos ? $aCurrentPart[8][$iIndex] : $aCurrentPart[$iIndex];
|
||||
$bFind = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $bFind ? $aCurrentPart : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns dict with key="charset" and value="US-ASCII" for array ("CHARSET" "US-ASCII").
|
||||
* Keys are lowercased (StringDictionary itself does this), values are not altered.
|
||||
*
|
||||
* @param array $aList
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function getKeyValueListFromArrayList(array $aList)
|
||||
{
|
||||
$aDict = null;
|
||||
if (0 === count($aList) % 2)
|
||||
{
|
||||
$aDict = array();
|
||||
for ($iIndex = 0, $iLen = count($aList); $iIndex < $iLen; $iIndex += 2)
|
||||
{
|
||||
if (is_string($aList[$iIndex]) && isset($aList[$iIndex + 1]) && is_string($aList[$iIndex + 1]))
|
||||
{
|
||||
$aDict[strtolower($aList[$iIndex])] = $aList[$iIndex + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $aDict;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap\Enumerations;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Enumerations
|
||||
*/
|
||||
class FetchType
|
||||
{
|
||||
const ALL = 'ALL';
|
||||
const FAST = 'FAST';
|
||||
const FULL = 'FULL';
|
||||
const BODY = 'BODY';
|
||||
const BODY_PEEK = 'BODY.PEEK';
|
||||
const BODY_HEADER = 'BODY[HEADER]';
|
||||
const BODY_HEADER_PEEK = 'BODY.PEEK[HEADER]';
|
||||
const BODYSTRUCTURE = 'BODYSTRUCTURE';
|
||||
const ENVELOPE = 'ENVELOPE';
|
||||
const FLAGS = 'FLAGS';
|
||||
const INTERNALDATE = 'INTERNALDATE';
|
||||
const RFC822 = 'RFC822';
|
||||
const RFC822_HEADER = 'RFC822.HEADER';
|
||||
const RFC822_SIZE = 'RFC822.SIZE';
|
||||
const RFC822_TEXT = 'RFC822.TEXT';
|
||||
const UID = 'UID';
|
||||
const INDEX = 'INDEX';
|
||||
|
||||
const GMAIL_MSGID = 'X-GM-MSGID';
|
||||
const GMAIL_THRID = 'X-GM-THRID';
|
||||
const GMAIL_LABELS = 'X-GM-LABELS';
|
||||
|
||||
/**
|
||||
* @param array $aReturn
|
||||
*
|
||||
* @param string|array $mType
|
||||
*/
|
||||
private static function addHelper(&$aReturn, $mType)
|
||||
{
|
||||
if (is_string($mType))
|
||||
{
|
||||
$aReturn[$mType] = '';
|
||||
}
|
||||
else if (is_array($mType) && 2 === count($mType) && is_string($mType[0]) &&
|
||||
is_callable($mType[1]))
|
||||
{
|
||||
$aReturn[$mType[0]] = $mType[1];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aHeaders
|
||||
* @param bool $bPeek = true
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function BuildBodyCustomHeaderRequest(array $aHeaders, $bPeek = true)
|
||||
{
|
||||
$sResult = '';
|
||||
if (0 < count($aHeaders))
|
||||
{
|
||||
$aHeaders = array_map('trim', $aHeaders);
|
||||
$aHeaders = array_map('strtoupper', $aHeaders);
|
||||
|
||||
$sResult = $bPeek ? self::BODY_PEEK : self::BODY;
|
||||
$sResult .= '[HEADER.FIELDS ('.implode(' ', $aHeaders).')]';
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aFetchItems
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function ChangeFetchItemsBefourRequest(array $aFetchItems)
|
||||
{
|
||||
$aReturn = array();
|
||||
self::addHelper($aReturn, self::UID);
|
||||
|
||||
foreach ($aFetchItems as $mFetchKey)
|
||||
{
|
||||
switch ($mFetchKey)
|
||||
{
|
||||
default:
|
||||
if (is_string($mFetchKey) || is_array($mFetchKey))
|
||||
{
|
||||
self::addHelper($aReturn, $mFetchKey);
|
||||
}
|
||||
break;
|
||||
case self::INDEX:
|
||||
case self::UID:
|
||||
break;
|
||||
case self::ALL:
|
||||
self::addHelper($aReturn, self::FLAGS);
|
||||
self::addHelper($aReturn, self::INTERNALDATE);
|
||||
self::addHelper($aReturn, self::RFC822_SIZE);
|
||||
self::addHelper($aReturn, self::ENVELOPE);
|
||||
break;
|
||||
case self::FAST:
|
||||
self::addHelper($aReturn, self::FLAGS);
|
||||
self::addHelper($aReturn, self::INTERNALDATE);
|
||||
self::addHelper($aReturn, self::RFC822_SIZE);
|
||||
break;
|
||||
case self::FULL:
|
||||
self::addHelper($aReturn, self::FLAGS);
|
||||
self::addHelper($aReturn, self::INTERNALDATE);
|
||||
self::addHelper($aReturn, self::RFC822_SIZE);
|
||||
self::addHelper($aReturn, self::ENVELOPE);
|
||||
self::addHelper($aReturn, self::BODY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $aReturn;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap\Enumerations;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Enumerations
|
||||
*/
|
||||
class FolderResponseStatus
|
||||
{
|
||||
const MESSAGES = 'MESSAGES';
|
||||
const RECENT = 'RECENT';
|
||||
const UNSEEN = 'UNSEEN';
|
||||
const UIDNEXT = 'UIDNEXT';
|
||||
const UIDVALIDITY = 'UIDVALIDITY';
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap\Enumerations;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Enumerations
|
||||
*/
|
||||
class FolderStatus
|
||||
{
|
||||
const MESSAGES = 'MESSAGES';
|
||||
const RECENT = 'RECENT';
|
||||
const UNSEEN = 'UNSEEN';
|
||||
const UIDNEXT = 'UIDNEXT';
|
||||
const UIDVALIDITY = 'UIDVALIDITY';
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap\Enumerations;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Enumerations
|
||||
*/
|
||||
class FolderType
|
||||
{
|
||||
const USER = 0;
|
||||
const INBOX = 1;
|
||||
const SENT = 2;
|
||||
const DRAFTS = 3;
|
||||
const SPAM = 4;
|
||||
const TRASH = 5;
|
||||
const IMPORTANT = 10;
|
||||
const STARRED = 11;
|
||||
const ALLMAIL = 12;
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap\Enumerations;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Enumerations
|
||||
*/
|
||||
class MessageFlag
|
||||
{
|
||||
const RECENT = '\Recent';
|
||||
const SEEN = '\Seen';
|
||||
const DELETED = '\Deleted';
|
||||
const FLAGGED = '\Flagged';
|
||||
const ANSWERED = '\Answered';
|
||||
const DRAFT = '\Draft';
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap\Enumerations;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Enumerations
|
||||
*/
|
||||
class ResponseStatus
|
||||
{
|
||||
const OK = 'OK';
|
||||
const NO = 'NO';
|
||||
const BAD = 'BAD';
|
||||
const BYE = 'BYE';
|
||||
const PREAUTH = 'PREAUTH';
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap\Enumerations;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Enumerations
|
||||
*/
|
||||
class ResponseType
|
||||
{
|
||||
const UNKNOWN = 0;
|
||||
const TAGGED = 1;
|
||||
const UNTAGGED = 2;
|
||||
const CONTINUATION = 3;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap\Enumerations;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Enumerations
|
||||
*/
|
||||
class StoreAction
|
||||
{
|
||||
const SET_FLAGS = 'FLAGS';
|
||||
const SET_FLAGS_SILENT = 'FLAGS.SILENT';
|
||||
const ADD_FLAGS = '+FLAGS';
|
||||
const ADD_FLAGS_SILENT = '+FLAGS.SILENT';
|
||||
const REMOVE_FLAGS = '-FLAGS';
|
||||
const REMOVE_FLAGS_SILENT = '-FLAGS.SILENT';
|
||||
|
||||
const SET_GMAIL_LABELS = 'X-GM-LABELS';
|
||||
const SET_GMAIL_LABELS_SILENT = 'X-GM-LABELS.SILENT';
|
||||
const ADD_GMAIL_LABELS = '+X-GM-LABELS';
|
||||
const ADD_GMAIL_LABELS_SILENT = '+X-GM-LABELS.SILENT';
|
||||
const REMOVE_GMAIL_LABELS = '-X-GM-LABELS';
|
||||
const REMOVE_GMAIL_LABELS_SILENT = '-X-GM-LABELS.SILENT';
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class Exception extends \MailSo\Base\Exceptions\Exception {}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class InvalidResponseException extends \MailSo\Imap\Exceptions\ResponseException {}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class LoginBadCredentialsException extends \MailSo\Imap\Exceptions\LoginException {}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class LoginBadMethodException extends \MailSo\Imap\Exceptions\LoginException {}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class LoginException extends \MailSo\Imap\Exceptions\NegativeResponseException {}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class NegativeResponseException extends \MailSo\Imap\Exceptions\ResponseException {}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class ResponseException extends \MailSo\Imap\Exceptions\Exception
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aResponses;
|
||||
|
||||
/**
|
||||
* @param array $aResponses = array
|
||||
* @param string $sMessage = ''
|
||||
* @param int $iCode = 0
|
||||
* @param \Exception $oPrevious = null
|
||||
*/
|
||||
public function __construct($aResponses = array(), $sMessage = '', $iCode = 0, $oPrevious = null)
|
||||
{
|
||||
parent::__construct($sMessage, $iCode, $oPrevious);
|
||||
|
||||
if (is_array($aResponses))
|
||||
{
|
||||
$this->aResponses = $aResponses;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function GetResponses()
|
||||
{
|
||||
return $this->aResponses;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Imap\Response | null
|
||||
*/
|
||||
public function GetLastResponse()
|
||||
{
|
||||
return 0 < count($this->aResponses) ? $this->aResponses[count($this->aResponses) - 1] : null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class ResponseNotFoundException extends \MailSo\Imap\Exceptions\Exception {}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap\Exceptions;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
* @subpackage Exceptions
|
||||
*/
|
||||
class RuntimeException extends \MailSo\Imap\Exceptions\Exception {}
|
||||
225
rainloop/v/1.3.3.451/app/libraries/MailSo/Imap/FetchResponse.php
Normal file
225
rainloop/v/1.3.3.451/app/libraries/MailSo/Imap/FetchResponse.php
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
*/
|
||||
class FetchResponse
|
||||
{
|
||||
/**
|
||||
* @var \MailSo\Imap\Response
|
||||
*/
|
||||
private $oImapResponse;
|
||||
|
||||
/**
|
||||
* @var array|null
|
||||
*/
|
||||
private $aEnvelopeCache;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*
|
||||
* @param \MailSo\Imap\Response $oImapResponse
|
||||
*/
|
||||
private function __construct(&$oImapResponse)
|
||||
{
|
||||
$this->oImapResponse =& $oImapResponse;
|
||||
$this->aEnvelopeCache = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Imap\Response &$oImapResponse
|
||||
* @return \MailSo\Imap\FetchResponse
|
||||
*/
|
||||
public static function NewInstance(&$oImapResponse)
|
||||
{
|
||||
return new self($oImapResponse);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bForce = false
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function GetEnvelope($bForce = false)
|
||||
{
|
||||
if (null === $this->aEnvelopeCache || $bForce)
|
||||
{
|
||||
$this->aEnvelopeCache = $this->GetFetchValue(Enumerations\FetchType::ENVELOPE);
|
||||
}
|
||||
return $this->aEnvelopeCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iIndex
|
||||
* @param mixed $mNullResult = null
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetFetchEnvelopeValue($iIndex, $mNullResult)
|
||||
{
|
||||
return self::findEnvelopeIndex($this->GetEnvelope(), $iIndex, $mNullResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iIndex
|
||||
* @param string $sParentCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1
|
||||
*
|
||||
* @return \MailSo\Mime\EmailCollection|null
|
||||
*/
|
||||
public function GetFetchEnvelopeEmailCollection($iIndex, $sParentCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1)
|
||||
{
|
||||
$oResult = null;
|
||||
$aEmails = $this->GetFetchEnvelopeValue($iIndex, null);
|
||||
if (is_array($aEmails) && 0 < count($aEmails))
|
||||
{
|
||||
$oResult = \MailSo\Mime\EmailCollection::NewInstance();
|
||||
foreach ($aEmails as $aEmailItem)
|
||||
{
|
||||
if (is_array($aEmailItem) && 4 === count($aEmailItem))
|
||||
{
|
||||
$sDisplayName = \MailSo\Base\Utils::DecodeHeaderValue(
|
||||
self::findEnvelopeIndex($aEmailItem, 0, ''), $sParentCharset);
|
||||
|
||||
$sRemark = \MailSo\Base\Utils::DecodeHeaderValue(
|
||||
self::findEnvelopeIndex($aEmailItem, 1, ''), $sParentCharset);
|
||||
|
||||
$sLocalPart = self::findEnvelopeIndex($aEmailItem, 2, '');
|
||||
$sDomainPart = self::findEnvelopeIndex($aEmailItem, 3, '');
|
||||
|
||||
if (0 < strlen($sLocalPart) && 0 < strlen($sDomainPart))
|
||||
{
|
||||
$oResult->Add(
|
||||
\MailSo\Mime\Email::NewInstance(
|
||||
$sLocalPart.'@'.$sDomainPart, $sDisplayName, $sRemark)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $oResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sRfc822SubMimeIndex = ''
|
||||
*
|
||||
* @return \MailSo\Imap\BodyStructure|null
|
||||
*/
|
||||
public function GetFetchBodyStructure($sRfc822SubMimeIndex = '')
|
||||
{
|
||||
$oBodyStructure = null;
|
||||
$aBodyStructureArray = $this->GetFetchValue(Enumerations\FetchType::BODYSTRUCTURE);
|
||||
|
||||
if (is_array($aBodyStructureArray))
|
||||
{
|
||||
if (0 < strlen($sRfc822SubMimeIndex))
|
||||
{
|
||||
$oBodyStructure = BodyStructure::NewInstanceFromRfc822SubPart($aBodyStructureArray, $sRfc822SubMimeIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oBodyStructure = BodyStructure::NewInstance($aBodyStructureArray);
|
||||
}
|
||||
}
|
||||
|
||||
return $oBodyStructure;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFetchItemName
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function &GetFetchValue($sFetchItemName)
|
||||
{
|
||||
$mReturn = null;
|
||||
$bNextIsValue = false;
|
||||
|
||||
if (Enumerations\FetchType::INDEX === $sFetchItemName)
|
||||
{
|
||||
$mReturn =& $this->oImapResponse->ResponseList[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($this->oImapResponse->ResponseList[3] as &$mItem)
|
||||
{
|
||||
if ($bNextIsValue)
|
||||
{
|
||||
$mReturn =& $mItem;
|
||||
break;
|
||||
}
|
||||
|
||||
if ($sFetchItemName === $mItem)
|
||||
{
|
||||
$bNextIsValue = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $mReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sRfc822SubMimeIndex = ''
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetHeaderFieldsValue($sRfc822SubMimeIndex = '')
|
||||
{
|
||||
$sReturn = '';
|
||||
$bNextIsValue = false;
|
||||
|
||||
$sRfc822SubMimeIndex = 0 < \strlen($sRfc822SubMimeIndex) ? ''.$sRfc822SubMimeIndex.'.' : '';
|
||||
|
||||
if (isset($this->oImapResponse->ResponseList[3]) && \is_array($this->oImapResponse->ResponseList[3]))
|
||||
{
|
||||
foreach ($this->oImapResponse->ResponseList[3] as &$mItem)
|
||||
{
|
||||
if ($bNextIsValue)
|
||||
{
|
||||
$sReturn = (string) $mItem;
|
||||
break;
|
||||
}
|
||||
|
||||
if (\is_string($mItem) && (
|
||||
$mItem === 'BODY['.$sRfc822SubMimeIndex.'HEADER]' ||
|
||||
0 === \strpos($mItem, 'BODY['.$sRfc822SubMimeIndex.'HEADER.FIELDS') ||
|
||||
$mItem === 'BODY['.$sRfc822SubMimeIndex.'MIME]'))
|
||||
{
|
||||
$bNextIsValue = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $sReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Imap\Response $oImapResponse
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function IsValidFetchImapResponse($oImapResponse)
|
||||
{
|
||||
return ($oImapResponse && true !== $oImapResponse->IsStatusResponse
|
||||
&& \MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oImapResponse->ResponseType
|
||||
&& 3 < count($oImapResponse->ResponseList) && 'FETCH' === $oImapResponse->ResponseList[2]
|
||||
&& is_array($oImapResponse->ResponseList[3]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aEnvelope
|
||||
* @param int $iIndex
|
||||
* @param mixed $mNullResult = null
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private static function findEnvelopeIndex($aEnvelope, $iIndex, $mNullResult)
|
||||
{
|
||||
return (isset($aEnvelope[$iIndex]) && 'NIL' !== $aEnvelope[$iIndex] && '' !== $aEnvelope[$iIndex])
|
||||
? $aEnvelope[$iIndex] : $mNullResult;
|
||||
}
|
||||
}
|
||||
179
rainloop/v/1.3.3.451/app/libraries/MailSo/Imap/Folder.php
Normal file
179
rainloop/v/1.3.3.451/app/libraries/MailSo/Imap/Folder.php
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
*/
|
||||
class Folder
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sNameRaw;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sFullNameRaw;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDelimiter;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aFlags;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aFlagsLowerCase;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aExtended;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*
|
||||
* @param string $sFullNameRaw
|
||||
* @param string $sDelimiter
|
||||
* @param array $aFlags
|
||||
*
|
||||
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
private function __construct($sFullNameRaw, $sDelimiter, array $aFlags)
|
||||
{
|
||||
$this->sNameRaw = '';
|
||||
$this->sFullNameRaw = '';
|
||||
$this->sDelimiter = '';
|
||||
$this->aFlags = array();
|
||||
$this->aExtended = array();
|
||||
|
||||
$sDelimiter = 'NIL' === \strtoupper($sDelimiter) ? '' : $sDelimiter;
|
||||
if (empty($sDelimiter))
|
||||
{
|
||||
$sDelimiter = '.'; // default delimiter
|
||||
}
|
||||
|
||||
if (!\is_array($aFlags) ||
|
||||
!\is_string($sDelimiter) || 1 < \strlen($sDelimiter) ||
|
||||
!\is_string($sFullNameRaw) || 0 === \strlen($sFullNameRaw))
|
||||
{
|
||||
throw new \MailSo\Base\Exceptions\InvalidArgumentException();
|
||||
}
|
||||
|
||||
$this->sFullNameRaw = $sFullNameRaw;
|
||||
$this->sDelimiter = $sDelimiter;
|
||||
$this->aFlags = $aFlags;
|
||||
$this->aFlagsLowerCase = \array_map('strtolower', $this->aFlags);
|
||||
|
||||
$this->sFullNameRaw = 'INBOX'.$this->sDelimiter === \substr(\strtoupper($this->sFullNameRaw), 0, 5 + \strlen($this->sDelimiter)) ?
|
||||
'INBOX'.\substr($this->sFullNameRaw, 5) : $this->sFullNameRaw;
|
||||
|
||||
if ($this->IsInbox())
|
||||
{
|
||||
$this->sFullNameRaw = 'INBOX';
|
||||
}
|
||||
|
||||
$this->sNameRaw = $this->sFullNameRaw;
|
||||
if (0 < \strlen($this->sDelimiter))
|
||||
{
|
||||
$aNames = \explode($this->sDelimiter, $this->sFullNameRaw);
|
||||
$this->sNameRaw = \end($aNames);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFullNameRaw
|
||||
* @param string $sDelimiter = '.'
|
||||
* @param array $aFlags = array()
|
||||
*
|
||||
* @return \MailSo\Imap\Folder
|
||||
*
|
||||
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
public static function NewInstance($sFullNameRaw, $sDelimiter = '.', $aFlags = array())
|
||||
{
|
||||
return new self($sFullNameRaw, $sDelimiter, $aFlags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function NameRaw()
|
||||
{
|
||||
return $this->sNameRaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function FullNameRaw()
|
||||
{
|
||||
return $this->sFullNameRaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string | null
|
||||
*/
|
||||
public function Delimiter()
|
||||
{
|
||||
return $this->sDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function Flags()
|
||||
{
|
||||
return $this->aFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function FlagsLowerCase()
|
||||
{
|
||||
return $this->aFlagsLowerCase;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsSelectable()
|
||||
{
|
||||
return !\in_array('\noselect', $this->aFlagsLowerCase);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsInbox()
|
||||
{
|
||||
return 'INBOX' === \strtoupper($this->sFullNameRaw) || \in_array('\inbox', $this->aFlagsLowerCase);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $mData
|
||||
*/
|
||||
public function SetExtended($sName, $mData)
|
||||
{
|
||||
$this->aExtended[$sName] = $mData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetExtended($sName)
|
||||
{
|
||||
return isset($this->aExtended[$sName]) ? $this->aExtended[$sName] : null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
*/
|
||||
class FolderInformation
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $FolderName;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $IsWritable;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $Flags;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $PermanentFlags;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $Exists;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $Recent;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $Uidvalidity;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $Unread;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $Uidnext;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*
|
||||
* @param string $sFolderName
|
||||
* @param bool $bIsWritable
|
||||
*/
|
||||
private function __construct($sFolderName, $bIsWritable)
|
||||
{
|
||||
$this->FolderName = $sFolderName;
|
||||
$this->IsWritable = $bIsWritable;
|
||||
$this->Exists = null;
|
||||
$this->Recent = null;
|
||||
$this->Flags = array();
|
||||
$this->PermanentFlags = array();
|
||||
|
||||
$this->Unread = null;
|
||||
$this->Uidnext = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFolderName
|
||||
* @param bool $bIsWritable
|
||||
*
|
||||
* @return \MailSo\Imap\FolderInformation
|
||||
*/
|
||||
public static function NewInstance($sFolderName, $bIsWritable)
|
||||
{
|
||||
return new self($sFolderName, $bIsWritable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sFlag
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function IsFlagSupported($sFlag)
|
||||
{
|
||||
return in_array('\\*', $this->PermanentFlags) || in_array($sFlag, $this->PermanentFlags);
|
||||
}
|
||||
}
|
||||
2186
rainloop/v/1.3.3.451/app/libraries/MailSo/Imap/ImapClient.php
Normal file
2186
rainloop/v/1.3.3.451/app/libraries/MailSo/Imap/ImapClient.php
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,123 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
*/
|
||||
class NamespaceResult
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPersonal;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPersonalDelimiter;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sOtherUser;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sOtherUserDelimiter;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sShared;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sSharedDelimiter;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
$this->sPersonal = '';
|
||||
$this->sPersonalDelimiter = '';
|
||||
$this->sOtherUser = '';
|
||||
$this->sOtherUserDelimiter = '';
|
||||
$this->sShared = '';
|
||||
$this->sSharedDelimiter = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Imap\NamespaceResult
|
||||
*/
|
||||
public static function NewInstance()
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Imap\Response $oImapResponse
|
||||
*
|
||||
* @return \MailSo\Imap\NamespaceResult
|
||||
*/
|
||||
public function InitByImapResponse($oImapResponse)
|
||||
{
|
||||
if ($oImapResponse && $oImapResponse instanceof \MailSo\Imap\Response)
|
||||
{
|
||||
if (isset($oImapResponse->ResponseList[2][0]) &&
|
||||
\is_array($oImapResponse->ResponseList[2][0]) &&
|
||||
2 <= \count($oImapResponse->ResponseList[2][0]))
|
||||
{
|
||||
$this->sPersonal = $oImapResponse->ResponseList[2][0][0];
|
||||
$this->sPersonalDelimiter = $oImapResponse->ResponseList[2][0][1];
|
||||
|
||||
$this->sPersonal = 'INBOX'.$this->sPersonalDelimiter === \substr(\strtoupper($this->sPersonal), 0, 6) ?
|
||||
'INBOX'.$this->sPersonalDelimiter.\substr($this->sPersonal, 6) : $this->sPersonal;
|
||||
}
|
||||
|
||||
if (isset($oImapResponse->ResponseList[3][0]) &&
|
||||
\is_array($oImapResponse->ResponseList[3][0]) &&
|
||||
2 <= \count($oImapResponse->ResponseList[3][0]))
|
||||
{
|
||||
$this->sOtherUser = $oImapResponse->ResponseList[3][0][0];
|
||||
$this->sOtherUserDelimiter = $oImapResponse->ResponseList[3][0][1];
|
||||
|
||||
$this->sOtherUser = 'INBOX'.$this->sOtherUserDelimiter === \substr(\strtoupper($this->sOtherUser), 0, 6) ?
|
||||
'INBOX'.$this->sOtherUserDelimiter.\substr($this->sOtherUser, 6) : $this->sOtherUser;
|
||||
}
|
||||
|
||||
if (isset($oImapResponse->ResponseList[4][0]) &&
|
||||
\is_array($oImapResponse->ResponseList[4][0]) &&
|
||||
2 <= \count($oImapResponse->ResponseList[4][0]))
|
||||
{
|
||||
$this->sShared = $oImapResponse->ResponseList[4][0][0];
|
||||
$this->sSharedDelimiter = $oImapResponse->ResponseList[4][0][1];
|
||||
|
||||
$this->sShared = 'INBOX'.$this->sSharedDelimiter === \substr(\strtoupper($this->sShared), 0, 6) ?
|
||||
'INBOX'.$this->sSharedDelimiter.\substr($this->sShared, 6) : $this->sShared;
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetPersonalNamespace()
|
||||
{
|
||||
return $this->sPersonal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetPersonalNamespaceDelimiter()
|
||||
{
|
||||
return $this->sPersonalDelimiter;
|
||||
}
|
||||
}
|
||||
67
rainloop/v/1.3.3.451/app/libraries/MailSo/Imap/Response.php
Normal file
67
rainloop/v/1.3.3.451/app/libraries/MailSo/Imap/Response.php
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
*/
|
||||
class Response
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $ResponseList;
|
||||
|
||||
/**
|
||||
* @var array | null
|
||||
*/
|
||||
public $OptionalResponse;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $StatusOrIndex;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $HumanReadable;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $IsStatusResponse;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $ResponseType;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $Tag;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
$this->ResponseList = array();
|
||||
$this->OptionalResponse = null;
|
||||
$this->StatusOrIndex = '';
|
||||
$this->HumanReadable = '';
|
||||
$this->IsStatusResponse = false;
|
||||
$this->ResponseType = \MailSo\Imap\Enumerations\ResponseType::UNKNOWN;
|
||||
$this->Tag = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Imap\Response
|
||||
*/
|
||||
public static function NewInstance()
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
}
|
||||
104
rainloop/v/1.3.3.451/app/libraries/MailSo/Imap/SearchBuilder.php
Normal file
104
rainloop/v/1.3.3.451/app/libraries/MailSo/Imap/SearchBuilder.php
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
namespace MailSo\Imap;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Imap
|
||||
*/
|
||||
class SearchBuilder
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $aList;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
$this->Clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Imap\SearchBuilder
|
||||
*/
|
||||
public static function NewInstance()
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Imap\SearchBuilder
|
||||
*/
|
||||
public function Clear()
|
||||
{
|
||||
$this->aList = array();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param string $sValue = ''
|
||||
*
|
||||
* @return \MailSo\Imap\SearchBuilder
|
||||
*/
|
||||
public function AddAnd($sName, $sValue = '')
|
||||
{
|
||||
return $this->addCri('AND', $sName, $sValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param string $sValue = ''
|
||||
*
|
||||
* @return \MailSo\Imap\SearchBuilder
|
||||
*/
|
||||
public function AddOr($sName, $sValue = '')
|
||||
{
|
||||
return $this->addCri('OR', $sName, $sValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Complete()
|
||||
{
|
||||
$sResult = '';
|
||||
foreach ($this->aList as $iIndex => $aItem)
|
||||
{
|
||||
$sResult = trim((0 < $iIndex && 'OR' === $aItem[0] ? $aItem[0] : '').
|
||||
(0 === strlen($sResult) ? '' : ' ('.$sResult.')').' '.$aItem[1].
|
||||
(0 < strlen($aItem[2]) ? ' '.$aItem[2] : ''));
|
||||
}
|
||||
|
||||
if (0 === strlen($sResult))
|
||||
{
|
||||
$sResult = 'ALL';
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->Complete();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sType
|
||||
* @param string $sName
|
||||
* @param string $sValue = ''
|
||||
*
|
||||
* @return \MailSo\Imap\SearchBuilder
|
||||
*/
|
||||
private function addCri($sType, $sName, $sValue = '')
|
||||
{
|
||||
$this->aList[] = array($sType, $sName, $sValue);
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue