예제 #1
0
 /**
  * @param \RainLoop\Providers\Filters\Classes\Filter $oFilter
  * @param array $aCapa
  *
  * @return string
  */
 private function filterToSieveScript($oFilter, &$aCapa)
 {
     $sNL = \RainLoop\Providers\Filters\SieveStorage::NEW_LINE;
     $sTab = '    ';
     $bAll = false;
     $aResult = array();
     // Conditions
     $aConditions = $oFilter->Conditions();
     if (\is_array($aConditions)) {
         if (1 < \count($aConditions)) {
             if (\RainLoop\Providers\Filters\Enumerations\ConditionsType::ANY === $oFilter->ConditionsType()) {
                 $aResult[] = 'if anyof(';
                 $bTrim = false;
                 foreach ($aConditions as $oCond) {
                     $bTrim = true;
                     $sCons = $this->conditionToSieveScript($oCond);
                     if (!empty($sCons)) {
                         $aResult[] = $sTab . $sCons . ',';
                     }
                 }
                 if ($bTrim) {
                     $aResult[\count($aResult) - 1] = \rtrim($aResult[\count($aResult) - 1], ',');
                 }
                 $aResult[] = ')';
             } else {
                 $aResult[] = 'if allof(';
                 foreach ($aConditions as $oCond) {
                     $aResult[] = $sTab . $this->conditionToSieveScript($oCond) . ',';
                 }
                 $aResult[\count($aResult) - 1] = \rtrim($aResult[\count($aResult) - 1], ',');
                 $aResult[] = ')';
             }
         } else {
             if (1 === \count($aConditions)) {
                 $aResult[] = 'if ' . $this->conditionToSieveScript($aConditions[0]) . '';
             } else {
                 $bAll = true;
             }
         }
     }
     // actions
     if (!$bAll) {
         $aResult[] = '{';
     } else {
         $sTab = '';
     }
     if ($oFilter->MarkAsRead() && \in_array($oFilter->ActionType(), array(\RainLoop\Providers\Filters\Enumerations\ActionType::NONE, \RainLoop\Providers\Filters\Enumerations\ActionType::MOVE_TO, \RainLoop\Providers\Filters\Enumerations\ActionType::FORWARD))) {
         $aCapa['imap4flags'] = true;
         $aResult[] = $sTab . 'addflag "\\\\Seen";';
     }
     switch ($oFilter->ActionType()) {
         case \RainLoop\Providers\Filters\Enumerations\ActionType::NONE:
             $aResult[] = $sTab . 'stop;';
             break;
         case \RainLoop\Providers\Filters\Enumerations\ActionType::DISCARD:
             $aResult[] = $sTab . 'discard;';
             $aResult[] = $sTab . 'stop;';
             break;
         case \RainLoop\Providers\Filters\Enumerations\ActionType::VACATION:
             $sValue = \trim($oFilter->ActionValue());
             $sValueSecond = \trim($oFilter->ActionValueSecond());
             $sValueThird = \trim($oFilter->ActionValueThird());
             if (0 < \strlen($sValue)) {
                 $aCapa['vacation'] = true;
                 $iDays = 1;
                 $sSubject = '';
                 if (0 < \strlen($sValueSecond)) {
                     $sSubject = ':subject "' . $this->quote(\MailSo\Base\Utils::StripSpaces($sValueSecond)) . '" ';
                 }
                 if (0 < \strlen($sValueThird) && \is_numeric($sValueThird) && 1 < (int) $sValueThird) {
                     $iDays = (int) $sValueThird;
                 }
                 $aResult[] = $sTab . 'vacation :days ' . $iDays . ' ' . $sSubject . '"' . $this->quote($sValue) . '";';
                 if ($oFilter->Stop()) {
                     $aResult[] = $sTab . 'stop;';
                 }
             } else {
                 $aResult[] = $sTab . '# @Error (vacation): empty action value';
             }
             break;
         case \RainLoop\Providers\Filters\Enumerations\ActionType::REJECT:
             $sValue = \trim($oFilter->ActionValue());
             if (0 < \strlen($sValue)) {
                 $aCapa['reject'] = true;
                 $aResult[] = $sTab . 'reject "' . $this->quote($sValue) . '";';
                 $aResult[] = $sTab . 'stop;';
             } else {
                 $aResult[] = $sTab . '# @Error (reject): empty action value';
             }
             break;
         case \RainLoop\Providers\Filters\Enumerations\ActionType::FORWARD:
             $sValue = $oFilter->ActionValue();
             if (0 < \strlen($sValue)) {
                 if ($oFilter->Keep()) {
                     $aCapa['fileinto'] = true;
                     $aResult[] = $sTab . 'fileinto "INBOX";';
                 }
                 $aResult[] = $sTab . 'redirect "' . $this->quote($sValue) . '";';
                 $aResult[] = $sTab . 'stop;';
             } else {
                 $aResult[] = $sTab . '# @Error (redirect): empty action value';
             }
             break;
         case \RainLoop\Providers\Filters\Enumerations\ActionType::MOVE_TO:
             $sValue = $oFilter->ActionValue();
             if (0 < \strlen($sValue)) {
                 $sFolderName = $sValue;
                 // utf7-imap
                 if ($this->bUtf8FolderName) {
                     $sFolderName = \MailSo\Base\Utils::ConvertEncoding($sFolderName, \MailSo\Base\Enumerations\Charset::UTF_7_IMAP, \MailSo\Base\Enumerations\Charset::UTF_8);
                 }
                 $aCapa['fileinto'] = true;
                 $aResult[] = $sTab . 'fileinto "' . $this->quote($sFolderName) . '";';
                 $aResult[] = $sTab . 'stop;';
             } else {
                 $aResult[] = $sTab . '# @Error (fileinto): empty action value';
             }
             break;
     }
     if (!$bAll) {
         $aResult[] = '}';
     }
     return \implode($sNL, $aResult);
 }
예제 #2
0
 /**
  * @param string $sText
  *
  * @return string
  */
 public static function ConvertHtmlToPlain($sText)
 {
     $sText = \trim(\stripslashes($sText));
     $sText = \MailSo\Base\Utils::StripSpaces($sText);
     $sText = \preg_replace(array("/\r/", "/[\n\t]+/", '/<script[^>]*>.*?<\\/script>/i', '/<style[^>]*>.*?<\\/style>/i', '/<title[^>]*>.*?<\\/title>/i', '/<h[123][^>]*>(.+?)<\\/h[123]>/i', '/<h[456][^>]*>(.+?)<\\/h[456]>/i', '/<p[^>]*>/i', '/<br[^>]*>/i', '/<b[^>]*>(.+?)<\\/b>/i', '/<i[^>]*>(.+?)<\\/i>/i', '/(<ul[^>]*>|<\\/ul>)/i', '/(<ol[^>]*>|<\\/ol>)/i', '/<li[^>]*>/i', '/<a[^>]*href="([^"]+)"[^>]*>(.+?)<\\/a>/i', '/<hr[^>]*>/i', '/(<table[^>]*>|<\\/table>)/i', '/(<tr[^>]*>|<\\/tr>)/i', '/<td[^>]*>(.+?)<\\/td>/i', '/<th[^>]*>(.+?)<\\/th>/i', '/&nbsp;/i', '/&quot;/i', '/&gt;/i', '/&lt;/i', '/&amp;/i', '/&copy;/i', '/&trade;/i', '/&#8220;/', '/&#8221;/', '/&#8211;/', '/&#8217;/', '/&#38;/', '/&#169;/', '/&#8482;/', '/&#151;/', '/&#147;/', '/&#148;/', '/&#149;/', '/&reg;/i', '/&bull;/i', '/&[&;]+;/i', '/&#39;/', '/&#160;/'), array('', ' ', '', '', '', "\n\n\\1\n\n", "\n\n\\1\n\n", "\n\n\t", "\n", '\\1', '\\1', "\n\n", "\n\n", "\n\t* ", '\\2 (\\1)', "\n------------------------------------\n", "\n", "\n", "\t\\1\n", "\t\\1\n", ' ', '"', '>', '<', '&', '(c)', '(tm)', '"', '"', '-', "'", '&', '(c)', '(tm)', '--', '"', '"', '*', '(R)', '*', '', '\'', ''), $sText);
     $sText = \str_ireplace('<div>', "\n<div>", $sText);
     $sText = \strip_tags($sText, '');
     $sText = \preg_replace("/\n\\s+\n/", "\n", $sText);
     $sText = \preg_replace("/[\n]{3,}/", "\n\n", $sText);
     return \trim($sText);
 }
예제 #3
0
 /**
  * @param string $sSearch
  * @param string $sFilter
  * @param int $iTimeZoneOffset = 0
  * @param bool $bUseCache = true
  *
  * @return string
  */
 private function getImapSearchCriterias($sSearch, $sFilter, $iTimeZoneOffset = 0, &$bUseCache = true)
 {
     $bUseCache = true;
     $iTimeFilter = 0;
     $aCriteriasResult = array();
     if (0 < \MailSo\Config::$MessageListDateFilter) {
         $iD = \time() - 3600 * 24 * 30 * \MailSo\Config::$MessageListDateFilter;
         $iTimeFilter = \gmmktime(1, 1, 1, \gmdate('n', $iD), 1, \gmdate('Y', $iD));
     }
     if (0 < \strlen(\trim($sSearch))) {
         $sGmailRawSearch = '';
         $sResultBodyTextSearch = '';
         $aLines = $this->parseSearchString($sSearch);
         $bIsGmail = $this->oImapClient->IsSupported('X-GM-EXT-1');
         if (1 === \count($aLines) && isset($aLines['OTHER'])) {
             $sValue = $this->escapeSearchString($aLines['OTHER']);
             if (\MailSo\Config::$MessageListFastSimpleSearch) {
                 $aCriteriasResult[] = 'OR OR OR';
                 $aCriteriasResult[] = 'FROM';
                 $aCriteriasResult[] = $sValue;
                 $aCriteriasResult[] = 'TO';
                 $aCriteriasResult[] = $sValue;
                 $aCriteriasResult[] = 'CC';
                 $aCriteriasResult[] = $sValue;
                 $aCriteriasResult[] = 'SUBJECT';
                 $aCriteriasResult[] = $sValue;
             } else {
                 $aCriteriasResult[] = 'TEXT';
                 $aCriteriasResult[] = $sValue;
             }
         } else {
             if (isset($aLines['EMAIL'])) {
                 $sValue = $this->escapeSearchString($aLines['EMAIL']);
                 $aCriteriasResult[] = 'OR OR';
                 $aCriteriasResult[] = 'FROM';
                 $aCriteriasResult[] = $sValue;
                 $aCriteriasResult[] = 'TO';
                 $aCriteriasResult[] = $sValue;
                 $aCriteriasResult[] = 'CC';
                 $aCriteriasResult[] = $sValue;
                 unset($aLines['EMAIL']);
             }
             if (isset($aLines['TO'])) {
                 $sValue = $this->escapeSearchString($aLines['TO']);
                 $aCriteriasResult[] = 'OR';
                 $aCriteriasResult[] = 'TO';
                 $aCriteriasResult[] = $sValue;
                 $aCriteriasResult[] = 'CC';
                 $aCriteriasResult[] = $sValue;
                 unset($aLines['TO']);
             }
             $sMainText = '';
             foreach ($aLines as $sName => $sRawValue) {
                 if ('' === \trim($sRawValue)) {
                     continue;
                 }
                 $sValue = $this->escapeSearchString($sRawValue);
                 switch ($sName) {
                     case 'FROM':
                         $aCriteriasResult[] = 'FROM';
                         $aCriteriasResult[] = $sValue;
                         break;
                     case 'SUBJECT':
                         $aCriteriasResult[] = 'SUBJECT';
                         $aCriteriasResult[] = $sValue;
                         break;
                     case 'OTHER':
                     case 'TEXT':
                         $sMainText .= ' ' . $sRawValue;
                         break;
                     case 'HAS':
                         $aValue = \explode(',', \strtolower($sRawValue));
                         $aValue = \array_map('trim', $aValue);
                         $aCompareArray = array('file', 'files', 'attach', 'attachs', 'attachment', 'attachments');
                         if (\count($aCompareArray) > \count(\array_diff($aCompareArray, $aValue))) {
                             if ($bIsGmail) {
                                 $sGmailRawSearch .= ' has:attachment';
                             } else {
                                 // Simple, is not detailed search (Sometimes doesn't work)
                                 $aCriteriasResult[] = 'OR OR OR';
                                 $aCriteriasResult[] = 'HEADER Content-Type application/';
                                 $aCriteriasResult[] = 'HEADER Content-Type multipart/m';
                                 $aCriteriasResult[] = 'HEADER Content-Type multipart/signed';
                                 $aCriteriasResult[] = 'HEADER Content-Type multipart/report';
                             }
                         }
                     case 'IS':
                         $aValue = \explode(',', \strtolower($sRawValue));
                         $aValue = \array_map('trim', $aValue);
                         $aCompareArray = array('flag', 'flagged', 'star', 'starred', 'pinned');
                         $aCompareArray2 = array('unflag', 'unflagged', 'unstar', 'unstarred', 'unpinned');
                         if (\count($aCompareArray) > \count(\array_diff($aCompareArray, $aValue))) {
                             $aCriteriasResult[] = 'FLAGGED';
                             $bUseCache = false;
                         } else {
                             if (\count($aCompareArray2) > \count(\array_diff($aCompareArray2, $aValue))) {
                                 $aCriteriasResult[] = 'UNFLAGGED';
                                 $bUseCache = false;
                             }
                         }
                         $aCompareArray = array('unread', 'unseen');
                         $aCompareArray2 = array('read', 'seen');
                         if (\count($aCompareArray) > \count(\array_diff($aCompareArray, $aValue))) {
                             $aCriteriasResult[] = 'UNSEEN';
                             $bUseCache = false;
                         } else {
                             if (\count($aCompareArray2) > \count(\array_diff($aCompareArray2, $aValue))) {
                                 $aCriteriasResult[] = 'SEEN';
                                 $bUseCache = false;
                             }
                         }
                         break;
                     case 'LARGER':
                         $aCriteriasResult[] = 'LARGER';
                         $aCriteriasResult[] = $this->parseFriendlySize($sRawValue);
                         break;
                     case 'SMALLER':
                         $aCriteriasResult[] = 'SMALLER';
                         $aCriteriasResult[] = $this->parseFriendlySize($sRawValue);
                         break;
                     case 'DATE':
                         $iDateStampFrom = $iDateStampTo = 0;
                         $sDate = $sRawValue;
                         $aDate = \explode('/', $sDate);
                         if (\is_array($aDate) && 2 === \count($aDate)) {
                             if (0 < \strlen($aDate[0])) {
                                 $iDateStampFrom = $this->parseSearchDate($aDate[0], $iTimeZoneOffset);
                             }
                             if (0 < \strlen($aDate[1])) {
                                 $iDateStampTo = $this->parseSearchDate($aDate[1], $iTimeZoneOffset);
                                 $iDateStampTo += 60 * 60 * 24;
                             }
                         } else {
                             if (0 < \strlen($sDate)) {
                                 $iDateStampFrom = $this->parseSearchDate($sDate, $iTimeZoneOffset);
                                 $iDateStampTo = $iDateStampFrom + 60 * 60 * 24;
                             }
                         }
                         if (0 < $iDateStampFrom) {
                             $aCriteriasResult[] = 'SINCE';
                             $aCriteriasResult[] = \gmdate('j-M-Y', $iTimeFilter > $iDateStampFrom ? $iTimeFilter : $iDateStampFrom);
                             $iTimeFilter = 0;
                         }
                         if (0 < $iDateStampTo) {
                             $aCriteriasResult[] = 'BEFORE';
                             $aCriteriasResult[] = \gmdate('j-M-Y', $iDateStampTo);
                         }
                         break;
                 }
             }
             if ('' !== \trim($sMainText)) {
                 $sMainText = \trim(\MailSo\Base\Utils::StripSpaces($sMainText), '"');
                 if ($bIsGmail) {
                     $sGmailRawSearch .= ' ' . $sMainText;
                 } else {
                     $sResultBodyTextSearch .= ' ' . $sMainText;
                 }
             }
         }
         $sGmailRawSearch = \trim($sGmailRawSearch);
         if ($bIsGmail && 0 < \strlen($sGmailRawSearch)) {
             $aCriteriasResult[] = 'X-GM-RAW';
             $aCriteriasResult[] = $this->escapeSearchString($sGmailRawSearch, false);
         }
         $sResultBodyTextSearch = \trim($sResultBodyTextSearch);
         if (0 < \strlen($sResultBodyTextSearch)) {
             $aCriteriasResult[] = 'BODY';
             $aCriteriasResult[] = $this->escapeSearchString($sResultBodyTextSearch);
         }
     }
     $sCriteriasResult = \trim(\implode(' ', $aCriteriasResult));
     if (0 < $iTimeFilter) {
         $sCriteriasResult .= ' SINCE ' . \gmdate('j-M-Y', $iTimeFilter);
     }
     $sCriteriasResult = \trim($sCriteriasResult);
     if (\MailSo\Config::$MessageListUndeletedOnly) {
         $sCriteriasResult = \trim($sCriteriasResult . ' UNDELETED');
     }
     $sFilter = \trim($sFilter);
     if ('' !== $sFilter) {
         $sCriteriasResult .= ' ' . $sFilter;
     }
     $sCriteriasResult = \trim($sCriteriasResult);
     if ('' !== \MailSo\Config::$MessageListPermanentFilter) {
         $sCriteriasResult = \trim($sCriteriasResult . ' ' . \MailSo\Config::$MessageListPermanentFilter);
     }
     $sCriteriasResult = \trim($sCriteriasResult);
     if ('' === $sCriteriasResult) {
         $sCriteriasResult = 'ALL';
     }
     return $sCriteriasResult;
 }
예제 #4
0
 /**
  * @param string $sFileName
  * @param string $sContentType
  * @param string $sMimeIndex
  * @param int $iMaxLength = 250
  *
  * @return string
  */
 public function MainClearFileName($sFileName, $sContentType, $sMimeIndex, $iMaxLength = 250)
 {
     $sFileName = 0 === \strlen($sFileName) ? \preg_replace('/[^a-zA-Z0-9]/', '.', (empty($sMimeIndex) ? '' : $sMimeIndex . '.') . $sContentType) : $sFileName;
     $sClearedFileName = \MailSo\Base\Utils::StripSpaces(\preg_replace('/[\\.]+/', '.', $sFileName));
     $sExt = \MailSo\Base\Utils::GetFileExtension($sClearedFileName);
     if (10 < $iMaxLength && $iMaxLength < \strlen($sClearedFileName) - \strlen($sExt)) {
         $sClearedFileName = \substr($sClearedFileName, 0, $iMaxLength) . (empty($sExt) ? '' : '.' . $sExt);
     }
     return \MailSo\Base\Utils::ClearFileName(\MailSo\Base\Utils::Utf8Clear($sClearedFileName));
 }
예제 #5
0
 /**
  * @param string $sFileName
  *
  * @return string
  */
 public static function ClearFileName($sFileName)
 {
     return \MailSo\Base\Utils::Trim(\MailSo\Base\Utils::ClearNullBite(\MailSo\Base\Utils::StripSpaces(\str_replace(array('"', '/', '\\', '*', '?', '<', '>', '|', ':'), ' ', $sFileName))));
 }
예제 #6
0
 /**
  * @param string $sReferences
  *
  * @return \MailSo\Mime\Message
  */
 public function SetReferences($sReferences)
 {
     $this->aHeadersValue[\MailSo\Mime\Enumerations\Header::REFERENCES] = \MailSo\Base\Utils::StripSpaces($sReferences);
     return $this;
 }
예제 #7
0
 public function UpdateDependentValues()
 {
     $this->Value = \trim($this->Value);
     $this->ValueCustom = \trim($this->ValueCustom);
     $this->TypeStr = \trim($this->TypeStr);
     $this->ValueLower = '';
     if (0 < \strlen($this->Value)) {
         // lower
         if ($this->IsEmail()) {
             $this->Value = \MailSo\Base\Utils::StrToLowerIfAscii($this->Value);
         }
         if ($this->IsName()) {
             $this->Value = \MailSo\Base\Utils::StripSpaces($this->Value);
         }
         // lower value for searching
         if (\MailSo\Base\Utils::FunctionExistsAndEnabled('mb_strtolower')) {
             $this->ValueLower = (string) @\mb_strtolower($this->Value, 'UTF-8');
         }
         // phone value for searching
         if ($this->IsPhone()) {
             $sPhone = \trim($this->Value);
             $sPhone = \preg_replace('/^[+]+/', '', $sPhone);
             $sPhone = \preg_replace('/[^\\d]/', '', $sPhone);
             $this->ValueCustom = \trim($sPhone);
         }
     }
 }
