示例#1
0
 /**
  * Obtains message list with messages data.
  * 
  * @param CAccount $oAccount Account object.
  * @param string $sFolderFullNameRaw Raw full name of the folder.
  * @param int $iOffset = 0. Offset value for obtaining a partial list.
  * @param int $iLimit = 20. Limit value for obtaining a partial list.
  * @param string $sSearch = ''. Search text.
  * @param bool $bUseThreads = false. If **true**, message list will be returned in threaded mode.
  * @param array $aFilters = array(). Contains filters for searching of messages.
  * @param string $sInboxUidnext = ''. Uidnext value of Inbox folder.
  *
  * @return CApiMailMessageCollection
  *
  * @throws CApiInvalidArgumentException
  */
 public function getMessageList($oAccount, $sFolderFullNameRaw, $iOffset = 0, $iLimit = 20, $sSearch = '', $bUseThreads = false, $aFilters = array(), $sInboxUidnext = '')
 {
     if (0 === strlen($sFolderFullNameRaw) || 0 > $iOffset || 0 >= $iLimit || 999 < $iLimit) {
         throw new CApiInvalidArgumentException();
     }
     $oMessageCollection = false;
     $oSettings =& CApi::GetSettings();
     $oImapClient =& $this->_getImapClient($oAccount, 20, 60 * 2);
     $oImapClient->FolderExamine($sFolderFullNameRaw);
     $aList = $this->_getFolderInformation($oImapClient, $sFolderFullNameRaw);
     $iMessageCount = $aList[0];
     $iRealMessageCount = $aList[0];
     $iMessageUnseenCount = $aList[1];
     $sUidNext = $aList[2];
     $oMessageCollection = CApiMailMessageCollection::createInstance();
     $oMessageCollection->FolderName = $sFolderFullNameRaw;
     $oMessageCollection->Offset = $iOffset;
     $oMessageCollection->Limit = $iLimit;
     $oMessageCollection->Search = $sSearch;
     $oMessageCollection->UidNext = $sUidNext;
     $oMessageCollection->Filters = implode(',', $aFilters);
     $aThreads = array();
     $bUseThreadsIfSupported = !!$oSettings->GetConf('WebMail/UseThreadsIfSupported');
     if ($bUseThreadsIfSupported) {
         $bUseThreadsIfSupported = $bUseThreads;
     }
     $oMessageCollection->FolderHash = $aList[3];
     $bSearch = false;
     if (0 < $iRealMessageCount) {
         $bIndexAsUid = false;
         $aIndexOrUids = array();
         $bUseSortIfSupported = !!$oSettings->GetConf('WebMail/UseSortImapForDateMode');
         if ($bUseSortIfSupported) {
             $bUseSortIfSupported = $oImapClient->IsSupported('SORT');
         }
         if ($bUseThreadsIfSupported) {
             $bUseThreadsIfSupported = $oImapClient->IsSupported('THREAD=REFS') || $oImapClient->IsSupported('THREAD=REFERENCES') || $oImapClient->IsSupported('THREAD=ORDEREDSUBJECT');
         }
         if (0 < strlen($sSearch) || 0 < count($aFilters)) {
             $sCutedSearch = $sSearch;
             $sCutedSearch = \preg_replace('/[\\s]+/', ' ', $sCutedSearch);
             $sCutedSearch = \preg_replace('/attach[ ]?:[ ]?/i', 'attach:', $sCutedSearch);
             $bSearchAttachments = false;
             $fAttachmentSearchCallback = null;
             $aMatch = array();
             if (CApi::GetConf('labs.use-body-structures-for-has-attachments-search', false) && \preg_match('/has[ ]?:[ ]?attachments/i', $sSearch) || \preg_match('/attach:([^\\s]+)/i', $sSearch, $aMatch)) {
                 $bSearchAttachments = true;
                 $sAttachmentName = isset($aMatch[1]) ? trim($aMatch[1]) : '';
                 $sAttachmentRegs = !empty($sAttachmentName) && '*' !== $sAttachmentName ? '/[^>]*' . str_replace('\\*', '[^>]*', preg_quote(trim($sAttachmentName, '*'), '/')) . '[^>]*/ui' : '';
                 if (CApi::GetConf('labs.use-body-structures-for-has-attachments-search', false)) {
                     $sCutedSearch = trim(preg_replace('/has[ ]?:[ ]?attachments/i', '', $sCutedSearch));
                 }
                 $sCutedSearch = trim(preg_replace('/attach:([^\\s]+)/', '', $sCutedSearch));
                 $fAttachmentSearchCallback = function ($oBodyStructure, $sSize, $sInternalDate, $aFlagsLower, $sUid) use($sFolderFullNameRaw, $sAttachmentRegs) {
                     $bResult = false;
                     if ($oBodyStructure) {
                         $aAttachmentsParts = $oBodyStructure->SearchAttachmentsParts();
                         if ($aAttachmentsParts && 0 < count($aAttachmentsParts)) {
                             $oAttachments = CApiMailAttachmentCollection::createInstance();
                             foreach ($aAttachmentsParts as $oAttachmentItem) {
                                 $oAttachments->Add(CApiMailAttachment::createInstance($sFolderFullNameRaw, $sUid, $oAttachmentItem));
                             }
                             $bResult = $oAttachments->hasNotInlineAttachments();
                             if ($bResult && !empty($sAttachmentRegs)) {
                                 $aList = $oAttachments->FilterList(function ($oAttachment) use($sAttachmentRegs) {
                                     if ($oAttachment && !$oAttachment->isInline() && !$oAttachment->getCid()) {
                                         return !!preg_match($sAttachmentRegs, $oAttachment->getFileName());
                                     }
                                     return false;
                                 });
                                 return is_array($aList) ? 0 < count($aList) : false;
                             }
                         }
                     }
                     unset($oBodyStructure);
                     return $bResult;
                 };
             }
             if (0 < strlen($sCutedSearch) || 0 < count($aFilters)) {
                 $bSearch = true;
                 $sSearchCriterias = $this->_prepareImapSearchString($oImapClient, $sCutedSearch, $oAccount->getDefaultTimeOffset() * 60, $aFilters);
                 $bIndexAsUid = true;
                 $aIndexOrUids = null;
                 if ($bUseSortIfSupported) {
                     $aIndexOrUids = $oImapClient->MessageSimpleSort(array('REVERSE ARRIVAL'), $sSearchCriterias, $bIndexAsUid);
                 } else {
                     if (!\MailSo\Base\Utils::IsAscii($sCutedSearch)) {
                         try {
                             $aIndexOrUids = $oImapClient->MessageSimpleSearch($sSearchCriterias, $bIndexAsUid, 'UTF-8');
                         } catch (\MailSo\Imap\Exceptions\NegativeResponseException $oException) {
                             // Charset is not supported. Skip and try request without charset.
                             $aIndexOrUids = null;
                         }
                     }
                     if (null === $aIndexOrUids) {
                         $aIndexOrUids = $oImapClient->MessageSimpleSearch($sSearchCriterias, $bIndexAsUid);
                     }
                 }
                 if ($bSearchAttachments && is_array($aIndexOrUids) && 0 < count($aIndexOrUids)) {
                     $aIndexOrUids = $this->_doSpecialUidsSearch($oImapClient, $fAttachmentSearchCallback, $sFolderFullNameRaw, $aIndexOrUids, $iOffset, $iLimit);
                 }
             } else {
                 if ($bSearchAttachments) {
                     $bIndexAsUid = true;
                     $aIndexOrUids = $this->_doSpecialIndexSearch($oImapClient, $fAttachmentSearchCallback, $sFolderFullNameRaw, $iOffset, $iLimit);
                 }
             }
         } else {
             if ($bUseThreadsIfSupported && 1 < $iMessageCount) {
                 $bIndexAsUid = true;
                 $aThreadUids = array();
                 try {
                     $aThreadUids = $oImapClient->MessageSimpleThread();
                 } catch (\MailSo\Imap\Exceptions\RuntimeException $oException) {
                     $aThreadUids = array();
                 }
                 $aThreads = $this->_compileThreadList($aThreadUids);
                 if ($bUseSortIfSupported) {
                     $aThreads = $this->_resortThreadList($aThreads, $oImapClient->MessageSimpleSort(array('REVERSE ARRIVAL'), 'ALL', true));
                 } else {
                     //						$this->chunkThreadArray($aThreads);
                 }
                 $aIndexOrUids = array_keys($aThreads);
                 $iMessageCount = count($aIndexOrUids);
             } else {
                 if ($bUseSortIfSupported && 1 < $iMessageCount) {
                     $bIndexAsUid = true;
                     $aIndexOrUids = $oImapClient->MessageSimpleSort(array('REVERSE ARRIVAL'), 'ALL', $bIndexAsUid);
                 } else {
                     $bIndexAsUid = false;
                     $aIndexOrUids = array(1);
                     if (1 < $iMessageCount) {
                         $aIndexOrUids = array_reverse(range(1, $iMessageCount));
                     }
                 }
             }
         }
         if (is_array($aIndexOrUids)) {
             $oMessageCollection->MessageCount = $iRealMessageCount;
             $oMessageCollection->MessageUnseenCount = $iMessageUnseenCount;
             $oMessageCollection->MessageResultCount = 0 < strlen($sSearch) || 0 < count($aFilters) ? count($aIndexOrUids) : $iMessageCount;
             if (0 < count($aIndexOrUids)) {
                 $iOffset = 0 > $iOffset ? 0 : $iOffset;
                 $aRequestIndexOrUids = array_slice($aIndexOrUids, $iOffset, $iLimit);
                 if ($bIndexAsUid) {
                     $oMessageCollection->Uids = $aRequestIndexOrUids;
                 }
                 if (is_array($aRequestIndexOrUids) && 0 < count($aRequestIndexOrUids)) {
                     $aFetchResponse = $oImapClient->Fetch(array(\MailSo\Imap\Enumerations\FetchType::INDEX, \MailSo\Imap\Enumerations\FetchType::UID, \MailSo\Imap\Enumerations\FetchType::RFC822_SIZE, \MailSo\Imap\Enumerations\FetchType::INTERNALDATE, \MailSo\Imap\Enumerations\FetchType::FLAGS, \MailSo\Imap\Enumerations\FetchType::BODYSTRUCTURE, \MailSo\Imap\Enumerations\FetchType::BODY_HEADER_PEEK), implode(',', $aRequestIndexOrUids), $bIndexAsUid);
                     if (is_array($aFetchResponse) && 0 < count($aFetchResponse)) {
                         $aFetchIndexArray = array();
                         $oFetchResponseItem = null;
                         foreach ($aFetchResponse as &$oFetchResponseItem) {
                             $aFetchIndexArray[$bIndexAsUid ? $oFetchResponseItem->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::UID) : $oFetchResponseItem->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::INDEX)] =& $oFetchResponseItem;
                             unset($oFetchResponseItem);
                         }
                         foreach ($aRequestIndexOrUids as $iFUid) {
                             if (isset($aFetchIndexArray[$iFUid])) {
                                 $oMailMessage = CApiMailMessage::createInstance($oMessageCollection->FolderName, $aFetchIndexArray[$iFUid]);
                                 if (!$bIndexAsUid) {
                                     $oMessageCollection->Uids[] = $oMailMessage->getUid();
                                 }
                                 $oMessageCollection->Add($oMailMessage);
                                 unset($oMailMessage);
                             }
                         }
                     }
                 }
             }
         }
     }
     if (!$bSearch && $bUseThreadsIfSupported && 0 < count($aThreads)) {
         $oMessageCollection->ForeachList(function ($oMessage) use($aThreads) {
             $iUid = $oMessage->getUid();
             if (isset($aThreads[$iUid]) && is_array($aThreads[$iUid])) {
                 $oMessage->setThreads($aThreads[$iUid]);
             }
         });
     }
     if (0 < strlen($sInboxUidnext) && 'INBOX' === $oMessageCollection->FolderName && $sInboxUidnext !== $oMessageCollection->UidNext) {
         $oMessageCollection->New = $this->getNewMessagesInformation($oAccount, 'INBOX', $sInboxUidnext, $oMessageCollection->UidNext);
     }
     return $oMessageCollection;
 }
示例#2
0
 /**
  * @param string $sRawFolderFullName
  * @param \MailSo\Imap\FetchResponse $oFetchResponse
  * @param \MailSo\Imap\BodyStructure $oBodyStructure = null
  * @param array $aAscPartsIds = array()
  *
  * @return CApiMailMessage
  */
 public function InitByFetchResponse($sRawFolderFullName, $oFetchResponse, $oBodyStructure = null, $sRfc822SubMimeIndex = '', $aAscPartsIds = array())
 {
     if (!$oBodyStructure) {
         $oBodyStructure = $oFetchResponse->GetFetchBodyStructure();
     }
     $aTextParts = $oBodyStructure ? $oBodyStructure->SearchHtmlOrPlainParts() : array();
     $aICalPart = $oBodyStructure ? $oBodyStructure->SearchByContentType('text/calendar') : null;
     $oICalPart = is_array($aICalPart) && 0 < count($aICalPart) ? $aICalPart[0] : null;
     $aVCardPart = $oBodyStructure ? $oBodyStructure->SearchByContentType('text/vcard') : null;
     $aVCardPart = $aVCardPart ? $aVCardPart : ($oBodyStructure ? $oBodyStructure->SearchByContentType('text/x-vcard') : null);
     $oVCardPart = is_array($aVCardPart) && 0 < count($aVCardPart) ? $aVCardPart[0] : null;
     $sUid = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::UID);
     $sSize = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::RFC822_SIZE);
     $sInternalDate = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::INTERNALDATE);
     $aFlags = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::FLAGS);
     $this->sFolder = $sRawFolderFullName;
     $this->iUid = is_numeric($sUid) ? (int) $sUid : 0;
     $this->iSize = is_numeric($sSize) ? (int) $sSize : 0;
     $this->iTextSize = 0;
     $this->aFlags = is_array($aFlags) ? $aFlags : array();
     $this->aFlagsLowerCase = array_map('strtolower', $this->aFlags);
     $this->iInternalTimeStampInUTC = \MailSo\Base\DateTimeHelper::ParseInternalDateString($sInternalDate);
     if ($oICalPart) {
         $sICal = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::BODY . '[' . $oICalPart->PartID() . ']');
         if (!empty($sICal)) {
             $sICal = \MailSo\Base\Utils::DecodeEncodingValue($sICal, $oICalPart->MailEncodingName());
             $sICal = \MailSo\Base\Utils::ConvertEncoding($sICal, \MailSo\Base\Utils::NormalizeCharset($oICalPart->Charset(), true), \MailSo\Base\Enumerations\Charset::UTF_8);
             if (!empty($sICal) && false !== strpos($sICal, 'BEGIN:VCALENDAR')) {
                 $sICal = preg_replace('/(.*)(BEGIN[:]VCALENDAR(.+)END[:]VCALENDAR)(.*)/ms', '$2', $sICal);
             } else {
                 $sICal = '';
             }
             if (!empty($sICal)) {
                 $this->AddExtend('ICAL_RAW', $sICal);
             }
         }
     }
     if ($oVCardPart) {
         $sVCard = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::BODY . '[' . $oVCardPart->PartID() . ']');
         if (!empty($sVCard)) {
             $sVCard = \MailSo\Base\Utils::DecodeEncodingValue($sVCard, $oVCardPart->MailEncodingName());
             $sVCard = \MailSo\Base\Utils::ConvertEncoding($sVCard, \MailSo\Base\Utils::NormalizeCharset($oVCardPart->Charset(), true), \MailSo\Base\Enumerations\Charset::UTF_8);
             if (!empty($sVCard) && false !== strpos($sVCard, 'BEGIN:VCARD')) {
                 $sVCard = preg_replace('/(.*)(BEGIN\\:VCARD(.+)END\\:VCARD)(.*)/ms', '$2', $sVCard);
             } else {
                 $sVCard = '';
             }
             if (!empty($sVCard)) {
                 $this->AddExtend('VCARD_RAW', $sVCard);
             }
         }
     }
     $sCharset = $oBodyStructure ? $oBodyStructure->SearchCharset() : '';
     $sCharset = \MailSo\Base\Utils::NormalizeCharset($sCharset);
     $this->sHeaders = trim($oFetchResponse->GetHeaderFieldsValue($sRfc822SubMimeIndex));
     if (!empty($this->sHeaders)) {
         $oHeaders = \MailSo\Mime\HeaderCollection::NewInstance()->Parse($this->sHeaders, false, $sCharset);
         $sContentTypeCharset = $oHeaders->ParameterValue(\MailSo\Mime\Enumerations\Header::CONTENT_TYPE, \MailSo\Mime\Enumerations\Parameter::CHARSET);
         if (!empty($sContentTypeCharset)) {
             $sCharset = $sContentTypeCharset;
             $sCharset = \MailSo\Base\Utils::NormalizeCharset($sCharset);
         }
         if (!empty($sCharset)) {
             $oHeaders->SetParentCharset($sCharset);
         }
         $bCharsetAutoDetect = 0 === \strlen($sCharset);
         $this->sSubject = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::SUBJECT, $bCharsetAutoDetect);
         $this->sMessageId = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::MESSAGE_ID);
         $this->sContentType = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::CONTENT_TYPE);
         $aReceived = $oHeaders->ValuesByName(\MailSo\Mime\Enumerations\Header::RECEIVED);
         $sReceived = !empty($aReceived[0]) ? trim($aReceived[0]) : '';
         $sDate = '';
         if (!empty($sReceived)) {
             $aParts = explode(';', $sReceived);
             if (0 < count($aParts)) {
                 $aParts = array_reverse($aParts);
                 foreach ($aParts as $sReceiveLine) {
                     $sReceiveLine = trim($sReceiveLine);
                     if (preg_match('/[\\d]{4} [\\d]{2}:[\\d]{2}:[\\d]{2} /', $sReceiveLine)) {
                         $sDate = $sReceiveLine;
                         break;
                     }
                 }
             }
         }
         if (empty($sDate)) {
             $sDate = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::DATE);
         }
         if (!empty($sDate)) {
             $this->iReceivedOrDateTimeStampInUTC = \MailSo\Base\DateTimeHelper::ParseRFC2822DateString($sDate);
         }
         $this->oFrom = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::FROM_, $bCharsetAutoDetect);
         $this->oTo = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::TO_, $bCharsetAutoDetect);
         $this->oCc = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::CC, $bCharsetAutoDetect);
         $this->oBcc = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::BCC, $bCharsetAutoDetect);
         $this->oSender = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::SENDER, $bCharsetAutoDetect);
         $this->oReplyTo = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::REPLY_TO, $bCharsetAutoDetect);
         $this->sInReplyTo = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::IN_REPLY_TO);
         $this->sReferences = \preg_replace('/[\\s]+/', ' ', $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::REFERENCES));
         // Sensitivity
         $this->iSensitivity = \MailSo\Mime\Enumerations\Sensitivity::NOTHING;
         $sSensitivity = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::SENSITIVITY);
         switch (strtolower($sSensitivity)) {
             case 'personal':
                 $this->iSensitivity = \MailSo\Mime\Enumerations\Sensitivity::PERSONAL;
                 break;
             case 'private':
                 $this->iSensitivity = \MailSo\Mime\Enumerations\Sensitivity::PRIVATE_;
                 break;
             case 'company-confidential':
                 $this->iSensitivity = \MailSo\Mime\Enumerations\Sensitivity::CONFIDENTIAL;
                 break;
         }
         // Priority
         $this->iPriority = \MailSo\Mime\Enumerations\MessagePriority::NORMAL;
         $sPriority = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_MSMAIL_PRIORITY);
         if (0 === strlen($sPriority)) {
             $sPriority = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::IMPORTANCE);
         }
         if (0 === strlen($sPriority)) {
             $sPriority = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_PRIORITY);
         }
         if (0 < strlen($sPriority)) {
             switch (str_replace(' ', '', strtolower($sPriority))) {
                 case 'high':
                 case '1(highest)':
                 case '2(high)':
                 case '1':
                 case '2':
                     $this->iPriority = \MailSo\Mime\Enumerations\MessagePriority::HIGH;
                     break;
                 case 'low':
                 case '4(low)':
                 case '5(lowest)':
                 case '4':
                 case '5':
                     $this->iPriority = \MailSo\Mime\Enumerations\MessagePriority::LOW;
                     break;
             }
         }
         // ReadingConfirmation
         $this->sReadingConfirmation = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::DISPOSITION_NOTIFICATION_TO);
         if (0 === strlen($this->sReadingConfirmation)) {
             $this->sReadingConfirmation = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_CONFIRM_READING_TO);
         }
         $this->sReadingConfirmation = trim($this->sReadingConfirmation);
         $sDraftInfo = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_DRAFT_INFO);
         if (0 < strlen($sDraftInfo)) {
             $sType = '';
             $sFolder = '';
             $sUid = '';
             \MailSo\Mime\ParameterCollection::NewInstance($sDraftInfo)->ForeachList(function ($oParameter) use(&$sType, &$sFolder, &$sUid) {
                 switch (strtolower($oParameter->Name())) {
                     case 'type':
                         $sType = $oParameter->Value();
                         break;
                     case 'uid':
                         $sUid = $oParameter->Value();
                         break;
                     case 'folder':
                         $sFolder = base64_decode($oParameter->Value());
                         break;
                 }
             });
             if (0 < strlen($sType) && 0 < strlen($sFolder) && 0 < strlen($sUid)) {
                 $this->aDraftInfo = array($sType, $sUid, $sFolder);
             }
         }
         \CApi::Plugin()->RunHook('api-mail-message-headers-parse', array(&$this, $oHeaders));
     }
     if (is_array($aTextParts) && 0 < count($aTextParts)) {
         if (0 === \strlen($sCharset)) {
             $sCharset = \MailSo\Base\Enumerations\Charset::UTF_8;
         }
         $sHtmlParts = array();
         $sPlainParts = array();
         $iHtmlSize = 0;
         $iPlainSize = 0;
         foreach ($aTextParts as $oPart) {
             if ($oPart) {
                 if ('text/html ' === $oPart->ContentType()) {
                     $iHtmlSize += $oPart->EstimatedSize();
                 } else {
                     $iPlainSize += $oPart->EstimatedSize();
                 }
             }
             $sText = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::BODY . '[' . $oPart->PartID() . ('' !== $sRfc822SubMimeIndex && is_numeric($sRfc822SubMimeIndex) ? '.1' : '') . ']');
             //				if (null === $sText)
             //				{
             //					$sText = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::BODY.'['.$oPart->PartID().
             //						('' !== $sRfc822SubMimeIndex && is_numeric($sRfc822SubMimeIndex) ? '.1' : '').']<0>');
             //				}
             if (is_string($sText) && 0 < strlen($sText)) {
                 $sTextCharset = $oPart->Charset();
                 if (empty($sTextCharset)) {
                     $sTextCharset = $sCharset;
                 }
                 $sTextCharset = \MailSo\Base\Utils::NormalizeCharset($sTextCharset, true);
                 $sText = \MailSo\Base\Utils::DecodeEncodingValue($sText, $oPart->MailEncodingName());
                 $sText = \MailSo\Base\Utils::ConvertEncoding($sText, $sTextCharset, \MailSo\Base\Enumerations\Charset::UTF_8);
                 $sText = \MailSo\Base\Utils::Utf8Clear($sText);
                 if ('text/html' === $oPart->ContentType()) {
                     $sHtmlParts[] = $sText;
                 } else {
                     $sPlainParts[] = $sText;
                 }
             }
         }
         if (0 < count($sHtmlParts)) {
             $this->sHtml = trim(implode('<br />', $sHtmlParts));
             $this->iTextSize = strlen($this->sHtml);
         } else {
             $this->sPlain = trim(implode("\n", $sPlainParts));
             $this->iTextSize = strlen($this->sPlain);
         }
         if (0 === $this->iTextSize) {
             $this->iTextSize = 0 < $iHtmlSize ? $iHtmlSize : $iPlainSize;
         }
         unset($sHtmlParts, $sPlainParts);
     }
     if ($oBodyStructure) {
         $aAttachmentsParts = $oBodyStructure->SearchAttachmentsParts();
         if ($aAttachmentsParts && 0 < count($aAttachmentsParts)) {
             $this->oAttachments = CApiMailAttachmentCollection::NewInstance();
             foreach ($aAttachmentsParts as $oAttachmentItem) {
                 $this->oAttachments->Add(CApiMailAttachment::NewBodyStructureInstance($this->sFolder, $this->iUid, $oAttachmentItem));
             }
             $this->oAttachments->ForeachList(function ($oAttachment) use($aAscPartsIds, $oFetchResponse) {
                 if ($oAttachment && in_array($oAttachment->MimeIndex(), $aAscPartsIds)) {
                     $mContent = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::BODY . '[' . $oAttachment->MimeIndex() . ']');
                     if (is_string($mContent)) {
                         $oAttachment->SetContent(\MailSo\Base\Utils::DecodeEncodingValue($mContent, $oAttachment->ContentTransferEncoding()));
                     }
                 }
             });
         }
     }
     \CApi::Plugin()->RunHook('api-mail-message-parse', array(&$this, $oFetchResponse, $oBodyStructure, $sRfc822SubMimeIndex));
     return $this;
 }