mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
A lot small fixes
This commit is contained in:
parent
4457cdbc23
commit
09334159c2
38 changed files with 1496 additions and 239 deletions
|
|
@ -126,7 +126,7 @@ class HtmlUtils
|
|||
{
|
||||
$aRemoveTags = array(
|
||||
'link', 'base', 'meta', 'title', 'script', 'bgsound', 'keygen', 'source',
|
||||
'object', 'embed', 'applet', 'mocha', 'iframe', 'frame', 'frameset', 'video', 'audio'
|
||||
'object', 'embed', 'applet', 'mocha', 'iframe', 'frame', 'frameset', 'video', 'audio', 'area', 'map'
|
||||
);
|
||||
|
||||
if ($bClearStyleAndHead)
|
||||
|
|
@ -755,7 +755,8 @@ class HtmlUtils
|
|||
|
||||
if ('' !== $sTagNameLower && \in_array($sTagNameLower, array('svg', 'head', 'link',
|
||||
'base', 'meta', 'title', 'style', 'x-script', 'script', 'bgsound', 'keygen', 'source',
|
||||
'object', 'embed', 'applet', 'mocha', 'iframe', 'frame', 'frameset', 'video', 'audio')))
|
||||
'object', 'embed', 'applet', 'mocha', 'iframe', 'frame', 'frameset',
|
||||
'video', 'audio', 'area', 'map')))
|
||||
{
|
||||
if (isset($oElement->parentNode))
|
||||
{
|
||||
|
|
@ -867,7 +868,8 @@ class HtmlUtils
|
|||
foreach (array(
|
||||
'id', 'class',
|
||||
'contenteditable', 'designmode', 'formaction',
|
||||
'data-bind', 'data-reactid', 'xmlns', 'srcset'
|
||||
'data-bind', 'data-reactid', 'xmlns', 'srcset',
|
||||
'data-x-skip-style'
|
||||
) as $sAttr)
|
||||
{
|
||||
@$oElement->removeAttribute($sAttr);
|
||||
|
|
@ -903,27 +905,50 @@ class HtmlUtils
|
|||
$sAlt = $oElement->hasAttribute('alt')
|
||||
? \trim($oElement->getAttribute('alt')) : '';
|
||||
|
||||
$sH = $oElement->hasAttribute('height')
|
||||
? \trim($oElement->getAttribute('height')) : '';
|
||||
|
||||
$sW = $oElement->hasAttribute('width')
|
||||
? \trim($oElement->getAttribute('width')) : '';
|
||||
|
||||
$sStyles = $oElement->hasAttribute('style')
|
||||
? \trim(\trim(\trim($oElement->getAttribute('style')), ';')) : '';
|
||||
|
||||
if ($oElement->hasAttribute('src'))
|
||||
if ($oElement->hasAttribute('src') && '' === $sAlt)
|
||||
{
|
||||
$aValues = array('4', '3', '2', '1', '0', '4px', '3px', '2px', '1px', '0px');
|
||||
if (('' === $sAlt && \in_array($sH, $aValues) && \in_array($sW, $aValues)) ||
|
||||
\preg_match('/(display:none|visibility:hidden)/i', \preg_replace('/[\s]+/', '', $sStyles)))
|
||||
$aH = array(
|
||||
'email.microsoftemail.com/open',
|
||||
'github.com/notifications/beacon/',
|
||||
'mandrillapp.com/track/open',
|
||||
'list-manage.com/track/open'
|
||||
);
|
||||
|
||||
$sH = $oElement->hasAttribute('height')
|
||||
? \trim($oElement->getAttribute('height')) : '';
|
||||
|
||||
// $sW = $oElement->hasAttribute('width')
|
||||
// ? \trim($oElement->getAttribute('width')) : '';
|
||||
|
||||
$sStyles = $oElement->hasAttribute('style')
|
||||
? \preg_replace('/[\s]+/', '', \trim(\trim(\trim($oElement->getAttribute('style')), ';'))) : '';
|
||||
|
||||
$sSrc = \trim($oElement->getAttribute('src'));
|
||||
|
||||
$bC = \in_array($sH, array('1', '0', '1px', '0px')) ||
|
||||
\preg_match('/(display:none|visibility:hidden|height:0|height:[01][a-z][a-z])/i', $sStyles);
|
||||
|
||||
if (!$bC)
|
||||
{
|
||||
if (isset($oElement->parentNode))
|
||||
$sSrcLower = \strtolower($sSrc);
|
||||
foreach ($aH as $sLine)
|
||||
{
|
||||
@$oElement->parentNode->removeChild($oElement);
|
||||
continue;
|
||||
if (false !== \strpos($sSrcLower, $sLine))
|
||||
{
|
||||
$bC = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($bC)
|
||||
{
|
||||
$oElement->setAttribute('style', 'display:none');
|
||||
$oElement->setAttribute('data-x-skip-style', 'true');
|
||||
$oElement->setAttribute('data-x-hidden-src', $sSrc);
|
||||
|
||||
$oElement->removeAttribute('src');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1002,12 +1027,14 @@ class HtmlUtils
|
|||
$oElement->setAttribute('style', (empty($sStyles) ? '' : $sStyles.'; ').\implode('; ', $aStyles));
|
||||
}
|
||||
|
||||
if ($oElement->hasAttribute('style'))
|
||||
if ($oElement->hasAttribute('style') && !$oElement->hasAttribute('data-x-skip-style'))
|
||||
{
|
||||
$oElement->setAttribute('style',
|
||||
\MailSo\Base\HtmlUtils::ClearStyle($oElement->getAttribute('style'), $oElement, $bHasExternals,
|
||||
$aFoundCIDs, $aContentLocationUrls, $aFoundedContentLocationUrls, $bDoNotReplaceExternalUrl, $fAdditionalExternalFilter));
|
||||
}
|
||||
|
||||
$oElement->removeAttribute('data-x-skip-style');
|
||||
}
|
||||
|
||||
$sResult = $oDom->saveHTML();
|
||||
|
|
@ -1023,7 +1050,7 @@ class HtmlUtils
|
|||
$sResult = '<div data-x-div-type="html" '.$sHtmlAttrs.'>'.$sResult.'</div>';
|
||||
|
||||
$sResult = \str_replace(\MailSo\Base\HtmlUtils::$KOS, ':', $sResult);
|
||||
$sResult = \preg_replace('/[\s]+/u', ' ', $sResult);
|
||||
$sResult = \MailSo\Base\Utils::StripSpaces($sResult);
|
||||
|
||||
return \trim($sResult);
|
||||
}
|
||||
|
|
@ -1275,103 +1302,104 @@ class HtmlUtils
|
|||
*/
|
||||
public static function ConvertHtmlToPlain($sText)
|
||||
{
|
||||
$sText = trim(stripslashes($sText));
|
||||
$sText = preg_replace('/[\s]+/', ' ', $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',
|
||||
'/ /i',
|
||||
'/"/i',
|
||||
'/>/i',
|
||||
'/</i',
|
||||
'/&/i',
|
||||
'/©/i',
|
||||
'/™/i',
|
||||
'/“/',
|
||||
'/”/',
|
||||
'/–/',
|
||||
'/’/',
|
||||
'/&/',
|
||||
'/©/',
|
||||
'/™/',
|
||||
'/—/',
|
||||
'/“/',
|
||||
'/”/',
|
||||
'/•/',
|
||||
'/®/i',
|
||||
'/•/i',
|
||||
'/&[&;]+;/i',
|
||||
'/'/',
|
||||
'/ /'
|
||||
), 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 = \trim(\stripslashes($sText));
|
||||
$sText = \MailSo\Base\Utils::StripSpaces($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);
|
||||
$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',
|
||||
'/ /i',
|
||||
'/"/i',
|
||||
'/>/i',
|
||||
'/</i',
|
||||
'/&/i',
|
||||
'/©/i',
|
||||
'/™/i',
|
||||
'/“/',
|
||||
'/”/',
|
||||
'/–/',
|
||||
'/’/',
|
||||
'/&/',
|
||||
'/©/',
|
||||
'/™/',
|
||||
'/—/',
|
||||
'/“/',
|
||||
'/”/',
|
||||
'/•/',
|
||||
'/®/i',
|
||||
'/•/i',
|
||||
'/&[&;]+;/i',
|
||||
'/'/',
|
||||
'/ /'
|
||||
), 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);
|
||||
|
||||
return trim($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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -550,6 +550,17 @@ END;
|
|||
return \MailSo\Base\Utils::IsAscii($sValue) ? \strtoupper($sValue) : $sValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sValue
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function StripSpaces($sValue)
|
||||
{
|
||||
return \MailSo\Base\Utils::Trim(
|
||||
\preg_replace('/[\s]+/u', ' ', $sValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sValue
|
||||
*
|
||||
|
|
@ -557,7 +568,7 @@ END;
|
|||
*/
|
||||
public static function IsUtf8($sValue)
|
||||
{
|
||||
return (bool) ( \function_exists('mb_check_encoding') ?
|
||||
return (bool) (\function_exists('mb_check_encoding') ?
|
||||
\mb_check_encoding($sValue, 'UTF-8') : \preg_match('//u', $sValue));
|
||||
}
|
||||
|
||||
|
|
@ -1362,8 +1373,9 @@ END;
|
|||
*/
|
||||
public static function ClearFileName($sFileName)
|
||||
{
|
||||
return \MailSo\Base\Utils::ClearNullBite(\preg_replace('/[\s]+/u', ' ',
|
||||
\str_replace(array('"', '/', '\\', '*', '?', '<', '>', '|', ':'), ' ', $sFileName)));
|
||||
return \MailSo\Base\Utils::Trim(\MailSo\Base\Utils::ClearNullBite(
|
||||
\MailSo\Base\Utils::StripSpaces(
|
||||
\str_replace(array('"', '/', '\\', '*', '?', '<', '>', '|', ':'), ' ', $sFileName))));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1373,8 +1385,8 @@ END;
|
|||
*/
|
||||
public static function ClearXss($sValue)
|
||||
{
|
||||
return \MailSo\Base\Utils::ClearNullBite(
|
||||
\str_replace(array('"', '/', '\\', '*', '?', '<', '>', '|', ':'), ' ', $sValue));
|
||||
return \MailSo\Base\Utils::Trim(\MailSo\Base\Utils::ClearNullBite(
|
||||
\str_replace(array('"', '/', '\\', '*', '?', '<', '>', '|', ':'), ' ', $sValue)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -56,6 +56,11 @@ class Config
|
|||
*/
|
||||
public static $LargeThreadLimit = 50;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public static $MessageAllHeaders = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ abstract class Driver
|
|||
foreach ($mDesc as &$sLine)
|
||||
{
|
||||
$sLine = \strtr($sLine, array("\r" => '\r', "\n" => '\n'.$this->sNewLine));
|
||||
$sLine = \rtrim($mDesc);
|
||||
$sLine = \rtrim($sLine);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -179,33 +179,41 @@ class MailClient
|
|||
*/
|
||||
private function getEnvelopeOrHeadersRequestString()
|
||||
{
|
||||
return \MailSo\Imap\Enumerations\FetchType::BODY_HEADER_PEEK;
|
||||
if (\MailSo\Config::$MessageAllHeaders)
|
||||
{
|
||||
return \MailSo\Imap\Enumerations\FetchType::BODY_HEADER_PEEK;
|
||||
}
|
||||
|
||||
// return \MailSo\Imap\Enumerations\FetchType::ENVELOPE;
|
||||
return \MailSo\Imap\Enumerations\FetchType::BuildBodyCustomHeaderRequest(array(
|
||||
\MailSo\Mime\Enumerations\Header::RETURN_PATH,
|
||||
\MailSo\Mime\Enumerations\Header::RECEIVED,
|
||||
\MailSo\Mime\Enumerations\Header::MIME_VERSION,
|
||||
\MailSo\Mime\Enumerations\Header::MESSAGE_ID,
|
||||
\MailSo\Mime\Enumerations\Header::CONTENT_TYPE,
|
||||
\MailSo\Mime\Enumerations\Header::FROM_,
|
||||
\MailSo\Mime\Enumerations\Header::TO_,
|
||||
\MailSo\Mime\Enumerations\Header::CC,
|
||||
\MailSo\Mime\Enumerations\Header::BCC,
|
||||
\MailSo\Mime\Enumerations\Header::SENDER,
|
||||
\MailSo\Mime\Enumerations\Header::REPLY_TO,
|
||||
\MailSo\Mime\Enumerations\Header::DELIVERED_TO,
|
||||
\MailSo\Mime\Enumerations\Header::IN_REPLY_TO,
|
||||
\MailSo\Mime\Enumerations\Header::REFERENCES,
|
||||
\MailSo\Mime\Enumerations\Header::DATE,
|
||||
\MailSo\Mime\Enumerations\Header::SUBJECT,
|
||||
\MailSo\Mime\Enumerations\Header::SENSITIVITY,
|
||||
\MailSo\Mime\Enumerations\Header::X_MSMAIL_PRIORITY,
|
||||
\MailSo\Mime\Enumerations\Header::IMPORTANCE,
|
||||
\MailSo\Mime\Enumerations\Header::X_PRIORITY,
|
||||
\MailSo\Mime\Enumerations\Header::X_DRAFT_INFO,
|
||||
\MailSo\Mime\Enumerations\Header::RETURN_RECEIPT_TO,
|
||||
\MailSo\Mime\Enumerations\Header::DISPOSITION_NOTIFICATION_TO,
|
||||
\MailSo\Mime\Enumerations\Header::X_CONFIRM_READING_TO,
|
||||
\MailSo\Mime\Enumerations\Header::AUTHENTICATION_RESULTS,
|
||||
\MailSo\Mime\Enumerations\Header::X_DKIM_AUTHENTICATION_RESULTS,
|
||||
), true);
|
||||
//
|
||||
// return \MailSo\Imap\Enumerations\FetchType::BuildBodyCustomHeaderRequest(array(
|
||||
// \MailSo\Mime\Enumerations\Header::RETURN_PATH,
|
||||
// \MailSo\Mime\Enumerations\Header::RECEIVED,
|
||||
// \MailSo\Mime\Enumerations\Header::MIME_VERSION,
|
||||
// \MailSo\Mime\Enumerations\Header::MESSAGE_ID,
|
||||
// \MailSo\Mime\Enumerations\Header::FROM_,
|
||||
// \MailSo\Mime\Enumerations\Header::TO_,
|
||||
// \MailSo\Mime\Enumerations\Header::CC,
|
||||
// \MailSo\Mime\Enumerations\Header::BCC,
|
||||
// \MailSo\Mime\Enumerations\Header::SENDER,
|
||||
// \MailSo\Mime\Enumerations\Header::REPLY_TO,
|
||||
// \MailSo\Mime\Enumerations\Header::IN_REPLY_TO,
|
||||
// \MailSo\Mime\Enumerations\Header::DATE,
|
||||
// \MailSo\Mime\Enumerations\Header::SUBJECT,
|
||||
// \MailSo\Mime\Enumerations\Header::X_MSMAIL_PRIORITY,
|
||||
// \MailSo\Mime\Enumerations\Header::IMPORTANCE,
|
||||
// \MailSo\Mime\Enumerations\Header::X_PRIORITY,
|
||||
// \MailSo\Mime\Enumerations\Header::CONTENT_TYPE,
|
||||
// \MailSo\Mime\Enumerations\Header::REFERENCES,
|
||||
// \MailSo\Mime\Enumerations\Header::X_DRAFT_INFO,
|
||||
// \MailSo\Mime\Enumerations\Header::RECEIVED_SPF,
|
||||
// \MailSo\Mime\Enumerations\Header::AUTHENTICATION_RESULTS,
|
||||
// ), true);
|
||||
// return \MailSo\Imap\Enumerations\FetchType::ENVELOPE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1032,7 +1040,7 @@ class MailClient
|
|||
|
||||
$sReg = 'e?mail|from|to|subject|has|is|date|text|body|size|larger|bigger|smaller|maxsize|minsize';
|
||||
|
||||
$sSearch = \trim(\preg_replace('/[\s]+/', ' ', $sSearch));
|
||||
$sSearch = \MailSo\Base\Utils::StripSpaces($sSearch);
|
||||
$sSearch = \trim(\preg_replace('/('.$sReg.'): /i', '\\1:', $sSearch));
|
||||
|
||||
$mMatch = array();
|
||||
|
|
@ -1079,7 +1087,7 @@ class MailClient
|
|||
$sSearch = \str_replace($sToken, '', $sSearch);
|
||||
}
|
||||
|
||||
$sSearch = \trim(\preg_replace('/[\s]+/', ' ', $sSearch));
|
||||
$sSearch = \MailSo\Base\Utils::StripSpaces($sSearch);
|
||||
}
|
||||
|
||||
foreach ($mMatch[1] as $iIndex => $sName)
|
||||
|
|
@ -1353,7 +1361,7 @@ class MailClient
|
|||
|
||||
if ('' !== \trim($sMainText))
|
||||
{
|
||||
$sMainText = \trim(\trim(preg_replace('/[\s]+/', ' ', $sMainText)), '"');
|
||||
$sMainText = \trim(\MailSo\Base\Utils::StripSpaces($sMainText), '"');
|
||||
if ($bIsGmail)
|
||||
{
|
||||
$sGmailRawSearch .= ' '.$sMainText;
|
||||
|
|
@ -1690,7 +1698,8 @@ class MailClient
|
|||
\MailSo\Imap\Enumerations\FetchType::INTERNALDATE,
|
||||
\MailSo\Imap\Enumerations\FetchType::FLAGS,
|
||||
\MailSo\Imap\Enumerations\FetchType::BODYSTRUCTURE,
|
||||
$bSimple ? $this->getEnvelopeOrHeadersRequestStringForSimpleList() :
|
||||
$bSimple ?
|
||||
$this->getEnvelopeOrHeadersRequestStringForSimpleList() :
|
||||
$this->getEnvelopeOrHeadersRequestString()
|
||||
), \MailSo\Base\Utils::PrepearFetchSequence($aRequestIndexOrUids), $bIndexAsUid);
|
||||
|
||||
|
|
|
|||
|
|
@ -620,9 +620,9 @@ class Message
|
|||
$this->oDeliveredTo = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::DELIVERED_TO, $bCharsetAutoDetect);
|
||||
|
||||
$this->sInReplyTo = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::IN_REPLY_TO);
|
||||
$this->sReferences = \trim(\preg_replace('/[\s]+/', ' ',
|
||||
$oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::REFERENCES)));
|
||||
|
||||
$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);
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ class Message
|
|||
public function SetReferences($sReferences)
|
||||
{
|
||||
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::REFERENCES] =
|
||||
\trim(\preg_replace('/[\s]+/', ' ', $sReferences));
|
||||
\MailSo\Base\Utils::StripSpaces($sReferences);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4127,7 +4127,7 @@ class Actions
|
|||
*/
|
||||
private function rainLoopRepo()
|
||||
{
|
||||
$sUrl = APP_REP_PATH;
|
||||
$sUrl = APP_REPOSITORY_PATH;
|
||||
if ('' !== $sUrl)
|
||||
{
|
||||
$sUrl = rtrim($sUrl, '\\/').'/';
|
||||
|
|
@ -7190,12 +7190,25 @@ class Actions
|
|||
$sFromFolder = $this->GetActionParam('FromFolder', '');
|
||||
$sToFolder = $this->GetActionParam('ToFolder', '');
|
||||
$aUids = \explode(',', (string) $this->GetActionParam('Uids', ''));
|
||||
$bMarkAsRead = '1' === (string) $this->GetActionParam('MarkAsRead', '0');
|
||||
|
||||
$aFilteredUids = \array_filter($aUids, function (&$mUid) {
|
||||
$mUid = (int) \trim($mUid);
|
||||
return 0 < $mUid;
|
||||
});
|
||||
|
||||
if ($bMarkAsRead)
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->MailClient()->MessageSetSeen($sFromFolder, $aFilteredUids, true, true);
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
unset($oException);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$this->MailClient()->MessageMove($sFromFolder, $sToFolder, $aFilteredUids, true,
|
||||
|
|
@ -7259,7 +7272,7 @@ class Actions
|
|||
public function MainClearFileName($sFileName, $sContentType, $sMimeIndex, $iMaxLength = 250)
|
||||
{
|
||||
$sFileName = 0 === \strlen($sFileName) ? \preg_replace('/[^a-zA-Z0-9]/', '.', (empty($sMimeIndex) ? '' : $sMimeIndex.'.').$sContentType) : $sFileName;
|
||||
$sClearedFileName = \preg_replace('/[\s]+/', ' ', \preg_replace('/[\.]+/', '.', $sFileName));
|
||||
$sClearedFileName = \MailSo\Base\Utils::StripSpaces(\preg_replace('/[\.]+/', '.', $sFileName));
|
||||
$sExt = \MailSo\Base\Utils::GetFileExtension($sClearedFileName);
|
||||
|
||||
if (10 < $iMaxLength && $iMaxLength < \strlen($sClearedFileName) - \strlen($sExt))
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class Api
|
|||
if ($bOne)
|
||||
{
|
||||
\RainLoop\Api::SetupDefaultMailSoConfig();
|
||||
|
||||
|
||||
$bOne = \RainLoop\Api::RunResult();
|
||||
}
|
||||
}
|
||||
|
|
@ -95,6 +95,9 @@ class Api
|
|||
\MailSo\Config::$MessageListPermanentFilter =
|
||||
\trim(\RainLoop\Api::Config()->Get('labs', 'imap_message_list_permanent_filter', ''));
|
||||
|
||||
\MailSo\Config::$MessageAllHeaders =
|
||||
!!\RainLoop\Api::Config()->Get('labs', 'imap_message_all_headers', false);
|
||||
|
||||
\MailSo\Config::$LargeThreadLimit =
|
||||
(int) \RainLoop\Api::Config()->Get('labs', 'imap_large_thread_limit', 50);
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,11 @@ abstract class PdoAbstract
|
|||
*/
|
||||
protected $bExplain = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $bSqliteCollate = true;
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
|
|
@ -48,6 +53,18 @@ abstract class PdoAbstract
|
|||
return array('', '', '', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sStr1
|
||||
* @param string $sStr2
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sqliteNoCaseCollationHelper($sStr1, $sStr2)
|
||||
{
|
||||
$this->oLogger->WriteDump(array($sStr1, $sStr2));
|
||||
return \strcmp(\mb_strtoupper($sStr1, 'UTF-8'), \mb_strtoupper($sStr2, 'UTF-8'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \PDO
|
||||
*
|
||||
|
|
@ -67,6 +84,7 @@ abstract class PdoAbstract
|
|||
|
||||
$sType = $sDsn = $sDbLogin = $sDbPassword = '';
|
||||
list($sType, $sDsn, $sDbLogin, $sDbPassword) = $this->getPdoAccessData();
|
||||
|
||||
if (!\in_array($sType, array('mysql', 'sqlite', 'pgsql')))
|
||||
{
|
||||
throw new \Exception('Unknown PDO SQL connection type');
|
||||
|
|
@ -82,15 +100,28 @@ abstract class PdoAbstract
|
|||
$oPdo = false;
|
||||
try
|
||||
{
|
||||
// $bCaseFunc = false;
|
||||
$oPdo = @new \PDO($sDsn, $sDbLogin, $sDbPassword);
|
||||
if ($oPdo)
|
||||
{
|
||||
$sPdoType = $oPdo->getAttribute(\PDO::ATTR_DRIVER_NAME);
|
||||
$oPdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||
if ('mysql' === $sType && 'mysql' === $oPdo->getAttribute(\PDO::ATTR_DRIVER_NAME))
|
||||
|
||||
if ('mysql' === $sType && 'mysql' === $sPdoType)
|
||||
{
|
||||
$oPdo->exec('SET NAMES utf8 COLLATE utf8_general_ci');
|
||||
// $oPdo->exec('SET NAMES utf8');
|
||||
}
|
||||
// else if ('sqlite' === $sType && 'sqlite' === $sPdoType && $this->bSqliteCollate)
|
||||
// {
|
||||
// if (\method_exists($oPdo, 'sqliteCreateCollation') && \MailSo\Base\Utils::FunctionExistsAndEnabled('mb_strtoupper'))
|
||||
// {
|
||||
// $oPdo->sqliteCreateCollation('SQLITE_NOCASE_UTF8', array($this, 'sqliteNoCaseCollationHelper'));
|
||||
// $bCaseFunc = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// $this->oLogger->Write('PDO:'.$sPdoType.($bCaseFunc ? '/SQLITE_NOCASE_UTF8' : ''));
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
|
|
@ -156,10 +187,11 @@ abstract class PdoAbstract
|
|||
* @param string $sSql
|
||||
* @param array $aParams
|
||||
* @param bool $bMultiplyParams = false
|
||||
* @param bool $bLogParams = false
|
||||
*
|
||||
* @return \PDOStatement|null
|
||||
*/
|
||||
protected function prepareAndExecute($sSql, $aParams = array(), $bMultiplyParams = false)
|
||||
protected function prepareAndExecute($sSql, $aParams = array(), $bMultiplyParams = false, $bLogParams = false)
|
||||
{
|
||||
if ($this->bExplain && !$bMultiplyParams)
|
||||
{
|
||||
|
|
@ -172,16 +204,27 @@ abstract class PdoAbstract
|
|||
$oStmt = $this->getPDO()->prepare($sSql);
|
||||
if ($oStmt)
|
||||
{
|
||||
$aLogs = array();
|
||||
$aRootParams = $bMultiplyParams ? $aParams : array($aParams);
|
||||
foreach ($aRootParams as $aSubParams)
|
||||
{
|
||||
foreach ($aSubParams as $sName => $aValue)
|
||||
{
|
||||
if ($bLogParams)
|
||||
{
|
||||
$aLogs[$sName] = $aValue[0];
|
||||
}
|
||||
|
||||
$oStmt->bindValue($sName, $aValue[0], $aValue[1]);
|
||||
}
|
||||
|
||||
$mResult = $oStmt->execute() && !$bMultiplyParams ? $oStmt : null;
|
||||
}
|
||||
|
||||
if ($bLogParams && $aLogs)
|
||||
{
|
||||
$this->writeLog('Params: '.@\json_encode($aLogs, \defined('JSON_UNESCAPED_UNICODE') ? JSON_UNESCAPED_UNICODE : 0));
|
||||
}
|
||||
}
|
||||
|
||||
return $mResult;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,11 @@ abstract class AbstractConfig
|
|||
*/
|
||||
private $sFile;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sAdditionalFile;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
|
|
@ -27,12 +32,19 @@ abstract class AbstractConfig
|
|||
/**
|
||||
* @param string $sFileName
|
||||
* @param string $sFileHeader = ''
|
||||
* @param string $sAdditionalFileName = ''
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($sFileName, $sFileHeader = '')
|
||||
public function __construct($sFileName, $sFileHeader = '', $sAdditionalFileName = '')
|
||||
{
|
||||
$this->sFile = \APP_PRIVATE_DATA.'configs/'.$sFileName;
|
||||
$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();
|
||||
|
||||
|
|
@ -109,7 +121,7 @@ abstract class AbstractConfig
|
|||
*/
|
||||
private function cacheKey()
|
||||
{
|
||||
return 'config:'.\sha1($this->sFile).':';
|
||||
return 'config:'.\sha1($this->sFile).':'.\sha1($this->sAdditionalFile).':';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -120,12 +132,17 @@ abstract class AbstractConfig
|
|||
if ($this->bUseApcCache)
|
||||
{
|
||||
$iMTime = @\filemtime($this->sFile);
|
||||
if (\is_int($iMTime) && 0 < $iMTime)
|
||||
$iMTime = \is_int($iMTime) && 0 < $iMTime ? $iMTime : 0;
|
||||
|
||||
$iATime = $this->sAdditionalFile ? @\filemtime($this->sAdditionalFile) : 0;
|
||||
$iATime = \is_int($iATime) && 0 < $iATime ? $iATime : 0;
|
||||
|
||||
if (0 < $iMTime)
|
||||
{
|
||||
$sKey = $this->cacheKey();
|
||||
|
||||
$iTime = \apc_fetch($sKey.'time');
|
||||
if ($iTime && $iMTime === (int) $iTime)
|
||||
$sTimeHash = \apc_fetch($sKey.'time');
|
||||
if ($sTimeHash && $sTimeHash === \md5($iMTime.'/'.$iATime))
|
||||
{
|
||||
$aFetchData = \apc_fetch($sKey.'data');
|
||||
if (\is_array($aFetchData))
|
||||
|
|
@ -148,11 +165,16 @@ abstract class AbstractConfig
|
|||
if ($this->bUseApcCache)
|
||||
{
|
||||
$iMTime = @\filemtime($this->sFile);
|
||||
if (\is_int($iMTime) && 0 < $iMTime)
|
||||
$iMTime = \is_int($iMTime) && 0 < $iMTime ? $iMTime : 0;
|
||||
|
||||
$iATime = $this->sAdditionalFile ? @\filemtime($this->sAdditionalFile) : 0;
|
||||
$iATime = \is_int($iATime) && 0 < $iATime ? $iATime : 0;
|
||||
|
||||
if (0 < $iMTime)
|
||||
{
|
||||
$sKey = $this->cacheKey();
|
||||
|
||||
\apc_store($sKey.'time', $iMTime);
|
||||
\apc_store($sKey.'time', \md5($iMTime.'/'.$iATime));
|
||||
\apc_store($sKey.'data', $this->aData);
|
||||
|
||||
return true;
|
||||
|
|
@ -193,7 +215,7 @@ abstract class AbstractConfig
|
|||
}
|
||||
|
||||
$aData = \RainLoop\Utils::CustomParseIniFile($this->sFile, true);
|
||||
if (\is_array($aData) && 0 < count($aData))
|
||||
if (\is_array($aData) && 0 < \count($aData))
|
||||
{
|
||||
foreach ($aData as $sSectionKey => $aSectionValue)
|
||||
{
|
||||
|
|
@ -206,6 +228,28 @@ abstract class AbstractConfig
|
|||
}
|
||||
}
|
||||
|
||||
unset($aData);
|
||||
|
||||
if (\file_exists($this->sAdditionalFile) && \is_readable($this->sAdditionalFile))
|
||||
{
|
||||
$aSubData = \RainLoop\Utils::CustomParseIniFile($this->sAdditionalFile, true);
|
||||
if (\is_array($aSubData) && 0 < \count($aSubData))
|
||||
{
|
||||
foreach ($aSubData as $sSectionKey => $aSectionValue)
|
||||
{
|
||||
if (\is_array($aSectionValue))
|
||||
{
|
||||
foreach ($aSectionValue as $sParamKey => $mParamValue)
|
||||
{
|
||||
$this->Set($sSectionKey, $sParamKey, $mParamValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset($aSubData);
|
||||
}
|
||||
|
||||
$this->storeDataToCache();
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ class Application extends \RainLoop\Config\AbstractConfig
|
|||
{
|
||||
parent::__construct('application.ini',
|
||||
'; RainLoop Webmail configuration file
|
||||
; Please don\'t add custom parameters here, those will be overwritten');
|
||||
; Please don\'t add custom parameters here, those will be overwritten',
|
||||
defined('APP_ADDITIONAL_CONFIGURATION_NAME') ? APP_ADDITIONAL_CONFIGURATION_NAME : '');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -321,6 +322,7 @@ Enables caching in the system'),
|
|||
'imap_message_list_count_limit_trigger' => array(0),
|
||||
'imap_message_list_date_filter' => array(0),
|
||||
'imap_message_list_permanent_filter' => array(''),
|
||||
'imap_message_all_headers' => array(false),
|
||||
'imap_large_thread_limit' => array(50),
|
||||
'imap_folder_list_limit' => array(200),
|
||||
'imap_show_login_alert' => array(true),
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class Plugin extends \RainLoop\Config\AbstractConfig
|
|||
*/
|
||||
private function convertConfigMap($aMap)
|
||||
{
|
||||
if (0 < count($aMap))
|
||||
if (0 < \count($aMap))
|
||||
{
|
||||
$aResultMap = array();
|
||||
foreach ($aMap as /* @var $oProperty \RainLoop\Plugins\Property */ $oProperty)
|
||||
|
|
@ -33,12 +33,12 @@ class Plugin extends \RainLoop\Config\AbstractConfig
|
|||
if ($oProperty)
|
||||
{
|
||||
$mValue = $oProperty->DefaultValue();
|
||||
$sValue = is_array($mValue) && isset($mValue[0]) ? $mValue[0] : $mValue;
|
||||
$sValue = \is_array($mValue) && isset($mValue[0]) ? $mValue[0] : $mValue;
|
||||
$aResultMap[$oProperty->Name()] = array($sValue, '');
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < count($aResultMap))
|
||||
if (0 < \count($aResultMap))
|
||||
{
|
||||
return array(
|
||||
'plugin' => $aResultMap
|
||||
|
|
|
|||
|
|
@ -26,6 +26,11 @@ class Property
|
|||
*/
|
||||
public $Value;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $ValueLower;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
|
|
@ -54,6 +59,7 @@ class Property
|
|||
$this->TypeStr = '';
|
||||
|
||||
$this->Value = '';
|
||||
$this->ValueLower = '';
|
||||
$this->ValueCustom = '';
|
||||
|
||||
$this->Frec = 0;
|
||||
|
|
@ -120,6 +126,7 @@ class Property
|
|||
$this->Value = \trim($this->Value);
|
||||
$this->ValueCustom = \trim($this->ValueCustom);
|
||||
$this->TypeStr = \trim($this->TypeStr);
|
||||
$this->ValueLower = '';
|
||||
|
||||
if (0 < \strlen($this->Value))
|
||||
{
|
||||
|
|
@ -131,16 +138,22 @@ class Property
|
|||
|
||||
if ($this->IsName())
|
||||
{
|
||||
$this->Value = \preg_replace('/[\s]+/u', ' ', $this->Value);
|
||||
$this->Value = \MailSo\Base\Utils::StripSpaces($this->Value);
|
||||
}
|
||||
|
||||
// phones clear value for searching
|
||||
// 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 = $this->Value;
|
||||
$sPhone = \trim($this->Value);
|
||||
$sPhone = \preg_replace('/^[+]+/', '', $sPhone);
|
||||
$sPhone = \preg_replace('/[^\d]/', '', $sPhone);
|
||||
$this->ValueCustom = $sPhone;
|
||||
$this->ValueCustom = \trim($sPhone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -957,6 +957,7 @@ class PdoAddressBook
|
|||
':prop_type' => array($oProp->Type, \PDO::PARAM_INT),
|
||||
':prop_type_str' => array($oProp->TypeStr, \PDO::PARAM_STR),
|
||||
':prop_value' => array($oProp->Value, \PDO::PARAM_STR),
|
||||
':prop_value_lower' => array($oProp->ValueLower, \PDO::PARAM_STR),
|
||||
':prop_value_custom' => array($oProp->ValueCustom, \PDO::PARAM_STR),
|
||||
':prop_frec' => array($iFreq, \PDO::PARAM_INT),
|
||||
);
|
||||
|
|
@ -965,9 +966,9 @@ class PdoAddressBook
|
|||
if (0 < \count($aParams))
|
||||
{
|
||||
$sSql = 'INSERT INTO rainloop_ab_properties '.
|
||||
'( id_contact, id_user, prop_type, prop_type_str, prop_value, prop_value_custom, prop_frec)'.
|
||||
'( id_contact, id_user, prop_type, prop_type_str, prop_value, prop_value_lower, prop_value_custom, prop_frec)'.
|
||||
' VALUES '.
|
||||
'(:id_contact, :id_user, :prop_type, :prop_type_str, :prop_value, :prop_value_custom, :prop_frec)';
|
||||
'(:id_contact, :id_user, :prop_type, :prop_type_str, :prop_value, :prop_value_lower, :prop_value_custom, :prop_frec)';
|
||||
|
||||
$this->prepareAndExecute($sSql, $aParams, true);
|
||||
}
|
||||
|
|
@ -1072,6 +1073,7 @@ class PdoAddressBook
|
|||
if (0 < \strlen($sSearch))
|
||||
{
|
||||
$sCustomSearch = $this->specialConvertSearchValueCustomPhone($sSearch);
|
||||
$sLowerSearch = $this->specialConvertSearchValueLower($sSearch, '=');
|
||||
|
||||
$sSearchTypes = \implode(',', array(
|
||||
PropertyType::EMAIl, PropertyType::FIRST_NAME, PropertyType::LAST_NAME, PropertyType::NICK_NAME,
|
||||
|
|
@ -1079,8 +1081,10 @@ class PdoAddressBook
|
|||
));
|
||||
|
||||
$sSql = 'SELECT id_user, id_prop, id_contact FROM rainloop_ab_properties '.
|
||||
'WHERE (id_user = :id_user) AND prop_type IN ('.$sSearchTypes.') AND (prop_value LIKE :search ESCAPE \'=\''.
|
||||
(0 < \strlen($sCustomSearch) ? ' OR (prop_type = '.PropertyType::PHONE.' AND prop_value_custom <> \'\' AND prop_value_custom LIKE :search_custom_phone)' : '').
|
||||
'WHERE (id_user = :id_user) AND prop_type IN ('.$sSearchTypes.') AND ('.
|
||||
'prop_value LIKE :search ESCAPE \'=\''.
|
||||
(0 < \strlen($sLowerSearch) ? ' OR (prop_value_lower <> \'\' AND prop_value_lower LIKE :search_lower ESCAPE \'=\')' : '').
|
||||
(0 < \strlen($sCustomSearch) ? ' OR (prop_type = '.PropertyType::PHONE.' AND prop_value_custom <> \'\' AND prop_value_custom LIKE :search_custom_phone)' : '').
|
||||
') GROUP BY id_contact, id_prop';
|
||||
|
||||
$aParams = array(
|
||||
|
|
@ -1088,12 +1092,17 @@ class PdoAddressBook
|
|||
':search' => array($this->specialConvertSearchValue($sSearch, '='), \PDO::PARAM_STR)
|
||||
);
|
||||
|
||||
if (0 < \strlen($sLowerSearch))
|
||||
{
|
||||
$aParams[':search_lower'] = array($sLowerSearch, \PDO::PARAM_STR);
|
||||
}
|
||||
|
||||
if (0 < \strlen($sCustomSearch))
|
||||
{
|
||||
$aParams[':search_custom_phone'] = array($sCustomSearch, \PDO::PARAM_STR);
|
||||
}
|
||||
|
||||
$oStmt = $this->prepareAndExecute($sSql, $aParams);
|
||||
$oStmt = $this->prepareAndExecute($sSql, $aParams, false, true);
|
||||
if ($oStmt)
|
||||
{
|
||||
$aFetch = $oStmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
|
|
@ -1211,6 +1220,7 @@ class PdoAddressBook
|
|||
$oProperty->Type = (int) $aItem['prop_type'];
|
||||
$oProperty->TypeStr = isset($aItem['prop_type_str']) ? (string) $aItem['prop_type_str'] : '';
|
||||
$oProperty->Value = (string) $aItem['prop_value'];
|
||||
$oProperty->ValueLower = isset($aItem['prop_value_lower']) ? (string) $aItem['prop_value_lower'] : '';
|
||||
$oProperty->ValueCustom = isset($aItem['prop_value_custom']) ? (string) $aItem['prop_value_custom'] : '';
|
||||
$oProperty->Frec = isset($aItem['prop_frec']) ? (int) $aItem['prop_frec'] : 0;
|
||||
|
||||
|
|
@ -1320,6 +1330,7 @@ class PdoAddressBook
|
|||
$oProperty->Type = (int) $aItem['prop_type'];
|
||||
$oProperty->TypeStr = isset($aItem['prop_type_str']) ? (string) $aItem['prop_type_str'] : '';
|
||||
$oProperty->Value = (string) $aItem['prop_value'];
|
||||
$oProperty->ValueLower = isset($aItem['prop_value_lower']) ? (string) $aItem['prop_value_lower'] : '';
|
||||
$oProperty->ValueCustom = isset($aItem['prop_value_custom']) ? (string) $aItem['prop_value_custom'] : '';
|
||||
$oProperty->Frec = isset($aItem['prop_frec']) ? (int) $aItem['prop_frec'] : 0;
|
||||
|
||||
|
|
@ -1364,8 +1375,14 @@ class PdoAddressBook
|
|||
PropertyType::EMAIl, PropertyType::FIRST_NAME, PropertyType::LAST_NAME, PropertyType::NICK_NAME
|
||||
));
|
||||
|
||||
$sLowerSearch = $this->specialConvertSearchValueLower($sSearch);
|
||||
|
||||
$sSql = 'SELECT id_contact, id_prop, prop_type, prop_value FROM rainloop_ab_properties '.
|
||||
'WHERE (id_user = :id_user) AND prop_type IN ('.$sTypes.') AND prop_value LIKE :search ESCAPE \'=\'';
|
||||
'WHERE (id_user = :id_user) AND prop_type IN ('.$sTypes.') AND ('.
|
||||
'prop_value LIKE :search ESCAPE \'=\''.
|
||||
(0 < \strlen($sLowerSearch) ? ' OR (prop_value_lower <> \'\' AND prop_value_lower LIKE :search_lower ESCAPE \'=\')' : '').
|
||||
')'
|
||||
;
|
||||
|
||||
$aParams = array(
|
||||
':id_user' => array($iUserID, \PDO::PARAM_INT),
|
||||
|
|
@ -1373,6 +1390,11 @@ class PdoAddressBook
|
|||
':search' => array($this->specialConvertSearchValue($sSearch, '='), \PDO::PARAM_STR)
|
||||
);
|
||||
|
||||
if (0 < \strlen($sLowerSearch))
|
||||
{
|
||||
$aParams[':search_lower'] = array($sLowerSearch, \PDO::PARAM_STR);
|
||||
}
|
||||
|
||||
$sSql .= ' ORDER BY prop_frec DESC';
|
||||
$sSql .= ' LIMIT :limit';
|
||||
|
||||
|
|
@ -1547,7 +1569,7 @@ class PdoAddressBook
|
|||
{
|
||||
$oResult = \MailSo\Mime\Email::Parse(\trim($mItem));
|
||||
}
|
||||
catch (\Exception $oException) {}
|
||||
catch (\Exception $oException) { unset($oException); }
|
||||
return $oResult;
|
||||
}, $aEmails);
|
||||
|
||||
|
|
@ -1837,7 +1859,7 @@ SQLITEINITIAL;
|
|||
break;
|
||||
}
|
||||
|
||||
if (0 < strlen($sInitial))
|
||||
if (0 < \strlen($sInitial))
|
||||
{
|
||||
$aList = \explode(';', \trim($sInitial));
|
||||
foreach ($aList as $sV)
|
||||
|
|
@ -1869,17 +1891,26 @@ SQLITEINITIAL;
|
|||
{
|
||||
case 'mysql':
|
||||
$mCache = $this->dataBaseUpgrade($this->sDsnType.'-ab-version', array(
|
||||
1 => $this->getInitialTablesArray($this->sDsnType)
|
||||
1 => $this->getInitialTablesArray($this->sDsnType),
|
||||
2 => array(
|
||||
'ALTER TABLE rainloop_ab_properties ADD prop_value_lower varchar(255) NOT NULL DEFAULT \'\' AFTER prop_value_custom;'
|
||||
)
|
||||
));
|
||||
break;
|
||||
case 'pgsql':
|
||||
$mCache = $this->dataBaseUpgrade($this->sDsnType.'-ab-version', array(
|
||||
1 => $this->getInitialTablesArray($this->sDsnType)
|
||||
1 => $this->getInitialTablesArray($this->sDsnType),
|
||||
2 => array(
|
||||
'ALTER TABLE rainloop_ab_properties ADD prop_value_lower text NOT NULL DEFAULT \'\';'
|
||||
)
|
||||
));
|
||||
break;
|
||||
case 'sqlite':
|
||||
$mCache = $this->dataBaseUpgrade($this->sDsnType.'-ab-version', array(
|
||||
1 => $this->getInitialTablesArray($this->sDsnType)
|
||||
1 => $this->getInitialTablesArray($this->sDsnType),
|
||||
2 => array(
|
||||
'ALTER TABLE rainloop_ab_properties ADD prop_value_lower text NOT NULL DEFAULT \'\';'
|
||||
)
|
||||
));
|
||||
break;
|
||||
}
|
||||
|
|
@ -1934,6 +1965,24 @@ SQLITEINITIAL;
|
|||
array($sEscapeSign.$sEscapeSign, $sEscapeSign.'_', $sEscapeSign.'%'), $sSearch).'%';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSearch
|
||||
* @param string $sEscapeSign = '='
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function specialConvertSearchValueLower($sSearch, $sEscapeSign = '=')
|
||||
{
|
||||
if (!\MailSo\Base\Utils::FunctionExistsAndEnabled('mb_strtolower'))
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
return '%'.\str_replace(array($sEscapeSign, '_', '%'),
|
||||
array($sEscapeSign.$sEscapeSign, $sEscapeSign.'_', $sEscapeSign.'%'),
|
||||
(string) @\mb_strtolower($sSearch, 'UTF-8')).'%';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sSearch
|
||||
*
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ class SieveStorage implements \RainLoop\Providers\Filters\FiltersInterface
|
|||
$sResult .= ' "'.$this->quote($sValue).'"';
|
||||
}
|
||||
|
||||
$sResult = \preg_replace('/[\s]+/u', ' ', $sResult);
|
||||
$sResult = \MailSo\Base\Utils::StripSpaces($sResult);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -358,8 +358,8 @@ class SieveStorage implements \RainLoop\Providers\Filters\FiltersInterface
|
|||
$sSubject = '';
|
||||
if (0 < \strlen($sValueSecond))
|
||||
{
|
||||
$sSubject = ':subject "'.$this->quote(
|
||||
\preg_replace('/[\s]+/u', ' ', $sValueSecond)).'" ';
|
||||
$sSubject = ':subject "'.
|
||||
$this->quote(\MailSo\Base\Utils::StripSpaces($sValueSecond)).'" ';
|
||||
}
|
||||
|
||||
if (0 < \strlen($sValueThird) && \is_numeric($sValueThird) && 1 < (int) $sValueThird)
|
||||
|
|
|
|||
|
|
@ -89,7 +89,10 @@
|
|||
|
||||
if (window.$LAB && window.rainloopAppData && window.rainloopAppData['TemplatesLink'] && window.rainloopAppData['LangLink'])
|
||||
{
|
||||
__simplePace(10);
|
||||
var oProgress = progressJs();
|
||||
|
||||
oProgress.setOptions({'theme': 'rainloop'});
|
||||
oProgress.start().set(5);
|
||||
|
||||
window.$LAB
|
||||
.script(function () {
|
||||
|
|
@ -98,7 +101,9 @@
|
|||
];
|
||||
})
|
||||
.wait(function () {
|
||||
__simplePace(20);
|
||||
|
||||
oProgress.set(20);
|
||||
|
||||
if (window.rainloopAppData['IncludeBackground']) {
|
||||
$('#rl-bg').attr('style', 'background-image: none !important;').backstretch(
|
||||
window.rainloopAppData['IncludeBackground'].replace('{{USER}}',
|
||||
|
|
@ -114,20 +119,20 @@
|
|||
];
|
||||
})
|
||||
.wait(function () {
|
||||
__simplePace(10);
|
||||
oProgress.set(30);
|
||||
})
|
||||
.script(function () {
|
||||
return {'src': '{{BaseAppMainScriptLink}}', 'type': 'text/javascript', 'charset': 'utf-8'};
|
||||
})
|
||||
.wait(function () {
|
||||
__simplePace(20);
|
||||
oProgress.set(50);
|
||||
})
|
||||
.script(function () {
|
||||
return window.rainloopAppData['PluginsLink'] ?
|
||||
{'src': window.rainloopAppData['PluginsLink'], 'type': 'text/javascript', 'charset': 'utf-8'} : null;
|
||||
})
|
||||
.wait(function () {
|
||||
__simplePace(5);
|
||||
oProgress.set(55);
|
||||
__runBoot(false);
|
||||
})
|
||||
.script(function () {
|
||||
|
|
|
|||
|
|
@ -22,16 +22,6 @@ Options -Indexes
|
|||
|
||||
define('APP_USE_APC_CACHE', true);
|
||||
|
||||
$sCustomDataPath = '';
|
||||
if (file_exists(APP_INDEX_ROOT_PATH.'include.php'))
|
||||
{
|
||||
include_once APP_INDEX_ROOT_PATH.'include.php';
|
||||
}
|
||||
|
||||
$sCustomDataPath = function_exists('__get_custom_data_full_path') ? rtrim(trim(__get_custom_data_full_path()), '\\/') : '';
|
||||
define('APP_DATA_FOLDER_PATH', 0 === strlen($sCustomDataPath) ? APP_INDEX_ROOT_PATH.'data/' : $sCustomDataPath.'/');
|
||||
unset($sCustomDataPath);
|
||||
|
||||
if (function_exists('date_default_timezone_set'))
|
||||
{
|
||||
date_default_timezone_set('UTC');
|
||||
|
|
@ -53,12 +43,30 @@ Options -Indexes
|
|||
define('APP_MULTIPLY', 0 < strlen($sPrivateDataFolderInternalName) && APP_DEFAULT_PRIVATE_DATA_NAME !== APP_PRIVATE_DATA_NAME);
|
||||
|
||||
define('APP_DUMMY', '********');
|
||||
define('APP_GOOGLE_ACCESS_TOKEN_PREFIX', ':GAT:');
|
||||
define('APP_DEV_VERSION', '0.0.0');
|
||||
define('APP_GOOGLE_ACCESS_TOKEN_PREFIX', ':GAT:');
|
||||
define('APP_WEB_SITE', 'http://www.rainloop.net/');
|
||||
define('APP_API_PATH', 'http://api.rainloop.net/');
|
||||
define('APP_REP_PATH', 'http://repository.rainloop.net/v1/');
|
||||
define('APP_REPO_CORE_FILE', 'http://repository.rainloop.net/v2/core.{{channel}}.json');
|
||||
define('APP_STATUS_PATH', 'http://status.rainloop.net/');
|
||||
define('APP_REPOSITORY_PATH', 'http://repository.rainloop.net/v1/');
|
||||
define('APP_REPO_CORE_FILE', 'http://repository.rainloop.net/v2/core.{{channel}}.json');
|
||||
|
||||
$sCustomDataPath = '';
|
||||
$sCustomConfiguration = '';
|
||||
|
||||
if (file_exists(APP_INDEX_ROOT_PATH.'include.php'))
|
||||
{
|
||||
include_once APP_INDEX_ROOT_PATH.'include.php';
|
||||
}
|
||||
|
||||
$sCustomDataPath = function_exists('__get_custom_data_full_path') ? rtrim(trim(__get_custom_data_full_path()), '\\/') : '';
|
||||
define('APP_DATA_FOLDER_PATH', 0 === strlen($sCustomDataPath) ? APP_INDEX_ROOT_PATH.'data/' : $sCustomDataPath.'/');
|
||||
unset($sCustomDataPath);
|
||||
|
||||
$sCustomConfiguration = function_exists('__get_additional_configuration_name') ? trim(__get_additional_configuration_name()) : '';
|
||||
define('APP_ADDITIONAL_CONFIGURATION_NAME', $sCustomConfiguration);
|
||||
unset($sCustomConfiguration);
|
||||
|
||||
define('APP_DATA_FOLDER_PATH_UNIX', str_replace('\\', '/', APP_DATA_FOLDER_PATH));
|
||||
|
||||
$sSalt = @file_get_contents(APP_DATA_FOLDER_PATH.'SALT.php');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue