/** * @return bool */ protected function clearImplementation() { if (\defined('PHP_SAPI') && 'cli' === PHP_SAPI && \MailSo\Base\Utils::FunctionExistsAndEnabled('system')) { \system('clear'); } return true; }
/** * @param bool $bSupported * @param int $iSecurityType * @param bool $bHasSupportedAuth = true * * @return bool */ public static function UseStartTLS($bSupported, $iSecurityType, $bHasSupportedAuth = true) { return ($bSupported && (self::STARTTLS === $iSecurityType || (self::AUTO_DETECT === $iSecurityType && (!$bHasSupportedAuth || \MailSo\Config::$PreferStartTlsIfAutoDetect))) && \defined('STREAM_CRYPTO_METHOD_TLS_CLIENT') && \MailSo\Base\Utils::FunctionExistsAndEnabled('stream_socket_enable_crypto')); }
/** * @param \RainLoop\Model\Account $oHmailAccount * @param string $sPrevPassword * @param string $sNewPassword * * @return bool */ public function ChangePassword(\RainLoop\Account $oHmailAccount, $sPrevPassword, $sNewPassword) { if ($this->oLogger) { $this->oLogger->Write('Try to change password for ' . $oHmailAccount->Email()); } $bResult = false; try { $oHmailApp = new COM("hMailServer.Application"); $oHmailApp->Connect(); if ($oHmailApp->Authenticate($this->sLogin, $this->sPassword)) { $sEmail = $oHmailAccount->Email(); $sDomain = \MailSo\Base\Utils::GetDomainFromEmail($sEmail); $oHmailDomain = $oHmailApp->Domains->ItemByName($sDomain); if ($oHmailDomain) { $oHmailAccount = $oHmailDomain->Accounts->ItemByAddress($sEmail); if ($oHmailAccount) { $oHmailAccount->Password = $sNewPassword; $oHmailAccount->Save(); $bResult = true; } else { $this->oLogger->Write('HMAILSERVER: Unknown account (' . $sEmail . ')', \MailSo\Log\Enumerations\Type::ERROR); } } else { $this->oLogger->Write('HMAILSERVER: Unknown domain (' . $sDomain . ')', \MailSo\Log\Enumerations\Type::ERROR); } } else { $this->oLogger->Write('HMAILSERVER: Auth error', \MailSo\Log\Enumerations\Type::ERROR); } } catch (\Exception $oException) { if ($this->oLogger) { $this->oLogger->WriteException($oException); } } return $bResult; }
/** * @param \RainLoop\Account $oAccount * @param string $sPrevPassword * @param string $sNewPassword */ public function ChangePassword(\RainLoop\Account $oAccount, $sPrevPassword, $sNewPassword) { $mResult = false; if ($this->oDriver instanceof \RainLoop\Providers\ChangePassword\ChangePasswordInterface && $this->PasswordChangePossibility($oAccount)) { if ($sPrevPassword !== $oAccount->Password()) { throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CurrentPasswordIncorrect); } $sPasswordForCheck = \trim($sNewPassword); if (6 > \strlen($sPasswordForCheck)) { throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::NewPasswordShort); } if (!\MailSo\Base\Utils::PasswordWeaknessCheck($sPasswordForCheck)) { throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::NewPasswordWeak); } if (!$this->oDriver->ChangePassword($oAccount, $sPrevPassword, $sNewPassword)) { throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CouldNotSaveNewPassword); } $oAccount->SetPassword($sNewPassword); $this->oActions->SetAuthToken($oAccount); $mResult = $this->oActions->GetSpecAuthToken(); } else { throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CouldNotSaveNewPassword); } return $mResult; }
/** * @param string $sFileName * @param string $sFileHeader = '' * * @return void */ public function __construct($sFileName, $sFileHeader = '') { $this->sFile = \APP_PRIVATE_DATA . 'configs/' . $sFileName; $this->sFileHeader = $sFileHeader; $this->aData = $this->defaultValues(); $this->bUseApcCache = APP_USE_APC_CACHE && \MailSo\Base\Utils::FunctionExistsAndEnabled(array('apc_fetch', 'apc_store')); }
/** * @return bool */ public function Connect() { $sHost = $this->bUseSsl ? 'ssl://' . $this->sHost : $this->sHost; if ($this->IsConnected()) { CApi::Log('already connected[' . $sHost . ':' . $this->iPort . ']: result = false', ELogLevel::Error); $this->Disconnect(); return false; } $sErrorStr = ''; $iErrorNo = 0; CApi::Log('start connect to ' . $sHost . ':' . $this->iPort); $this->rConnect = @fsockopen($sHost, $this->iPort, $iErrorNo, $sErrorStr, $this->iConnectTimeOut); if (!$this->IsConnected()) { CApi::Log('connection error[' . $sHost . ':' . $this->iPort . ']: fsockopen = false (' . $iErrorNo . ': ' . $sErrorStr . ')', ELogLevel::Error); return false; } else { CApi::Log('connected'); } if (\MailSo\Base\Utils::FunctionExistsAndEnabled('stream_set_timeout')) { @stream_set_timeout($this->rConnect, $this->iSocketTimeOut); } if (\MailSo\Base\Utils::FunctionExistsAndEnabled('@stream_set_blocking')) { @stream_set_blocking($this->rConnect, true); } return true; }
/** * @param int $iTimeToClearInHours = 24 * * @return bool */ public function GC($iTimeToClearInHours = 24) { if (0 < $iTimeToClearInHours) { \MailSo\Base\Utils::RecTimeDirRemove($this->sCacheFolder, 60 * 60 * $iTimeToClearInHours, \time()); return true; } return false; }
/** * @access protected * * @param string $sEmailAddresses = '' */ protected function __construct($sEmailAddresses = '') { parent::__construct(); $sEmailAddresses = \MailSo\Base\Utils::Trim($sEmailAddresses); if (0 < \strlen($sEmailAddresses)) { $this->parseEmailAddresses($sEmailAddresses); } }
/** * This function detects the SMTP Host, and if it is set to "auto", replaces it with the email domain. * * @param \RainLoop\Model\Account $oAccount * @param array $aSmtpCredentials */ public function FilterSmtpCredentials($oAccount, &$aSmtpCredentials) { if ($oAccount instanceof \RainLoop\Model\Account && \is_array($aSmtpCredentials)) { // Check for mail.$DOMAIN as entered value in RL settings if (!empty($aSmtpCredentials['Host']) && 'auto' === $aSmtpCredentials['Host']) { $aSmtpCredentials['Host'] = \MailSo\Base\Utils::GetDomainFromEmail($oAccount->Email()); } } }
/** * @param array $aSubStreams * * @return resource|bool */ public static function CreateStream($aSubStreams) { if (!\in_array(self::STREAM_NAME, \stream_get_wrappers())) { \stream_wrapper_register(self::STREAM_NAME, '\\MailSo\\Base\\StreamWrappers\\SubStreams'); } $sHashName = \MailSo\Base\Utils::Md5Rand(); self::$aStreams[$sHashName] = $aSubStreams; \MailSo\Base\Loader::IncStatistic('CreateStream/SubStreams'); return \fopen(self::STREAM_NAME . '://' . $sHashName, 'rb'); }
/** * @param string $sFileName * @param string $sFileHeader = '' * @param string $sAdditionalFileName = '' * * @return void */ public function __construct($sFileName, $sFileHeader = '', $sAdditionalFileName = '') { $this->sFile = \APP_PRIVATE_DATA . 'configs/' . \trim($sFileName); $sAdditionalFileName = \trim($sAdditionalFileName); $this->sAdditionalFile = \APP_PRIVATE_DATA . 'configs/' . $sAdditionalFileName; $this->sAdditionalFile = 0 < \strlen($sAdditionalFileName) && \file_exists($this->sAdditionalFile) ? $this->sAdditionalFile : ''; $this->sFileHeader = $sFileHeader; $this->aData = $this->defaultValues(); $this->bUseApcCache = APP_USE_APC_CACHE && \MailSo\Base\Utils::FunctionExistsAndEnabled(array('apc_fetch', 'apc_store')); }
/** * @param array $oItem * @param array $aPics * * @return array|null */ private function convertGoogleJsonContactToResponseContact($oItem, &$aPics) { $mResult = null; if (!empty($oItem['gd$email'][0]['address'])) { $mEmail = \MailSo\Base\Utils::IdnToAscii($oItem['gd$email'][0]['address'], true); if (\is_array($oItem['gd$email']) && 1 < \count($oItem['gd$email'])) { $mEmail = array(); foreach ($oItem['gd$email'] as $oEmail) { if (!empty($oEmail['address'])) { $mEmail[] = \MailSo\Base\Utils::IdnToAscii($oEmail['address'], true); } } } $sImg = ''; if (!empty($oItem['link']) && \is_array($oItem['link'])) { foreach ($oItem['link'] as $oLink) { if ($oLink && isset($oLink['type'], $oLink['href'], $oLink['rel']) && 'image/*' === $oLink['type'] && '#photo' === \substr($oLink['rel'], -6)) { $sImg = $oLink['href']; break; } } } $mResult = array('email' => $mEmail, 'name' => !empty($oItem['title']['$t']) ? $oItem['title']['$t'] : ''); if (0 < \strlen($sImg)) { $sHash = \RainLoop\Utils::EncodeKeyValues(array('url' => $sImg, 'type' => 'google_access_token')); $mData = array(); if (isset($aPics[$sHash])) { $mData = $aPics[$sHash]; if (!\is_array($mData)) { $mData = array($mData); } } if (\is_array($mEmail)) { $mData = \array_merge($mData, $mEmail); $mData = \array_unique($mData); } else { if (0 < \strlen($mEmail)) { $mData[] = $mEmail; } } if (\is_array($mData)) { if (1 === \count($mData) && !empty($mData[0])) { $aPics[$sHash] = $mData[0]; } else { if (1 < \count($mData)) { $aPics[$sHash] = $mData; } } } } } return $mResult; }
/** * @param \CAccount $oAccount * @param int $iStorageType * @param string $sKey * @param resource $rSource * * @return bool */ public function PutFile(\CAccount $oAccount, $iStorageType, $sKey, $rSource) { $bResult = false; if ($rSource) { $rOpenOutput = @fopen($this->generateFileName($oAccount, $iStorageType, $sKey, true), 'w+b'); if ($rOpenOutput) { $bResult = false !== \MailSo\Base\Utils::MultipleStreamWriter($rSource, array($rOpenOutput)); @fclose($rOpenOutput); } } return $bResult; }
/** * @param string $sText * @param string $sHtmlAttrs = '' * @param string $sBodyAttrs = '' * * @return \DOMDocument|bool */ public static function GetDomFromText($sText, $sHtmlAttrs = '', $sBodyAttrs = '') { static $bOnce = true; if ($bOnce) { $bOnce = false; if (\MailSo\Base\Utils::FunctionExistsAndEnabled('libxml_use_internal_errors')) { @\libxml_use_internal_errors(true); } } $oDom = new \DOMDocument('1.0', 'utf-8'); $oDom->encoding = 'UTF-8'; $oDom->formatOutput = false; @$oDom->loadHTML('<' . '?xml version="1.0" encoding="utf-8"?' . '>' . '<html ' . $sHtmlAttrs . '><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body ' . $sBodyAttrs . '>' . $sText . '</body></html>'); return $oDom; }
/** * @return array|null */ public static function Statistic() { $aResult = null; if (self::$StoreStatistic) { $aResult = array('php' => array('phpversion' => PHP_VERSION, 'ssl' => (int) \function_exists('openssl_open'), 'iconv' => (int) \function_exists('iconv'))); if (\MailSo\Base\Utils::FunctionExistsAndEnabled('memory_get_usage') && \MailSo\Base\Utils::FunctionExistsAndEnabled('memory_get_peak_usage')) { $aResult['php']['memory_get_usage'] = Utils::FormatFileSize(\memory_get_usage(true), 2); $aResult['php']['memory_get_peak_usage'] = Utils::FormatFileSize(\memory_get_peak_usage(true), 2); } self::SetStatistic('TimeDelta', \microtime(true) - self::GetStatistic('Inited')); $aResult['statistic'] = self::$aSetStatistic; $aResult['counts'] = self::$aIncStatistic; } return $aResult; }
/** * @param int $iIndex * @param string $sParentCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1 * * @return \MailSo\Mime\EmailCollection|null */ public function GetFetchEnvelopeEmailCollection($iIndex, $sParentCharset = \MailSo\Base\Enumerations\Charset::ISO_8859_1) { $oResult = null; $aEmails = $this->GetFetchEnvelopeValue($iIndex, null); if (is_array($aEmails) && 0 < count($aEmails)) { $oResult = \MailSo\Mime\EmailCollection::NewInstance(); foreach ($aEmails as $aEmailItem) { if (is_array($aEmailItem) && 4 === count($aEmailItem)) { $sDisplayName = \MailSo\Base\Utils::DecodeHeaderValue(self::findEnvelopeIndex($aEmailItem, 0, ''), $sParentCharset); $sRemark = \MailSo\Base\Utils::DecodeHeaderValue(self::findEnvelopeIndex($aEmailItem, 1, ''), $sParentCharset); $sLocalPart = self::findEnvelopeIndex($aEmailItem, 2, ''); $sDomainPart = self::findEnvelopeIndex($aEmailItem, 3, ''); if (0 < strlen($sLocalPart) && 0 < strlen($sDomainPart)) { $oResult->Add(\MailSo\Mime\Email::NewInstance($sLocalPart . '@' . $sDomainPart, $sDisplayName, $sRemark)); } } } } return $oResult; }
/** * @param \RainLoop\Account $oAccount * @param string $sPrevPassword * @param string $sNewPassword * * @return bool */ public function ChangePassword(\RainLoop\Account $oAccount, $sPrevPassword, $sNewPassword) { if ($this->oLogger) { $this->oLogger->Write('DirectAdmin: Try to change password for ' . $oAccount->Email()); } $bResult = false; if (!empty($this->sHost) && 0 < $this->iPort && $oAccount) { $sEmail = \trim(\strtolower($oAccount->Email())); $sHost = \trim($this->sHost); $sHost = \str_replace('{user:host-imap}', $oAccount->Domain()->IncHost(), $sHost); $sHost = \str_replace('{user:host-smtp}', $oAccount->Domain()->OutHost(), $sHost); $sHost = \str_replace('{user:domain}', \MailSo\Base\Utils::GetDomainFromEmail($sEmail), $sHost); $sHost = \rtrim($this->sHost, '/\\'); if (!\preg_match('/^http[s]?:\\/\\//i', $sHost)) { $sHost = 'http://' . $sHost; } $sUrl = $sHost . ':' . $this->iPort . '/CMD_CHANGE_EMAIL_PASSWORD'; $iCode = 0; $oHttp = \MailSo\Base\Http::SingletonInstance(); if ($this->oLogger) { $this->oLogger->Write('DirectAdmin[Api Request]:' . $sUrl); } $mResult = $oHttp->SendPostRequest($sUrl, array('email' => $sEmail, 'oldpassword' => $sPrevPassword, 'password1' => $sNewPassword, 'password2' => $sNewPassword, 'api' => '1'), 'MailSo Http User Agent (v1)', $iCode, $this->oLogger); if (false !== $mResult && 200 === $iCode) { $aRes = null; @\parse_str($mResult, $aRes); if (is_array($aRes) && (!isset($aRes['error']) || (int) $aRes['error'] !== 1)) { $bResult = true; } else { if ($this->oLogger) { $this->oLogger->Write('DirectAdmin[Error]: Response: ' . $mResult); } } } else { if ($this->oLogger) { $this->oLogger->Write('DirectAdmin[Error]: Empty Response: Code:' . $iCode); } } } return $bResult; }
/** * @param string $sPrevFolderFullNameRaw * @param string $sNextFolderNameInUtf * @param bool $bRenameOrMove * @param bool $bSubscribeOnModify * * @return \MailSo\Mail\MailClient * * @throws \MailSo\Base\Exceptions\InvalidArgumentException */ public function folderModify($sPrevFolderFullNameRaw, $sNextFolderNameInUtf, $bRenameOrMove, $bSubscribeOnModify) { if (0 === \strlen($sPrevFolderFullNameRaw) || 0 === \strlen($sNextFolderNameInUtf)) { throw new \MailSo\Base\Exceptions\InvalidArgumentException(); } $aFolders = $this->oImapClient->FolderList('', $sPrevFolderFullNameRaw); if (!\is_array($aFolders) || !isset($aFolders[0])) { // TODO throw new \MailSo\Mail\Exceptions\RuntimeException('Cannot rename non-existen folder'); } $sDelimiter = $aFolders[0]->Delimiter(); $iLast = \strrpos($sPrevFolderFullNameRaw, $sDelimiter); $mSubscribeFolders = null; if ($bSubscribeOnModify) { $mSubscribeFolders = $this->oImapClient->FolderSubscribeList($sPrevFolderFullNameRaw, '*'); if (\is_array($mSubscribeFolders) && 0 < count($mSubscribeFolders)) { foreach ($mSubscribeFolders as $oFolder) { $this->oImapClient->FolderUnSubscribe($oFolder->FullNameRaw()); } } } $sNewFolderFullNameRaw = \MailSo\Base\Utils::ConvertEncoding($sNextFolderNameInUtf, \MailSo\Base\Enumerations\Charset::UTF_8, \MailSo\Base\Enumerations\Charset::UTF_7_IMAP); if ($bRenameOrMove) { if (0 < \strlen($sDelimiter) && false !== \strpos($sNewFolderFullNameRaw, $sDelimiter)) { // TODO throw new \MailSo\Mail\Exceptions\RuntimeException('New folder name contain delimiter'); } $sFolderParentFullNameRaw = false === $iLast ? '' : \substr($sPrevFolderFullNameRaw, 0, $iLast + 1); $sNewFolderFullNameRaw = $sFolderParentFullNameRaw . $sNewFolderFullNameRaw; } $this->oImapClient->FolderRename($sPrevFolderFullNameRaw, $sNewFolderFullNameRaw); if (\is_array($mSubscribeFolders) && 0 < count($mSubscribeFolders)) { foreach ($mSubscribeFolders as $oFolder) { $sFolderFullNameRawForResubscrine = $oFolder->FullNameRaw(); if (0 === \strpos($sFolderFullNameRawForResubscrine, $sPrevFolderFullNameRaw)) { $sNewFolderFullNameRawForResubscrine = $sNewFolderFullNameRaw . \substr($sFolderFullNameRawForResubscrine, \strlen($sPrevFolderFullNameRaw)); $this->oImapClient->FolderSubscribe($sNewFolderFullNameRawForResubscrine); } } } return $this; }
/** * @param string $sParent * @param string $sLiteralAtomUpperCase * @param resource $rImapStream * @param int $iLiteralLen * * @return bool */ private function partialResponseLiteralCallbackCallable($sParent, $sLiteralAtomUpperCase, $rImapStream, $iLiteralLen) { $sLiteralAtomUpperCasePeek = ''; if (0 === \strpos($sLiteralAtomUpperCase, 'BODY')) { $sLiteralAtomUpperCasePeek = \str_replace('BODY', 'BODY.PEEK', $sLiteralAtomUpperCase); } $sFetchKey = ''; if (\is_array($this->aFetchCallbacks)) { if (0 < \strlen($sLiteralAtomUpperCasePeek) && isset($this->aFetchCallbacks[$sLiteralAtomUpperCasePeek])) { $sFetchKey = $sLiteralAtomUpperCasePeek; } else { if (0 < \strlen($sLiteralAtomUpperCase) && isset($this->aFetchCallbacks[$sLiteralAtomUpperCase])) { $sFetchKey = $sLiteralAtomUpperCase; } } } $bResult = false; if (0 < \strlen($sFetchKey) && '' !== $this->aFetchCallbacks[$sFetchKey] && \is_callable($this->aFetchCallbacks[$sFetchKey])) { $rImapLiteralStream = \MailSo\Base\StreamWrappers\Literal::CreateStream($rImapStream, $iLiteralLen); $bResult = true; $this->writeLog('Start Callback for ' . $sParent . ' / ' . $sLiteralAtomUpperCase . ' - try to read ' . $iLiteralLen . ' bytes.', \MailSo\Log\Enumerations\Type::NOTE); $this->bRunningCallback = true; try { \call_user_func($this->aFetchCallbacks[$sFetchKey], $sParent, $sLiteralAtomUpperCase, $rImapLiteralStream); } catch (\Exception $oException) { $this->writeLog('Callback Exception', \MailSo\Log\Enumerations\Type::NOTICE); $this->writeLogException($oException); } if (\is_resource($rImapLiteralStream)) { $iNotReadLiteralLen = 0; $bFeof = \feof($rImapLiteralStream); $this->writeLog('End Callback for ' . $sParent . ' / ' . $sLiteralAtomUpperCase . ' - feof = ' . ($bFeof ? 'good' : 'BAD'), $bFeof ? \MailSo\Log\Enumerations\Type::NOTE : \MailSo\Log\Enumerations\Type::WARNING); if (!$bFeof) { while (!@\feof($rImapLiteralStream)) { $sBuf = @\fread($rImapLiteralStream, 1024 * 1024); if (false === $sBuf || 0 === \strlen($sBuf) || null === $sBuf) { break; } \MailSo\Base\Utils::ResetTimeLimit(); $iNotReadLiteralLen += \strlen($sBuf); } if (\is_resource($rImapLiteralStream) && !@\feof($rImapLiteralStream)) { @\stream_get_contents($rImapLiteralStream); } } if (\is_resource($rImapLiteralStream)) { @\fclose($rImapLiteralStream); } if ($iNotReadLiteralLen > 0) { $this->writeLog('Not read literal size is ' . $iNotReadLiteralLen . ' bytes.', \MailSo\Log\Enumerations\Type::WARNING); } } else { $this->writeLog('Literal stream is not resource after callback.', \MailSo\Log\Enumerations\Type::WARNING); } \MailSo\Base\Loader::IncStatistic('NetRead', $iLiteralLen); $this->bRunningCallback = false; } return $bResult; }
/** * @param string $sStr * @param bool $bLowerIfAscii = false * * @return string */ public static function IdnToAscii($sStr, $bLowerIfAscii = false) { $sStr = $bLowerIfAscii ? \MailSo\Base\Utils::StrToLowerIfAscii($sStr) : $sStr; $sUser = ''; $sDomain = $sStr; if (false !== \strpos($sStr, '@')) { $sUser = \MailSo\Base\Utils::GetAccountNameFromEmail($sStr); $sDomain = \MailSo\Base\Utils::GetDomainFromEmail($sStr); } if (0 < \strlen($sDomain) && \preg_match('/[^\\x20-\\x7E]/', $sDomain)) { try { $sDomain = self::idn()->encode($sDomain); } catch (\Exception $oException) { } } return ('' === $sUser ? '' : $sUser . '@') . $sDomain; }
/** * @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); }
/** * @return string */ public function ValueWithCharsetAutoDetect() { $sValue = $this->Value(); if (!\MailSo\Base\Utils::IsAscii($sValue) && 0 < \strlen($this->sEncodedValueForReparse) && !\MailSo\Base\Utils::IsAscii($this->sEncodedValueForReparse)) { $sValueCharset = \MailSo\Base\Utils::CharsetDetect($this->sEncodedValueForReparse); if (0 < \strlen($sValueCharset)) { $this->SetParentCharset($sValueCharset); $sValue = $this->Value(); } } return $sValue; }
/** * @return void */ private function reParseParameters() { $aDataToReParse = $this->CloneAsArray(); $sCharset = \MailSo\Base\Enumerations\Charset::UTF_8; $this->clear(); $aPreParams = array(); foreach ($aDataToReParse as $oParam) { $aMatch = array(); $sParamName = $oParam->Name(); if (preg_match('/([^\\*]+)\\*([\\d]{1,2})\\*/', $sParamName, $aMatch) && isset($aMatch[1], $aMatch[2]) && 0 < strlen($aMatch[1]) && is_numeric($aMatch[2])) { if (!isset($aPreParams[$aMatch[1]])) { $aPreParams[$aMatch[1]] = array(); } $sValue = $oParam->Value(); $aValueParts = explode('\'\'', $sValue, 2); if (is_array($aValueParts) && 2 === count($aValueParts) && 0 < strlen($aValueParts[1])) { $sCharset = $aValueParts[0]; $sValue = $aValueParts[1]; } $aPreParams[$aMatch[1]][(int) $aMatch[2]] = $sValue; } else { if (preg_match('/([^\\*]+)\\*/', $sParamName, $aMatch) && isset($aMatch[1])) { if (!isset($aPreParams[$aMatch[1]])) { $aPreParams[$aMatch[1]] = array(); } $sValue = $oParam->Value(); $aValueParts = explode('\'\'', $sValue, 2); if (is_array($aValueParts) && 2 === count($aValueParts) && 0 < strlen($aValueParts[1])) { $sCharset = $aValueParts[0]; $sValue = $aValueParts[1]; } $aPreParams[$aMatch[1]][0] = $sValue; } else { $this->Add($oParam); } } } foreach ($aPreParams as $sName => $aValues) { ksort($aValues); $sResult = implode(array_values($aValues)); $sResult = urldecode($sResult); if (0 < strlen($sCharset)) { $sResult = \MailSo\Base\Utils::ConvertEncoding($sResult, $sCharset, \MailSo\Base\Enumerations\Charset::UTF_8); } $this->Add(Parameter::NewInstance($sName, $sResult)); } }
/** * @param array $aBodyStructure * @param string $sPartID = '' * * @return \MailSo\Imap\BodyStructure */ public static function NewInstance(array $aBodyStructure, $sPartID = '') { if (!\is_array($aBodyStructure) || 2 > \count($aBodyStructure)) { return null; } else { $sBodyMainType = null; if (\is_string($aBodyStructure[0]) && 'NIL' !== $aBodyStructure[0]) { $sBodyMainType = $aBodyStructure[0]; } $sBodySubType = null; $sContentType = ''; $aSubParts = null; $aBodyParams = array(); $sName = null; $sCharset = null; $sContentID = null; $sDescription = null; $sMailEncodingName = null; $iSize = 0; $iTextLineCount = 0; // valid for rfc822/message and text parts $iExtraItemPos = 0; // list index of items which have no well-established position (such as 0, 1, 5, etc). if (null === $sBodyMainType) { // Process multipart body structure if (!\is_array($aBodyStructure[0])) { return null; } else { $sBodyMainType = 'multipart'; $sSubPartIDPrefix = ''; if (0 === \strlen($sPartID) || '.' === $sPartID[\strlen($sPartID) - 1]) { // This multi-part is root part of message. $sSubPartIDPrefix = $sPartID; $sPartID .= 'TEXT'; } else { if (0 < \strlen($sPartID)) { // This multi-part is a part of another multi-part. $sSubPartIDPrefix = $sPartID . '.'; } } $aSubParts = array(); $iIndex = 1; while ($iExtraItemPos < \count($aBodyStructure) && \is_array($aBodyStructure[$iExtraItemPos])) { $oPart = self::NewInstance($aBodyStructure[$iExtraItemPos], $sSubPartIDPrefix . $iIndex); if (null === $oPart) { return null; } else { // For multipart, we have no charset info in the part itself. Thus, // obtain charset from nested parts. if ($sCharset == null) { $sCharset = $oPart->Charset(); } $aSubParts[] = $oPart; $iExtraItemPos++; $iIndex++; } } } if ($iExtraItemPos < \count($aBodyStructure)) { if (!\is_string($aBodyStructure[$iExtraItemPos]) || 'NIL' === $aBodyStructure[$iExtraItemPos]) { return null; } $sBodySubType = \strtolower($aBodyStructure[$iExtraItemPos]); $iExtraItemPos++; } if ($iExtraItemPos < \count($aBodyStructure)) { $sBodyParamList = $aBodyStructure[$iExtraItemPos]; if (\is_array($sBodyParamList)) { $aBodyParams = self::getKeyValueListFromArrayList($sBodyParamList); } } $iExtraItemPos++; } else { // Process simple (singlepart) body structure if (7 > \count($aBodyStructure)) { return null; } $sBodyMainType = \strtolower($sBodyMainType); if (!\is_string($aBodyStructure[1]) || 'NIL' === $aBodyStructure[1]) { return null; } $sBodySubType = \strtolower($aBodyStructure[1]); $aBodyParamList = $aBodyStructure[2]; if (\is_array($aBodyParamList)) { $aBodyParams = self::getKeyValueListFromArrayList($aBodyParamList); if (isset($aBodyParams['charset'])) { $sCharset = $aBodyParams['charset']; } if (\is_array($aBodyParams)) { $sName = self::decodeAttrParamenter($aBodyParams, 'name', $sContentType); } } if (null !== $aBodyStructure[3] && 'NIL' !== $aBodyStructure[3]) { if (!\is_string($aBodyStructure[3])) { return null; } $sContentID = $aBodyStructure[3]; } if (null !== $aBodyStructure[4] && 'NIL' !== $aBodyStructure[4]) { if (!\is_string($aBodyStructure[4])) { return null; } $sDescription = $aBodyStructure[4]; } if (null !== $aBodyStructure[5] && 'NIL' !== $aBodyStructure[5]) { if (!\is_string($aBodyStructure[5])) { return null; } $sMailEncodingName = $aBodyStructure[5]; } if (\is_numeric($aBodyStructure[6])) { $iSize = (int) $aBodyStructure[6]; } else { $iSize = -1; } if (0 === \strlen($sPartID) || '.' === $sPartID[\strlen($sPartID) - 1]) { // This is the only sub-part of the message (otherwise, it would be // one of sub-parts of a multi-part, and partID would already be fully set up). $sPartID .= '1'; } $iExtraItemPos = 7; if ('text' === $sBodyMainType) { if ($iExtraItemPos < \count($aBodyStructure)) { if (\is_numeric($aBodyStructure[$iExtraItemPos])) { $iTextLineCount = (int) $aBodyStructure[$iExtraItemPos]; } else { $iTextLineCount = -1; } } else { $iTextLineCount = -1; } $iExtraItemPos++; } else { if ('message' === $sBodyMainType && 'rfc822' === $sBodySubType) { if ($iExtraItemPos + 2 < \count($aBodyStructure)) { if (\is_numeric($aBodyStructure[$iExtraItemPos + 2])) { $iTextLineCount = (int) $aBodyStructure[$iExtraItemPos + 2]; } else { $iTextLineCount = -1; } } else { $iTextLineCount = -1; } $iExtraItemPos += 3; } } $iExtraItemPos++; // skip MD5 digest of the body because most mail servers leave it NIL anyway } $sContentType = $sBodyMainType . '/' . $sBodySubType; $sDisposition = null; $aDispositionParams = null; $sFileName = null; if ($iExtraItemPos < \count($aBodyStructure)) { $aDispList = $aBodyStructure[$iExtraItemPos]; if (\is_array($aDispList) && 1 < \count($aDispList)) { if (null !== $aDispList[0]) { if (\is_string($aDispList[0]) && 'NIL' !== $aDispList[0]) { $sDisposition = $aDispList[0]; } else { return null; } } } $aDispParamList = $aDispList[1]; if (\is_array($aDispParamList)) { $aDispositionParams = self::getKeyValueListFromArrayList($aDispParamList); if (\is_array($aDispositionParams)) { $sFileName = self::decodeAttrParamenter($aDispositionParams, 'filename', $sCharset); } } } $iExtraItemPos++; $sLanguage = null; if ($iExtraItemPos < count($aBodyStructure)) { if (null !== $aBodyStructure[$iExtraItemPos] && 'NIL' !== $aBodyStructure[$iExtraItemPos]) { if (\is_array($aBodyStructure[$iExtraItemPos])) { $sLanguage = \implode(',', $aBodyStructure[$iExtraItemPos]); } else { if (\is_string($aBodyStructure[$iExtraItemPos])) { $sLanguage = $aBodyStructure[$iExtraItemPos]; } } } $iExtraItemPos++; } $sLocation = null; if ($iExtraItemPos < \count($aBodyStructure)) { if (null !== $aBodyStructure[$iExtraItemPos] && 'NIL' !== $aBodyStructure[$iExtraItemPos]) { if (\is_string($aBodyStructure[$iExtraItemPos])) { $sLocation = $aBodyStructure[$iExtraItemPos]; } } $iExtraItemPos++; } return new self($sContentType, $sCharset, $aBodyParams, $sContentID, $sDescription, $sMailEncodingName, $sDisposition, $aDispositionParams, \MailSo\Base\Utils::Utf8Clear(null === $sFileName || 0 === \strlen($sFileName) ? $sName : $sFileName), $sLanguage, $sLocation, $iSize, $iTextLineCount, $sPartID, $aSubParts); } }
/** * @return array|bool */ public function StreamContextParams() { return \is_resource($this->rConnect) && \MailSo\Base\Utils::FunctionExistsAndEnabled('stream_context_get_options') ? \stream_context_get_params($this->rConnect) : false; }
/** * @return bool */ public function IsDoc() { return 'doc' === \MailSo\Base\Utils::ContentTypeType($this->ContentType(), $this->FileName()); }
/** * @param string $sEncodedValues * @param string $sCustomKey = '' * * @return array */ public static function DecodeKeyValues($sEncodedValues, $sCustomKey = '') { $aResult = \unserialize(\RainLoop\Utils::DecryptString(\MailSo\Base\Utils::UrlSafeBase64Decode($sEncodedValues), \md5(APP_SALT . $sCustomKey))); return \is_array($aResult) ? $aResult : array(); }
/** * @param bool $bAdmin = false * @param bool $bJsOutput = true * * @return string */ public function compileTemplates($bAdmin = false, $bJsOutput = true) { $aTemplates = array(); \RainLoop\Utils::CompileTemplates($aTemplates, APP_VERSION_ROOT_PATH . 'app/templates/Views/Components', 'Component'); \RainLoop\Utils::CompileTemplates($aTemplates, APP_VERSION_ROOT_PATH . 'app/templates/Views/' . ($bAdmin ? 'Admin' : 'User')); \RainLoop\Utils::CompileTemplates($aTemplates, APP_VERSION_ROOT_PATH . 'app/templates/Views/Common'); $this->oActions->Plugins()->CompileTemplate($aTemplates, $bAdmin); $sHtml = ''; foreach ($aTemplates as $sName => $sFile) { $sName = \preg_replace('/[^a-zA-Z0-9]/', '', $sName); $sHtml .= '<script id="' . $sName . '" type="text/html" data-cfasync="false">' . $this->oActions->ProcessTemplate($sName, \file_get_contents($sFile)) . '</script>'; } unset($aTemplates); return $bJsOutput ? 'window.rainloopTEMPLATES=' . \MailSo\Base\Utils::Php2js(array($sHtml), $this->Logger()) . ';' : $sHtml; }
/** * @param string $sEmail * @param bool $bSkipInsert = false * @param bool $bCache = true * * @return int */ protected function getUserId($sEmail, $bSkipInsert = false, $bCache = true) { static $aCache = array(); if ($bCache && isset($aCache[$sEmail])) { return $aCache[$sEmail]; } $sEmail = \MailSo\Base\Utils::IdnToAscii(\trim($sEmail), true); if (empty($sEmail)) { throw new \InvalidArgumentException('Empty Email argument'); } $oStmt = $this->prepareAndExecute('SELECT id_user FROM rainloop_users WHERE rl_email = :rl_email', array(':rl_email' => array($sEmail, \PDO::PARAM_STR))); $mRow = $oStmt->fetch(\PDO::FETCH_ASSOC); if ($mRow && isset($mRow['id_user']) && \is_numeric($mRow['id_user'])) { $iResult = (int) $mRow['id_user']; if (0 >= $iResult) { throw new \Exception('id_user <= 0'); } if ($bCache) { $aCache[$sEmail] = $iResult; } return $iResult; } if (!$bSkipInsert) { $oStmt->closeCursor(); $oStmt = $this->prepareAndExecute('INSERT INTO rainloop_users (rl_email) VALUES (:rl_email)', array(':rl_email' => array($sEmail, \PDO::PARAM_STR))); return $this->getUserId($sEmail, true); } throw new \Exception('id_user = 0'); }
/** * @return array */ public function UploadHelpdeskFile() { $oAccount = null; $oUser = $this->getHelpdeskAccountFromParam($oAccount); if (!$this->oApiCapability->isHelpdeskSupported() || !$this->oApiCapability->isFilesSupported()) { throw new \ProjectCore\Exceptions\ClientException(\ProjectCore\Notifications::AccessDenied); } $aFileData = $this->getParamValue('FileData', null); $iSizeLimit = 0; $sError = ''; $aResponse = array(); if ($oUser) { if (is_array($aFileData)) { if (0 < $iSizeLimit && $iSizeLimit < (int) $aFileData['size']) { $sError = 'size'; } else { $sSavedName = 'upload-post-' . md5($aFileData['name'] . $aFileData['tmp_name']); if ($this->ApiFileCache()->moveUploadedFile($oUser, $sSavedName, $aFileData['tmp_name'])) { $sUploadName = $aFileData['name']; $iSize = $aFileData['size']; $sMimeType = \MailSo\Base\Utils::MimeContentType($sUploadName); $aResponse['HelpdeskFile'] = array('Name' => $sUploadName, 'TempName' => $sSavedName, 'MimeType' => $sMimeType, 'Size' => (int) $iSize, 'Hash' => \CApi::EncodeKeyValues(array('TempFile' => true, 'HelpdeskTenantID' => $oUser->IdTenant, 'HelpdeskUserID' => $oUser->IdHelpdeskUser, 'Name' => $sUploadName, 'TempName' => $sSavedName))); } else { $sError = 'unknown'; } } } else { $sError = 'unknown'; } } else { $sError = 'auth'; } if (0 < strlen($sError)) { $aResponse['Error'] = $sError; } return $this->DefaultResponse($oAccount, __FUNCTION__, $aResponse); }