mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-08 22:18:28 +03:00
Find links in html messages
This commit is contained in:
parent
d50c068a3d
commit
041bd1ae1b
6 changed files with 388 additions and 335 deletions
|
|
@ -8,6 +8,8 @@ namespace MailSo\Base;
|
|||
*/
|
||||
class HtmlUtils
|
||||
{
|
||||
static $KOS = '@@_KOS_@@';
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
|
|
@ -261,14 +263,106 @@ class HtmlUtils
|
|||
return \implode(';', $aOutStyles);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMDocument $oDom
|
||||
*/
|
||||
public static function FindLinksInDOM(&$oDom)
|
||||
{
|
||||
$aNodes = $oDom->getElementsByTagName('*');
|
||||
foreach ($aNodes as /* @var $oElement \DOMElement */ $oElement)
|
||||
{
|
||||
$sTagNameLower = \strtolower($oElement->tagName);
|
||||
$sParentTagNameLower = isset($oElement->parentNode) && isset($oElement->parentNode->tagName) ?
|
||||
\strtolower($oElement->parentNode->tagName) : '';
|
||||
|
||||
if (!\in_array($sTagNameLower, array('html', 'meta', 'head', 'style', 'script', 'img', 'button', 'input', 'textarea', 'a')) &&
|
||||
'a' !== $sParentTagNameLower && $oElement->childNodes && 0 < $oElement->childNodes->length)
|
||||
{
|
||||
$oSubItem = null;
|
||||
$aTextNodes = array();
|
||||
$iIndex = $oElement->childNodes->length - 1;
|
||||
while ($iIndex > -1)
|
||||
{
|
||||
$oSubItem = $oElement->childNodes->item($iIndex);
|
||||
if ($oSubItem && XML_TEXT_NODE === $oSubItem->nodeType)
|
||||
{
|
||||
$aTextNodes[] = $oSubItem;
|
||||
}
|
||||
|
||||
$iIndex--;
|
||||
}
|
||||
|
||||
unset($oSubItem);
|
||||
|
||||
foreach ($aTextNodes as $oTextNode)
|
||||
{
|
||||
if ($oTextNode && 0 < \strlen($oTextNode->wholeText)/* && \preg_match('/http[s]?:\/\//i', $oTextNode->wholeText)*/)
|
||||
{
|
||||
$sText = \MailSo\Base\LinkFinder::NewInstance()
|
||||
->Text($oTextNode->wholeText)
|
||||
->UseDefaultWrappers(true)
|
||||
->CompileText()
|
||||
;
|
||||
|
||||
$oSubDom = \MailSo\Base\HtmlUtils::GetDomFromText('<html><body>'.$sText.'</body></html>');
|
||||
if ($oSubDom)
|
||||
{
|
||||
$oBodyNodes = $oSubDom->getElementsByTagName('body');
|
||||
if ($oBodyNodes && 0 < $oBodyNodes->length)
|
||||
{
|
||||
$oBodyChildNodes = $oBodyNodes->item(0)->childNodes;
|
||||
if ($oBodyChildNodes && $oBodyChildNodes->length)
|
||||
{
|
||||
for ($iIndex = 0, $iLen = $oBodyChildNodes->length; $iIndex < $iLen; $iIndex++)
|
||||
{
|
||||
$oSubItem = $oBodyChildNodes->item($iIndex);
|
||||
if ($oSubItem)
|
||||
{
|
||||
if (XML_ELEMENT_NODE === $oSubItem->nodeType &&
|
||||
'a' === \strtolower($oSubItem->tagName))
|
||||
{
|
||||
$oLink = $oDom->createElement('a',
|
||||
\str_replace(':', \MailSo\Base\HtmlUtils::$KOS, \htmlspecialchars($oSubItem->nodeValue)));
|
||||
|
||||
$sHref = $oSubItem->getAttribute('href');
|
||||
if ($sHref)
|
||||
{
|
||||
$oLink->setAttribute('href', $sHref);
|
||||
}
|
||||
|
||||
$oElement->insertBefore($oLink, $oTextNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oElement->insertBefore($oDom->importNode($oSubItem), $oTextNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$oElement->removeChild($oTextNode);
|
||||
}
|
||||
}
|
||||
|
||||
unset($oBodyNodes);
|
||||
}
|
||||
|
||||
unset($oSubDom, $sText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset($aNodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sHtml
|
||||
* @param bool $bDoNotReplaceExternalUrl = false
|
||||
* @param bool $bFindLinksInHtml = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function ClearHtmlSimple($sHtml, $bDoNotReplaceExternalUrl = false)
|
||||
public static function ClearHtmlSimple($sHtml, $bDoNotReplaceExternalUrl = false, $bFindLinksInHtml = false)
|
||||
{
|
||||
$bHasExternals = false;
|
||||
$aFoundCIDs = array();
|
||||
|
|
@ -276,7 +370,7 @@ class HtmlUtils
|
|||
$aFoundedContentLocationUrls = array();
|
||||
|
||||
return \MailSo\Base\HtmlUtils::ClearHtml($sHtml, $bHasExternals, $aFoundCIDs,
|
||||
$aContentLocationUrls, $aFoundedContentLocationUrls, $bDoNotReplaceExternalUrl);
|
||||
$aContentLocationUrls, $aFoundedContentLocationUrls, $bDoNotReplaceExternalUrl, $bFindLinksInHtml);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -286,11 +380,13 @@ class HtmlUtils
|
|||
* @param array $aContentLocationUrls = array()
|
||||
* @param array $aFoundedContentLocationUrls = array()
|
||||
* @param bool $bDoNotReplaceExternalUrl = false
|
||||
* @param bool $bFindLinksInHtml = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function ClearHtml($sHtml, &$bHasExternals = false, &$aFoundCIDs = array(),
|
||||
$aContentLocationUrls = array(), &$aFoundedContentLocationUrls = array(), $bDoNotReplaceExternalUrl = false)
|
||||
$aContentLocationUrls = array(), &$aFoundedContentLocationUrls = array(),
|
||||
$bDoNotReplaceExternalUrl = false, $bFindLinksInHtml = false)
|
||||
{
|
||||
$sHtml = null === $sHtml ? '' : (string) $sHtml;
|
||||
$sHtml = \trim($sHtml);
|
||||
|
|
@ -313,11 +409,16 @@ class HtmlUtils
|
|||
|
||||
if ($oDom)
|
||||
{
|
||||
if ($bFindLinksInHtml)
|
||||
{
|
||||
\MailSo\Base\HtmlUtils::FindLinksInDOM($oDom);
|
||||
}
|
||||
|
||||
$aNodes = $oDom->getElementsByTagName('*');
|
||||
foreach ($aNodes as /* @var $oElement \DOMElement */ $oElement)
|
||||
{
|
||||
$sTagNameLower = \strtolower($oElement->tagName);
|
||||
|
||||
|
||||
// convert body attributes to styles
|
||||
if ('body' === $sTagNameLower)
|
||||
{
|
||||
|
|
@ -493,6 +594,8 @@ class HtmlUtils
|
|||
$sResult = '<div data-x-div-type="body" '.$sBodyAttrs.'>'.$sResult.'</div>';
|
||||
$sResult = '<div data-x-div-type="html" '.$sHtmlAttrs.'>'.$sResult.'</div>';
|
||||
|
||||
$sResult = \str_replace(\MailSo\Base\HtmlUtils::$KOS, ':', $sResult);
|
||||
|
||||
return \trim($sResult);
|
||||
}
|
||||
|
||||
|
|
@ -658,8 +761,7 @@ class HtmlUtils
|
|||
$sText = \MailSo\Base\LinkFinder::NewInstance()
|
||||
->Text($sText)
|
||||
->UseDefaultWrappers($bLinksWithTargetBlank)
|
||||
// ->CompileText(true, false);
|
||||
->CompileText(true, true);
|
||||
->CompileText();
|
||||
|
||||
$sText = \str_replace("\r", '', $sText);
|
||||
|
||||
|
|
|
|||
|
|
@ -126,13 +126,8 @@ class LinkFinder
|
|||
*/
|
||||
public function UseDefaultWrappers($bAddTargetBlank = false)
|
||||
{
|
||||
$this->fLinkWrapper = function ($sLink, $bShortLink = false) use ($bAddTargetBlank) {
|
||||
|
||||
if ($bShortLink && \in_array(\strtolower($sLink), array('asp.net', 'vb.net', 'mailbee.net')))
|
||||
{
|
||||
return $sLink;
|
||||
}
|
||||
|
||||
$this->fLinkWrapper = function ($sLink) use ($bAddTargetBlank) {
|
||||
|
||||
$sNameLink = $sLink;
|
||||
if (!\preg_match('/^[a-z]{3,5}\:\/\//i', \ltrim($sLink)))
|
||||
{
|
||||
|
|
@ -151,11 +146,10 @@ class LinkFinder
|
|||
|
||||
/**
|
||||
* @param bool $bUseHtmlSpecialChars = true
|
||||
* @param bool $bFindShortLinks = true
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function CompileText($bUseHtmlSpecialChars = true, $bFindShortLinks = true)
|
||||
public function CompileText($bUseHtmlSpecialChars = true)
|
||||
{
|
||||
$sText = \substr($this->sText, 0, $this->iOptimizationLimit);
|
||||
$sSubText = \substr($this->sText, $this->iOptimizationLimit);
|
||||
|
|
@ -171,11 +165,6 @@ class LinkFinder
|
|||
$sText = $this->findMails($sText, $this->fMailWrapper);
|
||||
}
|
||||
|
||||
if ($bFindShortLinks && null !== $this->fLinkWrapper && \is_callable($this->fLinkWrapper))
|
||||
{
|
||||
$sText = $this->findShortLinks($sText, $this->fLinkWrapper);
|
||||
}
|
||||
|
||||
$sResult = '';
|
||||
if ($bUseHtmlSpecialChars)
|
||||
{
|
||||
|
|
@ -259,46 +248,6 @@ class LinkFinder
|
|||
return $sText;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sText
|
||||
* @param mixed $fWrapper
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function findShortLinks($sText, $fWrapper)
|
||||
{
|
||||
$sPattern = '/([a-z0-9-\.]+\.(?:com|org|net|ru))([^a-z0-9-\.])/i';
|
||||
|
||||
$aPrepearPlainStringUrls = $this->aPrepearPlainStringUrls;
|
||||
$sText = \preg_replace_callback($sPattern, function ($aMatch) use ($fWrapper, &$aPrepearPlainStringUrls) {
|
||||
|
||||
if (\is_array($aMatch) && 2 < \count($aMatch) && isset($aMatch[1]) && 0 < \strlen($aMatch[1]))
|
||||
{
|
||||
$sLinkWithWrap = \call_user_func_array($fWrapper, array($aMatch[1], true));
|
||||
if (\is_string($sLinkWithWrap))
|
||||
{
|
||||
$aPrepearPlainStringUrls[] = \stripslashes($sLinkWithWrap);
|
||||
return \MailSo\Base\LinkFinder::OPEN_LINK.
|
||||
(\count($aPrepearPlainStringUrls) - 1).
|
||||
\MailSo\Base\LinkFinder::CLOSE_LINK.
|
||||
$aMatch[2];
|
||||
}
|
||||
|
||||
return $aMatch[0];
|
||||
}
|
||||
|
||||
return '';
|
||||
|
||||
}, $sText);
|
||||
|
||||
if (0 < \count($aPrepearPlainStringUrls))
|
||||
{
|
||||
$this->aPrepearPlainStringUrls = $aPrepearPlainStringUrls;
|
||||
}
|
||||
|
||||
return $sText;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sText
|
||||
* @param mixed $fWrapper
|
||||
|
|
|
|||
|
|
@ -740,7 +740,7 @@ class Utils
|
|||
{
|
||||
$sResult = '';
|
||||
$sContentType = \strtolower($sContentType);
|
||||
if (0 === strpos($sContentType, 'image/'))
|
||||
if (0 === \strpos($sContentType, 'image/'))
|
||||
{
|
||||
$sResult = 'image';
|
||||
}
|
||||
|
|
@ -847,7 +847,7 @@ class Utils
|
|||
*/
|
||||
public static function Php2js($mInput)
|
||||
{
|
||||
return \json_encode($mInput, defined('JSON_UNESCAPED_UNICODE') ? JSON_UNESCAPED_UNICODE : 0);
|
||||
return \json_encode($mInput, \defined('JSON_UNESCAPED_UNICODE') ? JSON_UNESCAPED_UNICODE : 0);
|
||||
|
||||
// if (\is_null($mInput))
|
||||
// {
|
||||
|
|
@ -918,25 +918,25 @@ class Utils
|
|||
*/
|
||||
public static function RecRmDir($sDir)
|
||||
{
|
||||
if (@is_dir($sDir))
|
||||
if (@\is_dir($sDir))
|
||||
{
|
||||
$aObjects = scandir($sDir);
|
||||
$aObjects = \scandir($sDir);
|
||||
foreach ($aObjects as $sObject)
|
||||
{
|
||||
if ('.' !== $sObject && '..' !== $sObject)
|
||||
{
|
||||
if ('dir' === filetype($sDir.'/'.$sObject))
|
||||
if ('dir' === \filetype($sDir.'/'.$sObject))
|
||||
{
|
||||
self::RecRmDir($sDir.'/'.$sObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
@unlink($sDir.'/'.$sObject);
|
||||
@\unlink($sDir.'/'.$sObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return @rmdir($sDir);
|
||||
return @\rmdir($sDir);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ final class Version
|
|||
/**
|
||||
* @var string
|
||||
*/
|
||||
const APP_VERSION = '1.2.2';
|
||||
const APP_VERSION = '1.3.0';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
|
|
|
|||
|
|
@ -6264,7 +6264,7 @@ class Actions
|
|||
protected function responseObject($mResponse, $sParent = '', $aParameters = array())
|
||||
{
|
||||
$mResult = $mResponse;
|
||||
if (is_object($mResponse))
|
||||
if (\is_object($mResponse))
|
||||
{
|
||||
$bHook = true;
|
||||
$sClassName = \get_class($mResponse);
|
||||
|
|
@ -6327,7 +6327,7 @@ class Actions
|
|||
$sSubject = $mResult['Subject'];
|
||||
$mResult['RequestHash'] = \RainLoop\Utils::EncodeKeyValues(array(
|
||||
'V' => APP_VERSION,
|
||||
'Account' => $oAccount ? md5($oAccount->Hash()) : '',
|
||||
'Account' => $oAccount ? \md5($oAccount->Hash()) : '',
|
||||
'Folder' => $mResult['Folder'],
|
||||
'Uid' => $mResult['Uid'],
|
||||
'MimeType' => 'message/rfc822',
|
||||
|
|
@ -6372,12 +6372,12 @@ class Actions
|
|||
}
|
||||
|
||||
$sPlain = '';
|
||||
$sHtml = $mResponse->Html();
|
||||
$sHtml = \trim($mResponse->Html());
|
||||
$bRtl = false;
|
||||
|
||||
if (0 === \strlen($sHtml))
|
||||
{
|
||||
$sPlain = $mResponse->Plain();
|
||||
$sPlain = \trim($mResponse->Plain());
|
||||
$bRtl = \MailSo\Base\Utils::IsRTL($sPlain);
|
||||
}
|
||||
else
|
||||
|
|
@ -6389,7 +6389,8 @@ class Actions
|
|||
$mResult['InReplyTo'] = $mResponse->InReplyTo();
|
||||
$mResult['References'] = $mResponse->References();
|
||||
$mResult['Html'] = 0 === \strlen($sHtml) ? '' : \MailSo\Base\HtmlUtils::ClearHtml(
|
||||
$sHtml, $bHasExternals, $mFoundedCIDs, $aContentLocationUrls, $mFoundedContentLocationUrls);
|
||||
$sHtml, $bHasExternals, $mFoundedCIDs, $aContentLocationUrls, $mFoundedContentLocationUrls, false,
|
||||
!!$this->Config()->Get('labs', 'allow_smart_html_links', true));
|
||||
|
||||
$mResult['PlainRaw'] = $sPlain;
|
||||
$mResult['Plain'] = 0 === \strlen($sPlain) ? '' : \MailSo\Base\HtmlUtils::ConvertPlainToHtml($sPlain);
|
||||
|
|
@ -6418,7 +6419,7 @@ class Actions
|
|||
try
|
||||
{
|
||||
$oReadReceipt = \MailSo\Mime\Email::Parse($mResult['ReadReceipt']);
|
||||
if ($oReadReceipt && \strtolower($oAccount->Email()) === \strtolower($oReadReceipt->GetEmail()))
|
||||
if (!$oReadReceipt || ($oReadReceipt && \strtolower($oAccount->Email()) === \strtolower($oReadReceipt->GetEmail())))
|
||||
{
|
||||
$mResult['ReadReceipt'] = '';
|
||||
}
|
||||
|
|
@ -6495,13 +6496,13 @@ class Actions
|
|||
'CID' => $mResponse->Cid(),
|
||||
'ContentLocation' => $mResponse->ContentLocation(),
|
||||
'IsInline' => $mResponse->IsInline(),
|
||||
'IsLinked' => ($mFoundedCIDs && \in_array(trim(trim($mResponse->Cid()), '<>'), $mFoundedCIDs)) ||
|
||||
'IsLinked' => ($mFoundedCIDs && \in_array(\trim(\trim($mResponse->Cid()), '<>'), $mFoundedCIDs)) ||
|
||||
($mFoundedContentLocationUrls && \in_array(\trim($mResponse->ContentLocation()), $mFoundedContentLocationUrls))
|
||||
));
|
||||
|
||||
$mResult['Download'] = \RainLoop\Utils::EncodeKeyValues(array(
|
||||
'V' => APP_VERSION,
|
||||
'Account' => $oAccount ? md5($oAccount->Hash()) : '',
|
||||
'Account' => $oAccount ? \md5($oAccount->Hash()) : '',
|
||||
'Folder' => $mResult['Folder'],
|
||||
'Uid' => $mResult['Uid'],
|
||||
'MimeIndex' => $mResult['MimeIndex'],
|
||||
|
|
@ -6513,7 +6514,7 @@ class Actions
|
|||
{
|
||||
$aExtended = null;
|
||||
$mStatus = $mResponse->Status();
|
||||
if (is_array($mStatus) && isset($mStatus['MESSAGES'], $mStatus['UNSEEN'], $mStatus['UIDNEXT']))
|
||||
if (\is_array($mStatus) && isset($mStatus['MESSAGES'], $mStatus['UNSEEN'], $mStatus['UIDNEXT']))
|
||||
{
|
||||
$aExtended = array(
|
||||
'MessageCount' => (int) $mStatus['MESSAGES'],
|
||||
|
|
@ -6524,7 +6525,7 @@ class Actions
|
|||
);
|
||||
}
|
||||
|
||||
$mResult = array_merge($this->objectData($mResponse, $sParent, $aParameters), array(
|
||||
$mResult = \array_merge($this->objectData($mResponse, $sParent, $aParameters), array(
|
||||
'Name' => $mResponse->Name(),
|
||||
'FullName' => $mResponse->FullName(),
|
||||
'FullNameRaw' => $mResponse->FullNameRaw(),
|
||||
|
|
@ -6541,7 +6542,7 @@ class Actions
|
|||
}
|
||||
else if ('MailSo\Mail\MessageCollection' === $sClassName)
|
||||
{
|
||||
$mResult = array_merge($this->objectData($mResponse, $sParent, $aParameters), array(
|
||||
$mResult = \array_merge($this->objectData($mResponse, $sParent, $aParameters), array(
|
||||
'MessageCount' => $mResponse->MessageCount,
|
||||
'MessageUnseenCount' => $mResponse->MessageUnseenCount,
|
||||
'MessageResultCount' => $mResponse->MessageResultCount,
|
||||
|
|
@ -6557,13 +6558,13 @@ class Actions
|
|||
}
|
||||
else if ('MailSo\Mail\AttachmentCollection' === $sClassName)
|
||||
{
|
||||
$mResult = array_merge($this->objectData($mResponse, $sParent, $aParameters), array(
|
||||
$mResult = \array_merge($this->objectData($mResponse, $sParent, $aParameters), array(
|
||||
'InlineCount' => $mResponse->InlineCount()
|
||||
));
|
||||
}
|
||||
else if ('MailSo\Mail\FolderCollection' === $sClassName)
|
||||
{
|
||||
$mResult = array_merge($this->objectData($mResponse, $sParent, $aParameters), array(
|
||||
$mResult = \array_merge($this->objectData($mResponse, $sParent, $aParameters), array(
|
||||
'Namespace' => $mResponse->GetNamespace(),
|
||||
'FoldersHash' => isset($mResponse->FoldersHash) ? $mResponse->FoldersHash : '',
|
||||
'IsThreadsSupported' => $mResponse->IsThreadsSupported,
|
||||
|
|
@ -6579,7 +6580,7 @@ class Actions
|
|||
}
|
||||
else
|
||||
{
|
||||
$mResult = '['.get_class($mResponse).']';
|
||||
$mResult = '['.\get_class($mResponse).']';
|
||||
$bHook = false;
|
||||
}
|
||||
|
||||
|
|
@ -6588,7 +6589,7 @@ class Actions
|
|||
$this->Plugins()->RunHook('filter.response-object', array($sClassName, $mResult), false);
|
||||
}
|
||||
}
|
||||
else if (is_array($mResponse))
|
||||
else if (\is_array($mResponse))
|
||||
{
|
||||
foreach ($mResponse as $iKey => $oItem)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,252 +1,253 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Config;
|
||||
|
||||
class Application extends \RainLoop\Config\AbstractConfig
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('application.ini',
|
||||
'; RainLoop Webmail configuration file
|
||||
; Please don\'t add custom parameters here, those will be overwritten');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPassword
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function SetPassword($sPassword)
|
||||
{
|
||||
return $this->Set('security', 'admin_password', \md5(APP_SALT.$sPassword.APP_SALT));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPassword
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ValidatePassword($sPassword)
|
||||
{
|
||||
$sPassword = (string) $sPassword;
|
||||
$sConfigPassword = (string) $this->Get('security', 'admin_password', '');
|
||||
|
||||
return 0 < \strlen($sPassword) &&
|
||||
($sPassword === $sConfigPassword || \md5(APP_SALT.$sPassword.APP_SALT) === $sConfigPassword);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function Save()
|
||||
{
|
||||
$this->Set('version', 'current', APP_VERSION);
|
||||
$this->Set('version', 'saved', \gmdate('r'));
|
||||
|
||||
return parent::Save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function defaultValues()
|
||||
{
|
||||
return array(
|
||||
'webmail' => array(
|
||||
|
||||
'title' => array('RainLoop Webmail', 'Text displayed as page title'),
|
||||
'loading_description' => array('RainLoop', 'Text displayed on startup'),
|
||||
|
||||
'theme' => array('Default', 'Theme used by default'),
|
||||
'allow_themes' => array(true, 'Allow theme selection on settings screen'),
|
||||
'allow_custom_theme' => array(true, ''),
|
||||
|
||||
'language' => array('en', 'Language used by default'),
|
||||
'allow_languages_on_settings' => array(true, 'Allow language selection on settings screen'),
|
||||
|
||||
'allow_additional_accounts' => array(true, ''),
|
||||
'allow_identities' => array(true, ''),
|
||||
|
||||
'messages_per_page' => array(20, ' Number of messages displayed on page by default'),
|
||||
|
||||
'editor_default_type' => array('Html', 'Editor mode used by default (Html or Plain)'),
|
||||
|
||||
'attachment_size_limit' => array(5,
|
||||
'File size limit (MB) for file upload on compose screen
|
||||
0 for unlimited.')
|
||||
),
|
||||
|
||||
'branding' => array(
|
||||
'login_logo' => array(''),
|
||||
'login_desc' => array(''),
|
||||
'login_css' => array(''),
|
||||
),
|
||||
|
||||
'contacts' => array(
|
||||
'enable' => array(false, 'Enable contacts'),
|
||||
'allow_sharing' => array(true),
|
||||
'allow_sync' => array(false),
|
||||
'suggestions_limit' => array(30),
|
||||
'type' => array('sqlite', ''),
|
||||
'pdo_dsn' => array('mysql:host=127.0.0.1;port=3306;dbname=rainloop', ''),
|
||||
'pdo_user' => array('root', ''),
|
||||
'pdo_password' => array('', ''),
|
||||
),
|
||||
|
||||
'security' => array(
|
||||
'csrf_protection' => array(true,
|
||||
'Enable CSRF protection (http://en.wikipedia.org/wiki/Cross-site_request_forgery)'),
|
||||
|
||||
'custom_server_signature' => array('RainLoop'),
|
||||
'openpgp' => array(false),
|
||||
'admin_login' => array('admin', 'Login and password for web admin panel'),
|
||||
'admin_password' => array('12345'),
|
||||
'allow_admin_panel' => array(true, 'Access settings'),
|
||||
'admin_panel_host' => array(''),
|
||||
'core_install_access_domains' => array('')
|
||||
),
|
||||
|
||||
'login' => array(
|
||||
|
||||
'allow_custom_login' => array(false,
|
||||
'Enable additional Login field on webmail login screen'),
|
||||
|
||||
'default_domain' => array('', ''),
|
||||
|
||||
'allow_languages_on_login' => array(true,
|
||||
'Allow language selection on webmail login screen'),
|
||||
|
||||
'sign_me_auto' => array(\RainLoop\Enumerations\SignMeType::DEFAILT_OFF,
|
||||
'This option allows webmail to remember the logged in user
|
||||
once they closed the browser window.
|
||||
|
||||
Values:
|
||||
"DefaultOff" - can be used, disabled by default;
|
||||
"DefaultOn" - can be used, enabled by default;
|
||||
"Unused" - cannot be used')
|
||||
),
|
||||
|
||||
'plugins' => array(
|
||||
'enable' => array(false, 'Enable plugin support'),
|
||||
'enabled_list' => array('', 'List of enabled plugins'),
|
||||
),
|
||||
|
||||
'logs' => array(
|
||||
|
||||
'enable' => array(false, 'Enable logging'),
|
||||
|
||||
'write_on_error_only' => array(false, 'Logs entire request only if error occured'),
|
||||
|
||||
'filename' => array('log-{date:Y-m-d}.txt',
|
||||
'Log filename.
|
||||
For security reasons, some characters are removed from filename.
|
||||
Allows for pattern-based folder creation (see examples below).
|
||||
|
||||
Patterns:
|
||||
{date:Y-m-d} - Replaced by pattern-based date
|
||||
Detailed info: http://www.php.net/manual/en/function.date.php
|
||||
{user:email} - Replaced by user\'s email address
|
||||
If user is not logged in, value is set to "unknown"
|
||||
{user:login} - Replaced by user\'s login
|
||||
If user is not logged in, value is set to "unknown"
|
||||
{user:domain} - Replaced by user\'s domain name
|
||||
If user is not logged in, value is set to "unknown"
|
||||
{user:uid} - Replaced by user\'s UID regardless of account currently used
|
||||
|
||||
Examples:
|
||||
filename = "log-{date:Y-m-d}.txt"
|
||||
filename = "{date:Y-m-d}/{user:domain}/{user:email}_{user:uid}.log"
|
||||
filename = "{user:email}-{date:Y-m-d}.txt"')
|
||||
),
|
||||
|
||||
'debug' => array(
|
||||
'enable' => array(false, 'Special option required for development purposes'),
|
||||
),
|
||||
|
||||
'version' => array(
|
||||
'current' => array(''),
|
||||
'saved' => array('')
|
||||
),
|
||||
|
||||
'social' => array(
|
||||
'google_enable' => array(false, 'Google'),
|
||||
'google_client_id' => array(''),
|
||||
'google_client_secret' => array(''),
|
||||
|
||||
'fb_enable' => array(false, 'Facebook'),
|
||||
'fb_app_id' => array(''),
|
||||
'fb_app_secret' => array(''),
|
||||
|
||||
'twitter_enable' => array(false, 'Twitter'),
|
||||
'twitter_consumer_key' => array(''),
|
||||
'twitter_consumer_secret' => array(''),
|
||||
|
||||
'dropbox_enable' => array(false, 'Dropbox'),
|
||||
'dropbox_api_key' => array(''),
|
||||
),
|
||||
|
||||
'cache' => array(
|
||||
'enable' => array(true,
|
||||
'The section controls caching of the entire application.
|
||||
|
||||
Enables caching in the system'),
|
||||
|
||||
'index' => array('v1', 'Additional caching key. If changed, cache is purged'),
|
||||
|
||||
'fast_cache_driver' => array('files', 'Can be: files, APC, memcache'),
|
||||
'fast_cache_index' => array('v1', 'Additional caching key. If changed, fast cache is purged'),
|
||||
|
||||
'http' => array(true, 'Browser-level cache. If enabled, caching is maintainted without using files'),
|
||||
'server_uids' => array(false, 'Caching message UIDs when searching and sorting (threading)')
|
||||
),
|
||||
|
||||
'labs' => array(
|
||||
'ignore_folders_subscription' => array(false,
|
||||
'Experimental settings. Handle with care.
|
||||
'),
|
||||
'sync_dav_digest_auth' => array(true),
|
||||
'sync_dav_domain' => array(''),
|
||||
'sync_use_dav_browser' => array(true),
|
||||
'allow_message_append' => array(false),
|
||||
'date_from_headers' => array(false),
|
||||
'cache_system_data' => array(true),
|
||||
'use_app_debug_js' => array(false),
|
||||
'use_app_debug_css' => array(false),
|
||||
'use_dav_digest_auth' => array(false),
|
||||
'login_fault_delay' => array(1),
|
||||
'log_ajax_response_write_limit' => array(300),
|
||||
'determine_user_language' => array(true),
|
||||
'use_imap_sort' => array(false),
|
||||
'use_imap_force_selection' => array(false),
|
||||
'use_imap_list_subscribe' => array(true),
|
||||
'use_imap_thread' => array(true),
|
||||
'use_imap_move' => array(true),
|
||||
'use_imap_auth_plain' => array(false),
|
||||
'imap_forwarded_flag' => array('$Forwarded'),
|
||||
'imap_read_receipt_flag' => array('$ReadReceipt'),
|
||||
'smtp_show_server_errors' => array(false),
|
||||
'allow_prefetch' => array(true),
|
||||
'autocreate_system_folders' => array(true),
|
||||
'repo_type' => array('stable'),
|
||||
'custom_repo' => array(''),
|
||||
'additional_repo' => array(''),
|
||||
'cdn_static_domain' => array(''),
|
||||
'curl_proxy' => array(''),
|
||||
'curl_proxy_auth' => array(''),
|
||||
'in_iframe' => array(false),
|
||||
'custom_login_link' => array(''),
|
||||
'custom_logout_link' => array(''),
|
||||
'allow_external_login' => array(false),
|
||||
'fast_cache_memcache_host' => array('127.0.0.1'),
|
||||
'fast_cache_memcache_port' => array(11211),
|
||||
'fast_cache_memcache_expire' => array(43200),
|
||||
'dev_email' => array(''),
|
||||
'dev_login' => array(''),
|
||||
'dev_password' => array('')
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace RainLoop\Config;
|
||||
|
||||
class Application extends \RainLoop\Config\AbstractConfig
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('application.ini',
|
||||
'; RainLoop Webmail configuration file
|
||||
; Please don\'t add custom parameters here, those will be overwritten');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPassword
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function SetPassword($sPassword)
|
||||
{
|
||||
return $this->Set('security', 'admin_password', \md5(APP_SALT.$sPassword.APP_SALT));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPassword
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ValidatePassword($sPassword)
|
||||
{
|
||||
$sPassword = (string) $sPassword;
|
||||
$sConfigPassword = (string) $this->Get('security', 'admin_password', '');
|
||||
|
||||
return 0 < \strlen($sPassword) &&
|
||||
($sPassword === $sConfigPassword || \md5(APP_SALT.$sPassword.APP_SALT) === $sConfigPassword);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function Save()
|
||||
{
|
||||
$this->Set('version', 'current', APP_VERSION);
|
||||
$this->Set('version', 'saved', \gmdate('r'));
|
||||
|
||||
return parent::Save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function defaultValues()
|
||||
{
|
||||
return array(
|
||||
'webmail' => array(
|
||||
|
||||
'title' => array('RainLoop Webmail', 'Text displayed as page title'),
|
||||
'loading_description' => array('RainLoop', 'Text displayed on startup'),
|
||||
|
||||
'theme' => array('Default', 'Theme used by default'),
|
||||
'allow_themes' => array(true, 'Allow theme selection on settings screen'),
|
||||
'allow_custom_theme' => array(true, ''),
|
||||
|
||||
'language' => array('en', 'Language used by default'),
|
||||
'allow_languages_on_settings' => array(true, 'Allow language selection on settings screen'),
|
||||
|
||||
'allow_additional_accounts' => array(true, ''),
|
||||
'allow_identities' => array(true, ''),
|
||||
|
||||
'messages_per_page' => array(20, ' Number of messages displayed on page by default'),
|
||||
|
||||
'editor_default_type' => array('Html', 'Editor mode used by default (Html or Plain)'),
|
||||
|
||||
'attachment_size_limit' => array(5,
|
||||
'File size limit (MB) for file upload on compose screen
|
||||
0 for unlimited.')
|
||||
),
|
||||
|
||||
'branding' => array(
|
||||
'login_logo' => array(''),
|
||||
'login_desc' => array(''),
|
||||
'login_css' => array(''),
|
||||
),
|
||||
|
||||
'contacts' => array(
|
||||
'enable' => array(false, 'Enable contacts'),
|
||||
'allow_sharing' => array(true),
|
||||
'allow_sync' => array(false),
|
||||
'suggestions_limit' => array(30),
|
||||
'type' => array('sqlite', ''),
|
||||
'pdo_dsn' => array('mysql:host=127.0.0.1;port=3306;dbname=rainloop', ''),
|
||||
'pdo_user' => array('root', ''),
|
||||
'pdo_password' => array('', ''),
|
||||
),
|
||||
|
||||
'security' => array(
|
||||
'csrf_protection' => array(true,
|
||||
'Enable CSRF protection (http://en.wikipedia.org/wiki/Cross-site_request_forgery)'),
|
||||
|
||||
'custom_server_signature' => array('RainLoop'),
|
||||
'openpgp' => array(false),
|
||||
'admin_login' => array('admin', 'Login and password for web admin panel'),
|
||||
'admin_password' => array('12345'),
|
||||
'allow_admin_panel' => array(true, 'Access settings'),
|
||||
'admin_panel_host' => array(''),
|
||||
'core_install_access_domains' => array('')
|
||||
),
|
||||
|
||||
'login' => array(
|
||||
|
||||
'allow_custom_login' => array(false,
|
||||
'Enable additional Login field on webmail login screen'),
|
||||
|
||||
'default_domain' => array('', ''),
|
||||
|
||||
'allow_languages_on_login' => array(true,
|
||||
'Allow language selection on webmail login screen'),
|
||||
|
||||
'sign_me_auto' => array(\RainLoop\Enumerations\SignMeType::DEFAILT_OFF,
|
||||
'This option allows webmail to remember the logged in user
|
||||
once they closed the browser window.
|
||||
|
||||
Values:
|
||||
"DefaultOff" - can be used, disabled by default;
|
||||
"DefaultOn" - can be used, enabled by default;
|
||||
"Unused" - cannot be used')
|
||||
),
|
||||
|
||||
'plugins' => array(
|
||||
'enable' => array(false, 'Enable plugin support'),
|
||||
'enabled_list' => array('', 'List of enabled plugins'),
|
||||
),
|
||||
|
||||
'logs' => array(
|
||||
|
||||
'enable' => array(false, 'Enable logging'),
|
||||
|
||||
'write_on_error_only' => array(false, 'Logs entire request only if error occured'),
|
||||
|
||||
'filename' => array('log-{date:Y-m-d}.txt',
|
||||
'Log filename.
|
||||
For security reasons, some characters are removed from filename.
|
||||
Allows for pattern-based folder creation (see examples below).
|
||||
|
||||
Patterns:
|
||||
{date:Y-m-d} - Replaced by pattern-based date
|
||||
Detailed info: http://www.php.net/manual/en/function.date.php
|
||||
{user:email} - Replaced by user\'s email address
|
||||
If user is not logged in, value is set to "unknown"
|
||||
{user:login} - Replaced by user\'s login
|
||||
If user is not logged in, value is set to "unknown"
|
||||
{user:domain} - Replaced by user\'s domain name
|
||||
If user is not logged in, value is set to "unknown"
|
||||
{user:uid} - Replaced by user\'s UID regardless of account currently used
|
||||
|
||||
Examples:
|
||||
filename = "log-{date:Y-m-d}.txt"
|
||||
filename = "{date:Y-m-d}/{user:domain}/{user:email}_{user:uid}.log"
|
||||
filename = "{user:email}-{date:Y-m-d}.txt"')
|
||||
),
|
||||
|
||||
'debug' => array(
|
||||
'enable' => array(false, 'Special option required for development purposes'),
|
||||
),
|
||||
|
||||
'version' => array(
|
||||
'current' => array(''),
|
||||
'saved' => array('')
|
||||
),
|
||||
|
||||
'social' => array(
|
||||
'google_enable' => array(false, 'Google'),
|
||||
'google_client_id' => array(''),
|
||||
'google_client_secret' => array(''),
|
||||
|
||||
'fb_enable' => array(false, 'Facebook'),
|
||||
'fb_app_id' => array(''),
|
||||
'fb_app_secret' => array(''),
|
||||
|
||||
'twitter_enable' => array(false, 'Twitter'),
|
||||
'twitter_consumer_key' => array(''),
|
||||
'twitter_consumer_secret' => array(''),
|
||||
|
||||
'dropbox_enable' => array(false, 'Dropbox'),
|
||||
'dropbox_api_key' => array(''),
|
||||
),
|
||||
|
||||
'cache' => array(
|
||||
'enable' => array(true,
|
||||
'The section controls caching of the entire application.
|
||||
|
||||
Enables caching in the system'),
|
||||
|
||||
'index' => array('v1', 'Additional caching key. If changed, cache is purged'),
|
||||
|
||||
'fast_cache_driver' => array('files', 'Can be: files, APC, memcache'),
|
||||
'fast_cache_index' => array('v1', 'Additional caching key. If changed, fast cache is purged'),
|
||||
|
||||
'http' => array(true, 'Browser-level cache. If enabled, caching is maintainted without using files'),
|
||||
'server_uids' => array(false, 'Caching message UIDs when searching and sorting (threading)')
|
||||
),
|
||||
|
||||
'labs' => array(
|
||||
'ignore_folders_subscription' => array(false,
|
||||
'Experimental settings. Handle with care.
|
||||
'),
|
||||
'allow_prefetch' => array(true),
|
||||
'allow_smart_html_links' => array(true),
|
||||
'cache_system_data' => array(true),
|
||||
'date_from_headers' => array(false),
|
||||
'autocreate_system_folders' => array(true),
|
||||
'allow_message_append' => array(false),
|
||||
'determine_user_language' => array(true),
|
||||
'login_fault_delay' => array(1),
|
||||
'log_ajax_response_write_limit' => array(300),
|
||||
'sync_dav_digest_auth' => array(true),
|
||||
'sync_dav_domain' => array(''),
|
||||
'sync_use_dav_browser' => array(true),
|
||||
'use_app_debug_js' => array(false),
|
||||
'use_app_debug_css' => array(false),
|
||||
'use_imap_sort' => array(false),
|
||||
'use_imap_force_selection' => array(false),
|
||||
'use_imap_list_subscribe' => array(true),
|
||||
'use_imap_thread' => array(true),
|
||||
'use_imap_move' => array(true),
|
||||
'use_imap_auth_plain' => array(false),
|
||||
'imap_forwarded_flag' => array('$Forwarded'),
|
||||
'imap_read_receipt_flag' => array('$ReadReceipt'),
|
||||
'smtp_show_server_errors' => array(false),
|
||||
'repo_type' => array('stable'),
|
||||
'custom_repo' => array(''),
|
||||
'additional_repo' => array(''),
|
||||
'cdn_static_domain' => array(''),
|
||||
'curl_proxy' => array(''),
|
||||
'curl_proxy_auth' => array(''),
|
||||
'in_iframe' => array(false),
|
||||
'custom_login_link' => array(''),
|
||||
'custom_logout_link' => array(''),
|
||||
'allow_external_login' => array(false),
|
||||
'in_iframe' => array(false),
|
||||
'fast_cache_memcache_host' => array('127.0.0.1'),
|
||||
'fast_cache_memcache_port' => array(11211),
|
||||
'fast_cache_memcache_expire' => array(43200),
|
||||
'dev_email' => array(''),
|
||||
'dev_login' => array(''),
|
||||
'dev_password' => array('')
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue