Example #1
0
 /**
  * @param string $sFolderName
  * @param int $iOffset = 0
  * @param int $iLimit = 10
  * @param string $sSearch = ''
  * @param string $sPrevUidNext = ''
  * @param mixed $oCacher = null
  * @param string $sCachePrefix = ''
  * @param bool $bUseSortIfSupported = false
  * @param bool $bUseThreadSortIfSupported = false
  * @param array $aExpandedThreadsUids = array()
  *
  * @return \MailSo\Mail\MessageCollection
  *
  * @throws \MailSo\Base\Exceptions\InvalidArgumentException
  * @throws \MailSo\Net\Exceptions\Exception
  * @throws \MailSo\Imap\Exceptions\Exception
  */
 public function MessageList($sFolderName, $iOffset = 0, $iLimit = 10, $sSearch = '', $sPrevUidNext = '', $oCacher = null, $bUseSortIfSupported = false, $bUseThreadSortIfSupported = false, $aExpandedThreadsUids = array())
 {
     $sSearch = \trim($sSearch);
     if (!\MailSo\Base\Validator::RangeInt($iOffset, 0) || !\MailSo\Base\Validator::RangeInt($iLimit, 0, 999) || !is_string($sSearch)) {
         throw new \MailSo\Base\Exceptions\InvalidArgumentException();
     }
     $this->oImapClient->FolderExamine($sFolderName);
     $oMessageCollection = MessageCollection::NewInstance();
     $oMessageCollection->FolderName = $sFolderName;
     $oMessageCollection->Offset = $iOffset;
     $oMessageCollection->Limit = $iLimit;
     $oMessageCollection->Search = $sSearch;
     $aLastCollapsedThreadUids = array();
     $aThreads = array();
     $iMessageCount = 0;
     $iMessageRealCount = 0;
     $iMessageUnseenCount = 0;
     $sUidNext = '0';
     $sSerializedHash = '';
     $bUseSortIfSupported = $bUseSortIfSupported ? $this->oImapClient->IsSupported('SORT') : false;
     $bUseThreadSortIfSupported = $bUseThreadSortIfSupported ? $this->oImapClient->IsSupported('THREAD=REFS') || $this->oImapClient->IsSupported('THREAD=REFERENCES') || $this->oImapClient->IsSupported('THREAD=ORDEREDSUBJECT') : false;
     if (!$oCacher || !$oCacher instanceof \MailSo\Cache\CacheClient) {
         $oCacher = null;
     }
     $this->initFolderValues($sFolderName, $iMessageRealCount, $iMessageUnseenCount, $sUidNext);
     $iMessageCount = $iMessageRealCount;
     $oMessageCollection->FolderHash = self::GenerateHash($sFolderName, $iMessageRealCount, $iMessageUnseenCount, $sUidNext);
     $oMessageCollection->UidNext = $sUidNext;
     $oMessageCollection->NewMessages = $this->getFolderNextMessageInformation($sFolderName, $sPrevUidNext, $sUidNext);
     $bCacher = false;
     $bSearch = false;
     if (0 < $iMessageRealCount) {
         $bIndexAsUid = false;
         $aIndexOrUids = array();
         $bSearch = 0 < \strlen($sSearch);
         if ($bSearch || $bUseSortIfSupported && !$bUseThreadSortIfSupported) {
             $bIndexAsUid = true;
             $aIndexOrUids = null;
             $sSearchCriterias = $this->getSearchBuilder($sSearch)->Complete();
             if ($oCacher && $oCacher->IsInited()) {
                 $sSerializedHash = ($bUseSortIfSupported ? 'S' : 'N') . '/' . ($bUseThreadSortIfSupported ? 'T' : 'N') . '/' . $this->oImapClient->GetLogginedUser() . '@' . $this->oImapClient->GetConnectedHost() . ':' . $this->oImapClient->GetConnectedPort() . '/' . $oMessageCollection->FolderName . '/' . $oMessageCollection->FolderHash . '/' . $sSearchCriterias;
                 $sSerializedUids = $oCacher->Get($sSerializedHash);
                 if (!empty($sSerializedUids)) {
                     $aSerializedUids = @\unserialize($sSerializedUids);
                     if (\is_array($aSerializedUids)) {
                         $aIndexOrUids = $aSerializedUids;
                         $bCacher = true;
                     }
                 }
             }
             if (!\is_array($aIndexOrUids)) {
                 if ($bUseSortIfSupported && !$bUseThreadSortIfSupported) {
                     $aIndexOrUids = $this->oImapClient->MessageSimpleSort(array('ARRIVAL'), $sSearchCriterias, $bIndexAsUid);
                 } else {
                     if (!\MailSo\Base\Utils::IsAscii($sSearch)) {
                         try {
                             $aIndexOrUids = $this->oImapClient->MessageSimpleSearch($sSearchCriterias, $bIndexAsUid, 'UTF-8');
                         } catch (\MailSo\Imap\Exceptions\NegativeResponseException $oException) {
                             $oException = null;
                             $aIndexOrUids = null;
                         }
                     }
                     if (null === $aIndexOrUids) {
                         $aIndexOrUids = $this->oImapClient->MessageSimpleSearch($sSearchCriterias, $bIndexAsUid);
                     }
                 }
             }
         } else {
             if ($bUseThreadSortIfSupported && 1 < $iMessageCount) {
                 $bIndexAsUid = true;
                 $aThreads = $this->MessageListThreadsMap($oMessageCollection->FolderName, $oMessageCollection->FolderHash, $oCacher);
                 $aIndexOrUids = $this->compileLineThreadUids($aThreads, $aLastCollapsedThreadUids, $aExpandedThreadsUids, 0);
                 $iMessageCount = count($aIndexOrUids);
             } else {
                 $bIndexAsUid = false;
                 $aIndexOrUids = array(1);
                 if (1 < $iMessageCount) {
                     $aIndexOrUids = \array_reverse(\range(1, $iMessageCount));
                 }
             }
         }
         if ($bIndexAsUid && !$bCacher && \is_array($aIndexOrUids) && $oCacher && $oCacher->IsInited() && 0 < \strlen($sSerializedHash)) {
             $oCacher->Set($sSerializedHash, \serialize($aIndexOrUids));
         }
         if (\is_array($aIndexOrUids)) {
             $oMessageCollection->MessageCount = $iMessageRealCount;
             $oMessageCollection->MessageUnseenCount = $iMessageUnseenCount;
             $oMessageCollection->MessageResultCount = 0 === \strlen($sSearch) ? $iMessageCount : \count($aIndexOrUids);
             if (0 < count($aIndexOrUids)) {
                 $iOffset = 0 > $iOffset ? 0 : $iOffset;
                 $aRequestIndexOrUids = \array_slice($aIndexOrUids, $iOffset, $iLimit);
                 $this->MessageListByRequestIndexOrUids($oMessageCollection, $aRequestIndexOrUids, $bIndexAsUid);
             }
         }
     }
     $aLastCollapsedThreadUidsForPage = array();
     if (!$bSearch && $bUseThreadSortIfSupported && 0 < \count($aThreads)) {
         $oMessageCollection->ForeachList(function ($oMessage) use($aThreads, $aLastCollapsedThreadUids, &$aLastCollapsedThreadUidsForPage) {
             $iUid = $oMessage->Uid();
             if (in_array($iUid, $aLastCollapsedThreadUids)) {
                 $aLastCollapsedThreadUidsForPage[] = $iUid;
             }
             if (isset($aThreads[$iUid]) && \is_array($aThreads[$iUid]) && 0 < \count($aThreads[$iUid])) {
                 $oMessage->SetThreads($aThreads[$iUid]);
                 $oMessage->SetThreadsLen(\count($aThreads[$iUid]));
             } else {
                 if (!isset($aThreads[$iUid])) {
                     foreach ($aThreads as $iKeyUid => $mSubItem) {
                         if (is_array($mSubItem) && in_array($iUid, $mSubItem)) {
                             $oMessage->SetParentThread($iKeyUid);
                             $oMessage->SetThreadsLen(\count($mSubItem));
                         }
                     }
                 }
             }
         });
         $oMessageCollection->LastCollapsedThreadUids = $aLastCollapsedThreadUidsForPage;
     }
     return $oMessageCollection;
 }
Example #2
0
 /**
  * @param int $iPort
  *
  * @return bool
  */
 public static function PortInt($iPort)
 {
     return \MailSo\Base\Validator::RangeInt($iPort, 0, 65535);
 }
 /**
  * @param string $sFolderName
  * @param int $iOffset = 0
  * @param int $iLimit = 10
  * @param string $sSearch = ''
  * @param string $sPrevUidNext = ''
  * @param \MailSo\Cache\CacheClient|null $oCacher = null
  * @param bool $bUseSortIfSupported = false
  * @param bool $bUseThreadSortIfSupported = false
  * @param bool $bUseESearchOrESortRequest = false
  * @param string $sThreadUid = ''
  * @param string $sFilter = ''
  *
  * @return \MailSo\Mail\MessageCollection
  *
  * @throws \MailSo\Base\Exceptions\InvalidArgumentException
  * @throws \MailSo\Net\Exceptions\Exception
  * @throws \MailSo\Imap\Exceptions\Exception
  */
 public function MessageList($sFolderName, $iOffset = 0, $iLimit = 10, $sSearch = '', $sPrevUidNext = '', $oCacher = null, $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)) {
         throw new \MailSo\Base\Exceptions\InvalidArgumentException();
     }
     $bUseFilter = '' !== $sFilter;
     $this->oImapClient->FolderSelect($sFolderName);
     $oMessageCollection = MessageCollection::NewInstance();
     $oMessageCollection->FolderName = $sFolderName;
     $oMessageCollection->Offset = $iOffset;
     $oMessageCollection->Limit = $iLimit;
     $oMessageCollection->Search = $sSearch;
     $oMessageCollection->ThreadUid = $sThreadUid;
     $oMessageCollection->Filtered = '' !== \MailSo\Config::$MessageListPermanentFilter;
     $aUids = array();
     $mAllSortedUids = null;
     $mAllThreads = null;
     $iThreadUid = empty($sThreadUid) ? 0 : (int) $sThreadUid;
     $iMessageRealCount = 0;
     $iMessageUnseenCount = 0;
     $sUidNext = '0';
     $sHighestModSeq = '';
     $bUseSortIfSupported = $bUseSortIfSupported ? $this->oImapClient->IsSupported('SORT') : false;
     $bUseThreadSortIfSupported = $bUseThreadSortIfSupported ? $this->oImapClient->IsSupported('THREAD=REFS') || $this->oImapClient->IsSupported('THREAD=REFERENCES') || $this->oImapClient->IsSupported('THREAD=ORDEREDSUBJECT') : false;
     if (!empty($sThreadUid) && !$bUseThreadSortIfSupported) {
         throw new \MailSo\Base\Exceptions\InvalidArgumentException();
     }
     if (!$oCacher || !$oCacher instanceof \MailSo\Cache\CacheClient) {
         $oCacher = null;
     }
     $this->initFolderValues($sFolderName, $iMessageRealCount, $iMessageUnseenCount, $sUidNext, $sHighestModSeq);
     if ($bUseFilter) {
         $iMessageUnseenCount = 0;
     }
     $oMessageCollection->FolderHash = $this->GenerateFolderHash($sFolderName, $iMessageRealCount, $iMessageUnseenCount, $sUidNext, $sHighestModSeq);
     $oMessageCollection->UidNext = $sUidNext;
     if (empty($sThreadUid) && 0 < \strlen($sPrevUidNext) && 'INBOX' === $sFolderName) {
         $oMessageCollection->NewMessages = $this->getFolderNextMessageInformation($sFolderName, $sPrevUidNext, $sUidNext);
     }
     $bSearch = false;
     $bMessageListOptimization = 0 < \MailSo\Config::$MessageListCountLimitTrigger && \MailSo\Config::$MessageListCountLimitTrigger < $iMessageRealCount;
     if ($bMessageListOptimization) {
         $bUseSortIfSupported = false;
         $bUseThreadSortIfSupported = false;
     }
     if (0 < $iMessageRealCount && !$bMessageListOptimization) {
         $mAllSortedUids = $this->GetUids($oCacher, '', $sFilter, $oMessageCollection->FolderName, $oMessageCollection->FolderHash, $bUseSortIfSupported);
         $mAllThreads = $bUseThreadSortIfSupported ? $this->MessageListThreadsMap($oMessageCollection->FolderName, $oMessageCollection->FolderHash, $mAllSortedUids, $oCacher) : null;
         if ($bUseThreadSortIfSupported && 0 < $iThreadUid && \is_array($mAllThreads)) {
             $aUids = array();
             $iResultRootUid = 0;
             if (isset($mAllThreads[$iThreadUid])) {
                 $iResultRootUid = $iThreadUid;
                 if (\is_array($mAllThreads[$iThreadUid])) {
                     $aUids = $mAllThreads[$iThreadUid];
                 }
             } else {
                 foreach ($mAllThreads as $iRootUid => $mSubUids) {
                     if (\is_array($mSubUids) && \in_array($iThreadUid, $mSubUids)) {
                         $iResultRootUid = $iRootUid;
                         $aUids = $mSubUids;
                         continue;
                     }
                 }
             }
             if (0 < $iResultRootUid && \in_array($iResultRootUid, $mAllSortedUids)) {
                 \array_unshift($aUids, $iResultRootUid);
             }
         } else {
             if ($bUseThreadSortIfSupported && \is_array($mAllThreads)) {
                 $aUids = \array_keys($mAllThreads);
             } else {
                 $bUseThreadSortIfSupported = false;
                 $aUids = $mAllSortedUids;
             }
         }
         if (0 < \strlen($sSearch) && \is_array($aUids)) {
             $aSearchedUids = $this->GetUids($oCacher, $sSearch, $sFilter, $oMessageCollection->FolderName, $oMessageCollection->FolderHash);
             if (\is_array($aSearchedUids) && 0 < \count($aSearchedUids)) {
                 $aFlippedSearchedUids = \array_flip($aSearchedUids);
                 $bSearch = true;
                 $aNewUids = array();
                 foreach ($aUids as $iUid) {
                     if (isset($aFlippedSearchedUids[$iUid])) {
                         $aNewUids[] = $iUid;
                     } else {
                         if ($bUseThreadSortIfSupported && 0 === $iThreadUid && isset($mAllThreads[$iUid]) && \is_array($mAllThreads[$iUid])) {
                             foreach ($mAllThreads[$iUid] as $iSubUid) {
                                 if (isset($aFlippedSearchedUids[$iSubUid])) {
                                     $aNewUids[] = $iUid;
                                     continue;
                                 }
                             }
                         }
                     }
                 }
                 $aUids = \array_unique($aNewUids);
                 unset($aNewUids);
             } else {
                 $aUids = array();
             }
         }
         if (\is_array($aUids)) {
             $oMessageCollection->MessageCount = $iMessageRealCount;
             $oMessageCollection->MessageUnseenCount = $iMessageUnseenCount;
             $oMessageCollection->MessageResultCount = \count($aUids);
             if (0 < \count($aUids)) {
                 $aRequestUids = \array_slice($aUids, $iOffset, $iLimit);
                 $this->MessageListByRequestIndexOrUids($oMessageCollection, $aRequestUids, true);
             }
         }
     } else {
         if (0 < $iMessageRealCount) {
             if ($this->oLogger) {
                 $this->oLogger->Write('List optimization (count: ' . $iMessageRealCount . ', limit:' . \MailSo\Config::$MessageListCountLimitTrigger . ')');
             }
             $oMessageCollection->MessageCount = $iMessageRealCount;
             $oMessageCollection->MessageUnseenCount = $iMessageUnseenCount;
             if (0 < \strlen($sSearch) || $bUseFilter) {
                 $aUids = $this->GetUids($oCacher, $sSearch, $sFilter, $oMessageCollection->FolderName, $oMessageCollection->FolderHash);
                 if (0 < \count($aUids)) {
                     $oMessageCollection->MessageResultCount = \count($aUids);
                     $aRequestUids = \array_slice($aUids, $iOffset, $iLimit);
                     $this->MessageListByRequestIndexOrUids($oMessageCollection, $aRequestUids, true);
                 } else {
                     $oMessageCollection->MessageResultCount = 0;
                 }
             } else {
                 $oMessageCollection->MessageResultCount = $iMessageRealCount;
                 if (1 < $iMessageRealCount) {
                     $aRequestIndexes = \array_slice(array_reverse(range(1, $iMessageRealCount)), $iOffset, $iLimit);
                 } else {
                     $aRequestIndexes = \array_slice(array(1), $iOffset, $iLimit);
                 }
                 $this->MessageListByRequestIndexOrUids($oMessageCollection, $aRequestIndexes, false);
             }
         }
     }
     if ($bUseThreadSortIfSupported && 0 === $iThreadUid && \is_array($mAllThreads) && 0 < \count($mAllThreads)) {
         $oMessageCollection->ForeachList(function ($oMessage) use($mAllThreads) {
             $iUid = $oMessage->Uid();
             if (isset($mAllThreads[$iUid]) && \is_array($mAllThreads[$iUid]) && 0 < \count($mAllThreads[$iUid])) {
                 $aSubThreads = $mAllThreads[$iUid];
                 \array_unshift($aSubThreads, $iUid);
                 $oMessage->SetThreads(\array_map('trim', $aSubThreads));
                 unset($aSubThreads);
             }
         });
     }
     return $oMessageCollection;
 }
