Capability improvements

Additional branding options
This commit is contained in:
RainLoop Team 2015-05-20 02:05:54 +04:00
parent 7fce424758
commit 763fae345b
46 changed files with 880 additions and 556 deletions

View file

@ -907,7 +907,7 @@ END;
public static function GetClearDomainName($sDomain)
{
$sResultDomain = \preg_replace(
'/^(webmail|email|mail|www|imap4|pop3|imap|pop|demo|client|ssl|secure)\./i',
'/^(webmail|email|mail|www|imap4|pop3|imap|pop|demo|client|ssl|secure|test|cloud|box|m)\./i',
'', $sDomain);
return false === \strpos($sResultDomain, '.') ? $sDomain : $sResultDomain;

View file

@ -46,6 +46,11 @@ class Config
*/
public static $MessageListDateFilter = 0;
/**
* @var string
*/
public static $MessageListPermanentFilter = '';
/**
* @var int
*/

View file

@ -22,5 +22,6 @@ class FolderResponseStatus
const RECENT = 'RECENT';
const UNSEEN = 'UNSEEN';
const UIDNEXT = 'UIDNEXT';
const HIGHESTMODSEQ = 'HIGHESTMODSEQ';
const UIDVALIDITY = 'UIDVALIDITY';
}

View file

@ -22,5 +22,6 @@ class FolderStatus
const RECENT = 'RECENT';
const UNSEEN = 'UNSEEN';
const UIDNEXT = 'UIDNEXT';
const HIGHESTMODSEQ = 'HIGHESTMODSEQ';
const UIDVALIDITY = 'UIDVALIDITY';
}

View file