예제 #8
0
 /**
  * @param string $sFolder
  * @param \MailSo\Imap\FetchResponse $oFetchResponse
  * @param \MailSo\Imap\BodyStructure $oBodyStructure = null
  *
  * @return \MailSo\Mail\Message
  */
 public function InitByFetchResponse($sFolder, $oFetchResponse, $oBodyStructure = null)
 {
     if (!$oBodyStructure) {
         $oBodyStructure = $oFetchResponse->GetFetchBodyStructure();
     }
     $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 = $sFolder;
     $this->iUid = \is_numeric($sUid) ? (int) $sUid : 0;
     $this->iSize = \is_numeric($sSize) ? (int) $sSize : 0;
     $this->aFlags = \is_array($aFlags) ? $aFlags : array();
     $this->aFlagsLowerCase = \array_map('strtolower', $this->aFlags);
     $this->iInternalTimeStampInUTC = \MailSo\Base\DateTimeHelper::ParseInternalDateString($sInternalDate);
     $sCharset = $oBodyStructure ? $oBodyStructure->SearchCharset() : '';
     $sCharset = \MailSo\Base\Utils::NormalizeCharset($sCharset);
     $sHeaders = $oFetchResponse->GetHeaderFieldsValue();
     if (0 < \strlen($sHeaders)) {
         $oHeaders = \MailSo\Mime\HeaderCollection::NewInstance()->Parse($sHeaders, false, $sCharset);
         $sContentTypeCharset = $oHeaders->ParameterValue(\MailSo\Mime\Enumerations\Header::CONTENT_TYPE, \MailSo\Mime\Enumerations\Parameter::CHARSET);
         if (0 < \strlen($sContentTypeCharset)) {
             $sCharset = $sContentTypeCharset;
             $sCharset = \MailSo\Base\Utils::NormalizeCharset($sCharset);
         }
         if (0 < \strlen($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);
         $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);
         $oHeaders->PopulateEmailColectionByDkim($this->oFrom);
         $this->oSender = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::SENDER, $bCharsetAutoDetect);
         $this->oReplyTo = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::REPLY_TO, $bCharsetAutoDetect);
         $this->oDeliveredTo = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::DELIVERED_TO, $bCharsetAutoDetect);
         $this->sInReplyTo = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::IN_REPLY_TO);
         $this->sReferences = \MailSo\Base\Utils::StripSpaces($oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::REFERENCES));
         $sHeaderDate = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::DATE);
         $this->sHeaderDate = $sHeaderDate;
         $this->iHeaderTimeStampInUTC = \MailSo\Base\DateTimeHelper::ParseRFC2822DateString($sHeaderDate);
         // 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;
             }
         }
         // Delivery Receipt
         $this->sDeliveryReceipt = \trim($oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::RETURN_RECEIPT_TO));
         // Read Receipt
         $this->sReadReceipt = \trim($oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::DISPOSITION_NOTIFICATION_TO));
         if (empty($this->sReadReceipt)) {
             $this->sReadReceipt = \trim($oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_CONFIRM_READING_TO));
         }
         $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);
             }
         }
     } else {
         if ($oFetchResponse->GetEnvelope()) {
             if (0 === \strlen($sCharset) && $oBodyStructure) {
                 $sCharset = $oBodyStructure->SearchCharset();
                 $sCharset = \MailSo\Base\Utils::NormalizeCharset($sCharset);
             }
             if (0 === \strlen($sCharset)) {
                 $sCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1;
             }
             // date, subject, from, sender, reply-to, to, cc, bcc, in-reply-to, message-id
             $this->sMessageId = $oFetchResponse->GetFetchEnvelopeValue(9, '');
             $this->sSubject = \MailSo\Base\Utils::DecodeHeaderValue($oFetchResponse->GetFetchEnvelopeValue(1, ''), $sCharset);
             $this->oFrom = $oFetchResponse->GetFetchEnvelopeEmailCollection(2, $sCharset);
             $this->oSender = $oFetchResponse->GetFetchEnvelopeEmailCollection(3, $sCharset);
             $this->oReplyTo = $oFetchResponse->GetFetchEnvelopeEmailCollection(4, $sCharset);
             $this->oTo = $oFetchResponse->GetFetchEnvelopeEmailCollection(5, $sCharset);
             $this->oCc = $oFetchResponse->GetFetchEnvelopeEmailCollection(6, $sCharset);
             $this->oBcc = $oFetchResponse->GetFetchEnvelopeEmailCollection(7, $sCharset);
             $this->sInReplyTo = $oFetchResponse->GetFetchEnvelopeValue(8, '');
         }
     }
     $aTextParts = $oBodyStructure ? $oBodyStructure->SearchHtmlOrPlainParts() : null;
     if (\is_array($aTextParts) && 0 < \count($aTextParts)) {
         if (0 === \strlen($sCharset)) {
             $sCharset = \MailSo\Base\Enumerations\Charset::UTF_8;
         }
         $aHtmlParts = array();
         $aPlainParts = array();
         foreach ($aTextParts as $oPart) {
             $sText = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::BODY . '[' . $oPart->PartID() . ']');
             if (null === $sText) {
                 $sText = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::BODY . '[' . $oPart->PartID() . ']<0>');
                 if (\is_string($sText) && 0 < \strlen($sText)) {
                     $this->bTextPartIsTrimmed = true;
                 }
             }
             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()) {
                     $aHtmlParts[] = $sText;
                 } else {
                     if ($oPart->IsFlowedFormat()) {
                         $sText = \MailSo\Base\Utils::DecodeFlowedFormat($sText);
                     }
                     $aPlainParts[] = $sText;
                 }
             }
         }
         if (0 < \count($aHtmlParts)) {
             $this->sHtml = \implode('<br />', $aHtmlParts);
         } else {
             $this->sPlain = \trim(\implode("\n", $aPlainParts));
         }
         $aMatch = array();
         if (\preg_match('/-----BEGIN PGP SIGNATURE-----(.+)-----END PGP SIGNATURE-----/ism', $this->sPlain, $aMatch) && !empty($aMatch[0])) {
             $this->sPgpSignature = \trim($aMatch[0]);
             $this->bPgpSigned = true;
         }
         $aMatch = array();
         if (\preg_match('/-----BEGIN PGP MESSAGE-----/ism', $this->sPlain, $aMatch) && !empty($aMatch[0])) {
             $this->bPgpEncrypted = true;
         }
         unset($aHtmlParts, $aPlainParts, $aMatch);
     }
     //		if (empty($this->sPgpSignature) && 'multipart/signed' === \strtolower($this->sContentType) &&
     //			'application/pgp-signature' === \strtolower($oHeaders->ParameterValue(
     //				\MailSo\Mime\Enumerations\Header::CONTENT_TYPE,
     //				\MailSo\Mime\Enumerations\Parameter::PROTOCOL
     //			)))
     //		{
     //			$aPgpSignatureParts = $oBodyStructure ? $oBodyStructure->SearchByContentType('application/pgp-signature') : null;
     //			if (\is_array($aPgpSignatureParts) && 0 < \count($aPgpSignatureParts) && isset($aPgpSignatureParts[0]))
     //			{
     //				$sPgpSignatureText = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::BODY.'['.$aPgpSignatureParts[0]->PartID().']');
     //				if (\is_string($sPgpSignatureText) && 0 < \strlen($sPgpSignatureText) && 0 < \strpos($sPgpSignatureText, 'BEGIN PGP SIGNATURE'))
     //				{
     //					$this->sPgpSignature = \trim($sPgpSignatureText);
     //					$this->bPgpSigned = true;
     //				}
     //			}
     //		}
     if ($oBodyStructure) {
         $aAttachmentsParts = $oBodyStructure->SearchAttachmentsParts();
         if ($aAttachmentsParts && 0 < count($aAttachmentsParts)) {
             $this->oAttachments = AttachmentCollection::NewInstance();
             foreach ($aAttachmentsParts as $oAttachmentItem) {
                 $this->oAttachments->Add(\MailSo\Mail\Attachment::NewBodyStructureInstance($this->sFolder, $this->iUid, $oAttachmentItem));
             }
         }
     }
     return $this;
 }