Example #4
0
 /**
  * @param string $sFolderName
  * @param int $iOffset = 0
  * @param int $iLimit = 10
  * @param string $sSearch = ''
  * @param string $sPrevUidNext = ''
  * @param \MailSo\Cache\CacheClient|null $oCacher = null
  * @param bool $bUseSortIfSupported = false
  * @param bool $bUseThreadSortIfSupported = false
  * @param array $aExpandedThreadsUids = array()
  * @param bool $bUseESearchOrESortRequest = false
  *
  * @return \MailSo\Mail\MessageCollection
  *
  * @throws \MailSo\Base\Exceptions\InvalidArgumentException
  * @throws \MailSo\Net\Exceptions\Exception
  * @throws \MailSo\Imap\Exceptions\Exception
  */
 public function MessageList($sFolderName, $iOffset = 0, $iLimit = 10, $sSearch = '', $sPrevUidNext = '', $oCacher = null, $bUseSortIfSupported = false, $bUseThreadSortIfSupported = false, $aExpandedThreadsUids = array(), $bUseESearchOrESortRequest = false)
 {
     $sSearch = \trim($sSearch);
     if (!\MailSo\Base\Validator::RangeInt($iOffset, 0) || !\MailSo\Base\Validator::RangeInt($iLimit, 0, 999)) {
         throw new \MailSo\Base\Exceptions\InvalidArgumentException();
     }
     $this->oImapClient->FolderExamine($sFolderName);
     $oMessageCollection = MessageCollection::NewInstance();
     $oMessageCollection->FolderName = $sFolderName;
     $oMessageCollection->Offset = $iOffset;
     $oMessageCollection->Limit = $iLimit;
     $oMessageCollection->Search = $sSearch;
     $aLastCollapsedThreadUids = array();
     $aThreads = array();
     $iMessageCount = 0;
     $iMessageRealCount = 0;
     $iMessageUnseenCount = 0;
     $sUidNext = '0';
     $bUseSortIfSupported = $bUseSortIfSupported ? $this->oImapClient->IsSupported('SORT') : false;
     $bUseThreadSortIfSupported = $bUseThreadSortIfSupported ? $this->oImapClient->IsSupported('THREAD=REFS') || $this->oImapClient->IsSupported('THREAD=REFERENCES') || $this->oImapClient->IsSupported('THREAD=ORDEREDSUBJECT') : false;
     if (!$oCacher || !$oCacher instanceof \MailSo\Cache\CacheClient) {
         $oCacher = null;
     }
     $this->initFolderValues($sFolderName, $iMessageRealCount, $iMessageUnseenCount, $sUidNext);
     $iMessageCount = $iMessageRealCount;
     $oMessageCollection->FolderHash = self::GenerateHash($sFolderName, $iMessageRealCount, $iMessageUnseenCount, $sUidNext);
     $oMessageCollection->UidNext = $sUidNext;
     $oMessageCollection->NewMessages = $this->getFolderNextMessageInformation($sFolderName, $sPrevUidNext, $sUidNext);
     $bSearch = false;
     $bMessageListOptimization = 0 < \MailSo\Config::$MessageListCountLimitTrigger && \MailSo\Config::$MessageListCountLimitTrigger < $iMessageRealCount;
     if ($bMessageListOptimization) {
         $bUseSortIfSupported = false;
         $bUseThreadSortIfSupported = false;
         $bUseESearchOrESortRequest = false;
     }
     if (0 < $iMessageRealCount) {
         $bIndexAsUid = false;
         $aIndexOrUids = array();
         if (0 < \strlen($sSearch)) {
             $aIndexOrUids = $this->getSearchUidsResult($sSearch, $oMessageCollection->FolderName, $oMessageCollection->FolderHash, $bUseSortIfSupported, $bUseESearchOrESortRequest, $oCacher);
             $bIndexAsUid = true;
         } else {
             if ($bUseThreadSortIfSupported && 1 < $iMessageCount) {
                 $aIndexOrUids = $this->getSearchUidsResult('', $oMessageCollection->FolderName, $oMessageCollection->FolderHash, $bUseSortIfSupported, $bUseESearchOrESortRequest, $oCacher);
                 $aThreads = $this->MessageListThreadsMap($oMessageCollection->FolderName, $oMessageCollection->FolderHash, $aIndexOrUids, $oCacher, \MailSo\Config::$LargeThreadLimit);
                 $aExpandedThreadsUids = \is_array($aExpandedThreadsUids) ? $aExpandedThreadsUids : array();
                 $bWatchExpanded = 0 < \count($aExpandedThreadsUids);
                 $aNewIndexOrUids = array();
                 foreach ($aIndexOrUids as $iUid) {
                     if (isset($aThreads[$iUid])) {
                         $aNewIndexOrUids[] = $iUid;
                         if (\is_array($aThreads[$iUid])) {
                             if ($bWatchExpanded && \in_array($iUid, $aExpandedThreadsUids)) {
                                 $aSubArray = $aThreads[$iUid];
                                 foreach ($aSubArray as $iSubRootUid) {
                                     $aNewIndexOrUids[] = $iSubRootUid;
                                 }
                             } else {
                                 $aLastCollapsedThreadUids[] = $iUid;
                             }
                         }
                     }
                 }
                 $aIndexOrUids = $aNewIndexOrUids;
                 unset($aNewIndexOrUids);
                 $iMessageCount = \count($aIndexOrUids);
                 $bIndexAsUid = true;
             } else {
                 $aIndexOrUids = array(1);
                 $bIndexAsUid = false;
                 if (1 < $iMessageCount) {
                     if ($bMessageListOptimization || 0 === \MailSo\Config::$MessageListDateFilter) {
                         $aIndexOrUids = \array_reverse(\range(1, $iMessageCount));
                     } else {
                         $aIndexOrUids = $this->getSearchUidsResult('', $oMessageCollection->FolderName, $oMessageCollection->FolderHash, $bUseSortIfSupported, $bUseESearchOrESortRequest, $oCacher);
                         $bIndexAsUid = true;
                     }
                 }
             }
         }
         if (\is_array($aIndexOrUids)) {
             $oMessageCollection->MessageCount = $iMessageRealCount;
             $oMessageCollection->MessageUnseenCount = $iMessageUnseenCount;
             $oMessageCollection->MessageResultCount = 0 === \strlen($sSearch) ? $iMessageCount : \count($aIndexOrUids);
             if (0 < \count($aIndexOrUids)) {
                 $iOffset = 0 > $iOffset ? 0 : $iOffset;
                 $aRequestIndexOrUids = \array_slice($aIndexOrUids, $iOffset, $iLimit);
                 $this->MessageListByRequestIndexOrUids($oMessageCollection, $aRequestIndexOrUids, $bIndexAsUid);
             }
         }
     }
     $aLastCollapsedThreadUidsForPage = array();
     if (!$bSearch && $bUseThreadSortIfSupported && 0 < \count($aThreads)) {
         $oMessageCollection->ForeachList(function ($oMessage) use($aThreads, $aLastCollapsedThreadUids, &$aLastCollapsedThreadUidsForPage) {
             $iUid = $oMessage->Uid();
             if (\in_array($iUid, $aLastCollapsedThreadUids)) {
                 $aLastCollapsedThreadUidsForPage[] = $iUid;
             }
             if (isset($aThreads[$iUid]) && \is_array($aThreads[$iUid]) && 0 < \count($aThreads[$iUid])) {
                 $oMessage->SetThreads($aThreads[$iUid]);
                 $oMessage->SetThreadsLen(\count($aThreads[$iUid]));
             } else {
                 if (!isset($aThreads[$iUid])) {
                     foreach ($aThreads as $iKeyUid => $mSubItem) {
                         if (\is_array($mSubItem) && \in_array($iUid, $mSubItem)) {
                             $oMessage->SetParentThread($iKeyUid);
                             $oMessage->SetThreadsLen(\count($mSubItem));
                         }
                     }
                 }
             }
         });
         $oMessageCollection->LastCollapsedThreadUids = $aLastCollapsedThreadUidsForPage;
     }
     return $oMessageCollection;
 }