@ -62,6 +62,11 @@ class FolderInformation
*/
public $Uidnext;
/**
* @var string
*/
public $HighestModSeq;
/**
* @access private
*
@ -79,6 +84,7 @@ class FolderInformation
$this->Unread = null;
$this->Uidnext = null;
$this->HighestModSeq = null;
}
/**

View file

@ -326,7 +326,24 @@ class ImapClient extends \MailSo\Net\NetClient
try
{
$this->SendRequestWithCheck('AUTHENTICATE', array('XOAUTH2', \trim($sXOAuth2Token)));
$this->SendRequest('AUTHENTICATE', array('XOAUTH2', \trim($sXOAuth2Token)));
$aR = $this->parseResponseWithValidation();
if (\is_array($aR) && 0 < \count($aR) && isset($aR[\count($aR) - 1]))
{
$oR = $aR[\count($aR) - 1];
if (\MailSo\Imap\Enumerations\ResponseType::CONTINUATION === $oR->ResponseType)
{
if (!empty($oR->ResponseList[1]) && preg_match('/^[a-zA-Z0-9=+\/]+$/', $oR->ResponseList[1]))
{
$this->Logger()->Write(\base64_decode($oR->ResponseList[1]),
\MailSo\Log\Enumerations\Type::WARNING);
}
$this->sendRaw('');
$this->parseResponseWithValidation();
}
}
}
catch (\MailSo\Imap\Exceptions\NegativeResponseException $oException)
{
@ -681,6 +698,7 @@ class ImapClient extends \MailSo\Net\NetClient
{
$sName = null;
$aStatus = array();
foreach ($oImapResponse->ResponseList[3] as $sArrayItem)
{
if (null === $sName)
@ -734,17 +752,21 @@ class ImapClient extends \MailSo\Net\NetClient
$this->EscapeString($sListPattern)
);
if ($bUseListStatus && $this->IsSupported('LIST-STATUS'))
if ($bUseListStatus && !$bIsSubscribeList && $this->IsSupported('LIST-STATUS'))
{
$aParameters[] = 'RETURN';
$aParameters[] = array(
'STATUS',
array(
\MailSo\Imap\Enumerations\FolderStatus::MESSAGES,
\MailSo\Imap\Enumerations\FolderStatus::UNSEEN,
\MailSo\Imap\Enumerations\FolderStatus::UIDNEXT
)
$aL = array(
\MailSo\Imap\Enumerations\FolderStatus::MESSAGES,
\MailSo\Imap\Enumerations\FolderStatus::UNSEEN,
\MailSo\Imap\Enumerations\FolderStatus::UIDNEXT
);
// if ($this->IsSupported('CONDSTORE'))
// {
// $aL[] = \MailSo\Imap\Enumerations\FolderStatus::HIGHESTMODSEQ;
// }
$aParameters[] = 'RETURN';
$aParameters[] = array('STATUS', $aL);
}
else
{
@ -846,6 +868,12 @@ class ImapClient extends \MailSo\Net\NetClient
{
$oResult->Uidnext = $oImapResponse->OptionalResponse[1];
}
else if ('HIGHESTMODSEQ' === $oImapResponse->OptionalResponse[0] &&
isset($oImapResponse->OptionalResponse[1]) &&
\is_numeric($oImapResponse->OptionalResponse[1]))
{
$oResult->HighestModSeq = \trim($oImapResponse->OptionalResponse[1]);
}
}
if (\count($oImapResponse->ResponseList) > 2 &&

View file

@ -684,16 +684,25 @@ class MailClient
* @param int $iCount
* @param int $iUnseenCount
* @param string $sUidNext
* @param string $sHighestModSeq
*
* @return void
*/
protected function initFolderValues($sFolderName, &$iCount, &$iUnseenCount, &$sUidNext)
protected function initFolderValues($sFolderName, &$iCount, &$iUnseenCount,
&$sUidNext, &$sHighestModSeq = '')
{
$aFolderStatus = $this->oImapClient->FolderStatus($sFolderName, array(
$aTypes = array(
\MailSo\Imap\Enumerations\FolderResponseStatus::MESSAGES,
\MailSo\Imap\Enumerations\FolderResponseStatus::UNSEEN,
\MailSo\Imap\Enumerations\FolderResponseStatus::UIDNEXT
));
);
if ($this->oImapClient->IsSupported('CONDSTORE'))
{
$aTypes[] = \MailSo\Imap\Enumerations\FolderResponseStatus::HIGHESTMODSEQ;
}
$aFolderStatus = $this->oImapClient->FolderStatus($sFolderName, $aTypes);
$iCount = isset($aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::MESSAGES])
? (int) $aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::MESSAGES] : 0;
@ -704,6 +713,9 @@ class MailClient
$sUidNext = isset($aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::UIDNEXT])
? (string) $aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::UIDNEXT] : '0';
$sHighestModSeq = isset($aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::HIGHESTMODSEQ])
? (string) $aFolderStatus[\MailSo\Imap\Enumerations\FolderResponseStatus::HIGHESTMODSEQ] : '';
if ($this->IsGmail())
{
$oFolder = $this->oImapClient->FolderCurrentInformation();
@ -735,14 +747,15 @@ class MailClient
* @param int $iCount
* @param int $iUnseenCount
* @param string $sUidNext
* @param string $sHighestModSeq = ''
*
* @return string
*/
public function GenerateFolderHash($sFolder, $iCount, $iUnseenCount, $sUidNext)
public function GenerateFolderHash($sFolder, $iCount, $iUnseenCount, $sUidNext, $sHighestModSeq = '')
{
$iUnseenCount = 0; // unneccessery
return \md5('FolderHash/'.$sFolder.'-'.$iCount.'-'.$iUnseenCount.'-'.$sUidNext.'-'.
$this->GenerateImapClientHash()
$sHighestModSeq.'-'.$this->GenerateImapClientHash()
);
}
@ -866,16 +879,18 @@ class MailClient
$iCount = 0;
$iUnseenCount = 0;
$sUidNext = '0';
$sHighestModSeq = '';
$this->initFolderValues($sFolderName, $iCount, $iUnseenCount, $sUidNext);
$this->initFolderValues($sFolderName, $iCount, $iUnseenCount, $sUidNext, $sHighestModSeq);
$aResult = array(
'Folder' => $sFolderName,
'Hash' => $this->GenerateFolderHash($sFolderName, $iCount, $iUnseenCount, $sUidNext),
'Hash' => $this->GenerateFolderHash($sFolderName, $iCount, $iUnseenCount, $sUidNext, $sHighestModSeq),
'MessageCount' => $iCount,
'MessageUnseenCount' => $iUnseenCount,
'UidNext' => $sUidNext,
'Flags' => $aFlags,
'HighestModSeq' => $sHighestModSeq,
'NewMessages' => 'INBOX' === $sFolderName ?
$this->getFolderNextMessageInformation($sFolderName, $sPrevUidNext, $sUidNext) : array()
);
@ -897,10 +912,11 @@ class MailClient
$iCount = 0;
$iUnseenCount = 0;
$sUidNext = '0';
$sHighestModSeq = '';
$this->initFolderValues($sFolderName, $iCount, $iUnseenCount, $sUidNext);
$this->initFolderValues($sFolderName, $iCount, $iUnseenCount, $sUidNext, $sHighestModSeq);
return $this->GenerateFolderHash($sFolderName, $iCount, $iUnseenCount, $sUidNext);
return $this->GenerateFolderHash($sFolderName, $iCount, $iUnseenCount, $sUidNext, $sHighestModSeq);
}
/**
@ -1124,12 +1140,13 @@ class MailClient
/**
* @param string $sSearch
* @param string $sFilter
* @param int $iTimeZoneOffset = 0
* @param bool $bUseCache = true
*
* @return string
*/
private function getImapSearchCriterias($sSearch, $iTimeZoneOffset = 0, &$bUseCache = true)
private function getImapSearchCriterias($sSearch, $sFilter, $iTimeZoneOffset = 0, &$bUseCache = true)
{
$bUseCache = true;
$iTimeFilter = 0;
@ -1370,14 +1387,25 @@ class MailClient
$sCriteriasResult .= ' SINCE '.\gmdate('j-M-Y', $iTimeFilter);
}
$sCriteriasResult = \trim($sCriteriasResult);
$sCriteriasResult .= ' NOT DELETED';
$sFilter = \trim($sFilter);
if ('' !== $sFilter)
{
$sCriteriasResult .= ' '.$sFilter;
}
$sCriteriasResult = \trim($sCriteriasResult);
if ('' !== \MailSo\Config::$MessageListPermanentFilter)
{
$sCriteriasResult .= ' '.\MailSo\Config::$MessageListPermanentFilter;
}
$sCriteriasResult = \trim($sCriteriasResult);
if ('' === $sCriteriasResult)
{
$sCriteriasResult = 'NOT DELETED'; // ALL
}
else
{
$sCriteriasResult .= ' NOT DELETED';
$sCriteriasResult = 'ALL';
}
return $sCriteriasResult;
@ -1704,190 +1732,6 @@ class MailClient
$this->oImapClient->IsSupported('THREAD=ORDEREDSUBJECT');
}
/**
* @param string $sSearch
* @param string $sFolderName
* @param string|bool $sFolderHash
* @param bool $bUseSortIfSupported = true
* @param bool $bUseESearchOrESortRequest = false
* @param \MailSo\Cache\CacheClient|null $oCacher = null
*
* @return Array|bool
*/
private function getSearchUidsResult($sSearch, $sFolderName, $sFolderHash,
$bUseSortIfSupported = true, $bUseESearchOrESortRequest = false, $oCacher = null)
{
$aResultUids = false;
$bUidsFromCacher = false;
$bUseCacheAfterSearch = true;
$sSerializedHash = '';
$bESortSupported = $bUseSortIfSupported && $bUseESearchOrESortRequest ? $this->oImapClient->IsSupported('ESORT') : false;
$bESearchSupported = $bUseESearchOrESortRequest ? $this->oImapClient->IsSupported('ESEARCH') : false;
$bUseSortIfSupported = $bUseSortIfSupported ? $this->oImapClient->IsSupported('SORT') : false;
$sSearchCriterias = $this->getImapSearchCriterias($sSearch, 0, $bUseCacheAfterSearch);
if ($bUseCacheAfterSearch && $oCacher && $oCacher->IsInited())
{
$sSerializedHash = 'SearchSortUids/'.
($bUseSortIfSupported ? 'S': 'N').'/'.
$this->GenerateImapClientHash().'/'.
$sFolderName.'/'.$sSearchCriterias;
$sSerializedLog = '"'.$sFolderName.'" / '.$sSearchCriterias.'';
$sSerialized = $oCacher->Get($sSerializedHash);
if (!empty($sSerialized))
{
$aSerialized = @\json_decode($sSerialized, true);
if (\is_array($aSerialized) && isset($aSerialized['FolderHash'], $aSerialized['Uids']) &&
$sFolderHash === $aSerialized['FolderHash'] &&
\is_array($aSerialized['Uids'])
)
{
if ($this->oLogger)
{
$this->oLogger->Write('Get Serialized UIDS from cache ('.$sSerializedLog.') [count:'.\count($aSerialized['Uids']).']');
}
$aResultUids = $aSerialized['Uids'];
$bUidsFromCacher = true;
}
}
}
if (!\is_array($aResultUids))
{
if ($bUseSortIfSupported)
{
if ($bESortSupported)
{
$aESorthData = $this->oImapClient->MessageSimpleESort(array('ARRIVAL'), $sSearchCriterias, array('ALL'), true, '');
if (isset($aESorthData['ALL']))
{
$aResultUids = \MailSo\Base\Utils::ParseFetchSequence($aESorthData['ALL']);
$aResultUids = \array_reverse($aResultUids);
}
unset($aESorthData);
}
else
{
$aResultUids = $this->oImapClient->MessageSimpleSort(array('REVERSE ARRIVAL'), $sSearchCriterias, true);
}
}
else
{
if (!\MailSo\Base\Utils::IsAscii($sSearch))
{
try
{
if ($bESearchSupported)
{
$aESearchData = $this->oImapClient->MessageSimpleESearch($sSearchCriterias, array('ALL'), true, '', 'UTF-8');
if (isset($aESearchData['ALL']))
{
$aResultUids = \MailSo\Base\Utils::ParseFetchSequence($aESearchData['ALL']);
$aResultUids = \array_reverse($aResultUids);
}
unset($aESearchData);
}
else
{
$aResultUids = $this->oImapClient->MessageSimpleSearch($sSearchCriterias, true, 'UTF-8');
}
}
catch (\MailSo\Imap\Exceptions\NegativeResponseException $oException)
{
$oException = null;
$aResultUids = false;
}
}
if (false === $aResultUids)
{
if ($bESearchSupported)
{
$aESearchData = $this->oImapClient->MessageSimpleESearch($sSearchCriterias, array('ALL'), true);
if (isset($aESearchData['ALL']))
{
$aResultUids = \MailSo\Base\Utils::ParseFetchSequence($aESearchData['ALL']);
$aResultUids = \array_reverse($aResultUids);
}
unset($aESearchData);
}
else
{
$aResultUids = $this->oImapClient->MessageSimpleSearch($sSearchCriterias, true);
}
}
}
if (!$bUidsFromCacher && $bUseCacheAfterSearch && \is_array($aResultUids) && $oCacher && $oCacher->IsInited() && 0 < \strlen($sSerializedHash))
{
$oCacher->Set($sSerializedHash, @\json_encode(array(
'FolderHash' => $sFolderHash,
'Uids' => $aResultUids
)));
if ($this->oLogger)
{
$this->oLogger->Write('Save Serialized UIDS to cache ('.$sSerializedLog.') [count:'.\count($aResultUids).']');
}
}
}
return $aResultUids;
}
/**
* @param string $sFolderName
* @param string $sFolderHash
* @param string $sUid
* @param \MailSo\Cache\CacheClient|null $oCacher = null
*
* @return array
*/
public function MessageThreadUidsFromCache($sFolderName, $sFolderHash, $sUid, $oCacher = null)
{
$aResult = array();
if (0 < \strlen($sFolderName) && 0 < \strlen($sFolderHash) && 0 < \strlen($sUid) && $oCacher && $oCacher->IsInited())
{
$mThreads = $this->MessageListThreadsMap($sFolderName, $sFolderHash, array(), $oCacher, true);
if (\is_array($mThreads))
{
$iUid = (int) $sUid;
foreach ($mThreads as $iSubUid => $aSubUids)
{
if ($iUid === $iSubUid)
{
$aResult = $aSubUids;
if (!\is_array($aResult))
{
$aResult = array();
}
\array_unshift($aResult, $iSubUid);
break;
}
else if (\is_array($aSubUids))
{
if (\in_array($iUid, $aSubUids))
{
$aResult = $aSubUids;
\array_unshift($aResult, $iSubUid);
break;
}
}
}
}
}
return \array_map('trim', $aResult);
}
/**
* @param string $sFolderName
* @param array $aUids
@ -1918,6 +1762,7 @@ class MailClient
/**
* @param \MailSo\Cache\CacheClient|null $oCacher
* @param string $sSearch
* @param string $sFilter
* @param string $sFolderName
* @param string $sFolderHash
* @param bool $bUseSortIfSupported = false
@ -1928,7 +1773,7 @@ class MailClient
* @throws \MailSo\Net\Exceptions\Exception
* @throws \MailSo\Imap\Exceptions\Exception
*/
public function GetUids($oCacher, $sSearch, $sFolderName, $sFolderHash, $bUseSortIfSupported = false)
public function GetUids($oCacher, $sSearch, $sFilter, $sFolderName, $sFolderHash, $bUseSortIfSupported = false)
{
$aResultUids = false;
$bUidsFromCacher = false;
@ -1944,7 +1789,7 @@ class MailClient
$bUseSortIfSupported = false;
}
$sSearchCriterias = $this->getImapSearchCriterias($sSearch, 0, $bUseCacheAfterSearch);
$sSearchCriterias = $this->getImapSearchCriterias($sSearch, $sFilter, 0, $bUseCacheAfterSearch);
if ($bUseCacheAfterSearch && $oCacher && $oCacher->IsInited())
{
$sSerializedHash = 'GetUids/'.
@ -2009,6 +1854,7 @@ class MailClient
* @param bool $bUseThreadSortIfSupported = false
* @param bool $bUseESearchOrESortRequest = false
* @param string $sThreadUid = ''
* @param string $sFilter = ''
*
* @return \MailSo\Mail\MessageCollection
*
@ -2017,8 +1863,9 @@ class MailClient
* @throws \MailSo\Imap\Exceptions\Exception
*/
public function MessageList($sFolderName, $iOffset = 0, $iLimit = 10, $sSearch = '', $sPrevUidNext = '', $oCacher = null,
$bUseSortIfSupported = false, $bUseThreadSortIfSupported = false, $sThreadUid = '')
$bUseSortIfSupported = false, $bUseThreadSortIfSupported = false, $sThreadUid = '', $sFilter = '')
{
$sFilter = \trim($sFilter);
$sSearch = \trim($sSearch);
if (!\MailSo\Base\Validator::RangeInt($iOffset, 0) ||
!\MailSo\Base\Validator::RangeInt($iLimit, 0, 999))
@ -2026,6 +1873,8 @@ class MailClient
throw new \MailSo\Base\Exceptions\InvalidArgumentException();
}
$bUseFilter = '' !== $sFilter;
$this->oImapClient->FolderSelect($sFolderName);
$oMessageCollection = MessageCollection::NewInstance();
@ -2044,6 +1893,7 @@ class MailClient
$iMessageRealCount = 0;
$iMessageUnseenCount = 0;
$sUidNext = '0';
$sHighestModSeq = '';
$bUseSortIfSupported = $bUseSortIfSupported ? $this->oImapClient->IsSupported('SORT') : false;
@ -2060,9 +1910,16 @@ class MailClient
$oCacher = null;
}
$this->initFolderValues($sFolderName, $iMessageRealCount, $iMessageUnseenCount, $sUidNext);
$this->initFolderValues($sFolderName, $iMessageRealCount, $iMessageUnseenCount, $sUidNext, $sHighestModSeq);
if ($bUseFilter)
{
$iMessageUnseenCount = 0;
}
$oMessageCollection->FolderHash = $this->GenerateFolderHash(
$sFolderName, $iMessageRealCount, $iMessageUnseenCount, $sUidNext, $sHighestModSeq);
$oMessageCollection->FolderHash = $this->GenerateFolderHash($sFolderName, $iMessageRealCount, $iMessageUnseenCount, $sUidNext);
$oMessageCollection->UidNext = $sUidNext;
if (empty($sThreadUid) && 0 < \strlen($sPrevUidNext) && 'INBOX' === $sFolderName)
@ -2083,7 +1940,7 @@ class MailClient
if (0 < $iMessageRealCount)
{
$mAllSortedUids = $this->GetUids($oCacher, '',
$mAllSortedUids = $this->GetUids($oCacher, '', $sFilter,
$oMessageCollection->FolderName, $oMessageCollection->FolderHash, $bUseSortIfSupported);
$mAllThreads = $bUseThreadSortIfSupported ? $this->MessageListThreadsMap(
@ -2132,7 +1989,7 @@ class MailClient
if (0 < \strlen($sSearch) && \is_array($aUids))
{
$aSearchedUids = $this->GetUids($oCacher, $sSearch, $oMessageCollection->FolderName, $oMessageCollection->FolderHash);
$aSearchedUids = $this->GetUids($oCacher, $sSearch, $sFilter, $oMessageCollection->FolderName, $oMessageCollection->FolderHash);
if (\is_array($aSearchedUids) && 0 < \count($aSearchedUids))
{
$aFlippedSearchedUids = \array_flip($aSearchedUids);
@ -2678,7 +2535,7 @@ class MailClient
$this->oImapClient->FolderSelect($sFolderFullNameRaw);
$oFolderInformation = $this->oImapClient->FolderCurrentInformation();
if ($oFolderInformation && 0 < $oFolderInformation->Exists) // STATUS?
if ($oFolderInformation && $oFolderInformation->Exists && 0 < $oFolderInformation->Exists) // STATUS?
{
$this->oImapClient->MessageStoreFlag('1:*', false,
array(\MailSo\Imap\Enumerations\MessageFlag::DELETED),