mirror of
https://github.com/the-djmaze/snappymail.git
synced 2024-12-26 00:51:24 +08:00
Small fixes
This commit is contained in:
parent
300cee0b6e
commit
3e9a7a55c6
15 changed files with 405 additions and 292 deletions
|
@ -21,7 +21,6 @@
|
|||
;
|
||||
|
||||
this.capa = !!Settings.settingsGet('PremType');
|
||||
this.capa = true;
|
||||
|
||||
this.title = ko.observable(Settings.settingsGet('Title'));
|
||||
this.title.trigger = ko.observable(Enums.SaveSettingsStep.Idle);
|
||||
|
@ -37,6 +36,8 @@
|
|||
|
||||
this.loginCss = ko.observable(Settings.settingsGet('LoginCss'));
|
||||
this.loginCss.trigger = ko.observable(Enums.SaveSettingsStep.Idle);
|
||||
|
||||
this.loginPowered = ko.observable(!!Settings.settingsGet('LoginPowered'));
|
||||
}
|
||||
|
||||
BrandingAdminSetting.prototype.onBuild = function ()
|
||||
|
@ -46,30 +47,37 @@
|
|||
Remote = require('Storage/Admin/Remote')
|
||||
;
|
||||
|
||||
_.delay(function () {
|
||||
|
||||
var
|
||||
f1 = Utils.settingsSaveHelperSimpleFunction(self.title.trigger, self),
|
||||
f2 = Utils.settingsSaveHelperSimpleFunction(self.loadingDesc.trigger, self)
|
||||
;
|
||||
|
||||
self.title.subscribe(function (sValue) {
|
||||
Remote.saveAdminConfig(f1, {
|
||||
'Title': Utils.trim(sValue)
|
||||
});
|
||||
});
|
||||
|
||||
self.loadingDesc.subscribe(function (sValue) {
|
||||
Remote.saveAdminConfig(f2, {
|
||||
'LoadingDescription': Utils.trim(sValue)
|
||||
});
|
||||
});
|
||||
|
||||
}, 50);
|
||||
|
||||
if (this.capa)
|
||||
{
|
||||
_.delay(function () {
|
||||
|
||||
var
|
||||
f1 = Utils.settingsSaveHelperSimpleFunction(self.title.trigger, self),
|
||||
f2 = Utils.settingsSaveHelperSimpleFunction(self.loadingDesc.trigger, self),
|
||||
f3 = Utils.settingsSaveHelperSimpleFunction(self.loginLogo.trigger, self),
|
||||
f4 = Utils.settingsSaveHelperSimpleFunction(self.loginDescription.trigger, self),
|
||||
f5 = Utils.settingsSaveHelperSimpleFunction(self.loginCss.trigger, self)
|
||||
;
|
||||
|
||||
self.title.subscribe(function (sValue) {
|
||||
Remote.saveAdminConfig(f1, {
|
||||
'Title': Utils.trim(sValue)
|
||||
});
|
||||
});
|
||||
|
||||
self.loadingDesc.subscribe(function (sValue) {
|
||||
Remote.saveAdminConfig(f2, {
|
||||
'LoadingDescription': Utils.trim(sValue)
|
||||
});
|
||||
});
|
||||
|
||||
self.loginLogo.subscribe(function (sValue) {
|
||||
Remote.saveAdminConfig(f3, {
|
||||
'LoginLogo': Utils.trim(sValue)
|
||||
|
@ -88,7 +96,13 @@
|
|||
});
|
||||
});
|
||||
|
||||
}, 50);
|
||||
self.loginPowered.subscribe(function (bValue) {
|
||||
Remote.saveAdminConfig(null, {
|
||||
'LoginPowered': bValue ? '1' : '0'
|
||||
});
|
||||
});
|
||||
|
||||
}, 100);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
.b-admin-branding {
|
||||
.disabled-form {
|
||||
opacity: 0.5;
|
||||
opacity: 0.4;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -206,6 +206,14 @@ select {
|
|||
margin-left: 0;
|
||||
}
|
||||
|
||||
.alert a {
|
||||
color: #c09853;
|
||||
}
|
||||
|
||||
.alert.alert-info a {
|
||||
color: #3a87ad;
|
||||
}
|
||||
|
||||
.alert.alert-error a {
|
||||
color: #b94a48;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
this.adminManLoadingVisibility = Data.adminManLoadingVisibility;
|
||||
this.capa = !!Settings.settingsGet('PremType');
|
||||
this.capa = false;
|
||||
this.capa = false; // TODO
|
||||
|
||||
kn.constructorEnd(this);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
this.logoImg = Utils.trim(Settings.settingsGet('LoginLogo'));
|
||||
this.loginDescription = Utils.trim(Settings.settingsGet('LoginDescription'));
|
||||
this.logoCss = Utils.trim(Settings.settingsGet('LoginCss'));
|
||||
this.logoPowered = !!Settings.settingsGet('LoginPowered');
|
||||
|
||||
this.emailError = ko.observable(false);
|
||||
this.passwordError = ko.observable(false);
|
||||
|
|
|
@ -29,7 +29,6 @@ var
|
|||
gulp = require('gulp'),
|
||||
concat = require('gulp-concat-util'),
|
||||
header = require('gulp-header'),
|
||||
footer = require('gulp-footer'),
|
||||
eol = require('gulp-eol'),
|
||||
rename = require('gulp-rename'),
|
||||
replace = require('gulp-replace'),
|
||||
|
@ -225,8 +224,8 @@ gulp.task('js:boot', function() {
|
|||
gulp.task('js:encrypt', function() {
|
||||
return gulp.src(cfg.paths.js.encrypt.src)
|
||||
.pipe(concat(cfg.paths.js.encrypt.name))
|
||||
.pipe(header(cfg.paths.js.encrypt.header || ''))
|
||||
.pipe(footer(cfg.paths.js.encrypt.footer || ''))
|
||||
.pipe(concat.header(cfg.paths.js.encrypt.header || ''))
|
||||
.pipe(concat.footer(cfg.paths.js.encrypt.footer || ''))
|
||||
.pipe(uglify(cfg.uglify))
|
||||
.pipe(eol('\n', true))
|
||||
.pipe(gulp.dest(cfg.paths.js.encrypt.dest))
|
||||
|
|
|
@ -57,7 +57,6 @@
|
|||
"gulp-rename": "*",
|
||||
"gulp-replace": "*",
|
||||
"gulp-header": "*",
|
||||
"gulp-footer": "*",
|
||||
"gulp-eol": "*",
|
||||
"gulp-minify-css": "*",
|
||||
"gulp-autoprefixer": "*",
|
||||
|
|
|
@ -1,164 +1,164 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Cache;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Cache
|
||||
*/
|
||||
class CacheClient
|
||||
{
|
||||
/**
|
||||
* @var \MailSo\Cache\DriverInterface
|
||||
*/
|
||||
private $oDriver;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sCacheIndex;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
$this->oDriver = null;
|
||||
$this->sCacheIndex = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Cache\CacheClient
|
||||
*/
|
||||
public static function NewInstance()
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
* @param string $sValue
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Set($sKey, $sValue)
|
||||
{
|
||||
return $this->oDriver ? $this->oDriver->Set($sKey.$this->sCacheIndex, $sValue) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function SetTimer($sKey)
|
||||
{
|
||||
return $this->Set($sKey.'/TIMER', time());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
* @param string $bClearAfterGet = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Get($sKey, $bClearAfterGet = false)
|
||||
{
|
||||
$sValue = '';
|
||||
|
||||
if ($this->oDriver)
|
||||
{
|
||||
$sValue = $this->oDriver->Get($sKey.$this->sCacheIndex);
|
||||
}
|
||||
|
||||
if ($bClearAfterGet)
|
||||
{
|
||||
$this->Delete($sKey);
|
||||
}
|
||||
|
||||
return $sValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function GetTimer($sKey)
|
||||
{
|
||||
$iTimer = 0;
|
||||
$sValue = $this->Get($sKey.'/TIMER');
|
||||
if (0 < strlen($sValue) && is_numeric($sValue))
|
||||
{
|
||||
$iTimer = (int) $sValue;
|
||||
}
|
||||
|
||||
return $iTimer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return \MailSo\Cache\CacheClient
|
||||
*/
|
||||
public function Delete($sKey)
|
||||
{
|
||||
if ($this->oDriver)
|
||||
{
|
||||
$this->oDriver->Delete($sKey.$this->sCacheIndex);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Cache\DriverInterface $oDriver
|
||||
*
|
||||
* @return \MailSo\Cache\CacheClient
|
||||
*/
|
||||
public function SetDriver(\MailSo\Cache\DriverInterface $oDriver)
|
||||
{
|
||||
$this->oDriver = $oDriver;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iTimeToClearInHours = 24
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function GC($iTimeToClearInHours = 24)
|
||||
{
|
||||
return $this->oDriver ? $this->oDriver->GC($iTimeToClearInHours) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsInited()
|
||||
{
|
||||
return $this->oDriver instanceof \MailSo\Cache\DriverInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sCacheIndex
|
||||
*
|
||||
* @return \MailSo\Cache\CacheClient
|
||||
*/
|
||||
public function SetCacheIndex($sCacheIndex)
|
||||
{
|
||||
$this->sCacheIndex = 0 < \strlen($sCacheIndex) ? "\x0".$sCacheIndex : '';
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of MailSo.
|
||||
*
|
||||
* (c) 2014 Usenko Timur
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace MailSo\Cache;
|
||||
|
||||
/**
|
||||
* @category MailSo
|
||||
* @package Cache
|
||||
*/
|
||||
class CacheClient
|
||||
{
|
||||
/**
|
||||
* @var \MailSo\Cache\DriverInterface
|
||||
*/
|
||||
private $oDriver;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sCacheIndex;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
$this->oDriver = null;
|
||||
$this->sCacheIndex = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \MailSo\Cache\CacheClient
|
||||
*/
|
||||
public static function NewInstance()
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
* @param string $sValue
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Set($sKey, $sValue)
|
||||
{
|
||||
return $this->oDriver ? $this->oDriver->Set($sKey.$this->sCacheIndex, $sValue) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function SetTimer($sKey)
|
||||
{
|
||||
return $this->Set($sKey.'/TIMER', time());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
* @param string $bClearAfterGet = false
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Get($sKey, $bClearAfterGet = false)
|
||||
{
|
||||
$sValue = '';
|
||||
|
||||
if ($this->oDriver)
|
||||
{
|
||||
$sValue = $this->oDriver->Get($sKey.$this->sCacheIndex);
|
||||
}
|
||||
|
||||
if ($bClearAfterGet)
|
||||
{
|
||||
$this->Delete($sKey);
|
||||
}
|
||||
|
||||
return $sValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function GetTimer($sKey)
|
||||
{
|
||||
$iTimer = 0;
|
||||
$sValue = $this->Get($sKey.'/TIMER');
|
||||
if (0 < strlen($sValue) && is_numeric($sValue))
|
||||
{
|
||||
$iTimer = (int) $sValue;
|
||||
}
|
||||
|
||||
return $iTimer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sKey
|
||||
*
|
||||
* @return \MailSo\Cache\CacheClient
|
||||
*/
|
||||
public function Delete($sKey)
|
||||
{
|
||||
if ($this->oDriver)
|
||||
{
|
||||
$this->oDriver->Delete($sKey.$this->sCacheIndex);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Cache\DriverInterface $oDriver
|
||||
*
|
||||
* @return \MailSo\Cache\CacheClient
|
||||
*/
|
||||
public function SetDriver(\MailSo\Cache\DriverInterface $oDriver)
|
||||
{
|
||||
$this->oDriver = $oDriver;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iTimeToClearInHours = 24
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function GC($iTimeToClearInHours = 24)
|
||||
{
|
||||
return $this->oDriver ? $this->oDriver->GC($iTimeToClearInHours) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsInited()
|
||||
{
|
||||
return $this->oDriver instanceof \MailSo\Cache\DriverInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sCacheIndex
|
||||
*
|
||||
* @return \MailSo\Cache\CacheClient
|
||||
*/
|
||||
public function SetCacheIndex($sCacheIndex)
|
||||
{
|
||||
$this->sCacheIndex = 0 < \strlen($sCacheIndex) ? "\x0".$sCacheIndex : '';
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -330,7 +330,7 @@ class BodyStructure
|
|||
{
|
||||
$mResult = $this->SearchPlainParts();
|
||||
}
|
||||
|
||||
|
||||
return $mResult;
|
||||
}
|
||||
|
||||
|
@ -465,7 +465,7 @@ class BodyStructure
|
|||
* @param array $aParams
|
||||
* @param string $sParamName
|
||||
* @param string $sCharset = \MailSo\Base\Enumerations\Charset::UTF_8
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function decodeAttrParamenter($aParams, $sParamName, $sCharset = \MailSo\Base\Enumerations\Charset::UTF_8)
|
||||
|
@ -477,7 +477,7 @@ class BodyStructure
|
|||
}
|
||||
else if (isset($aParams[$sParamName.'*']))
|
||||
{
|
||||
$aValueParts = \explode('\'\'', $aParams[$sParamName.'*'], 2);
|
||||
$aValueParts = \explode("''", $aParams[$sParamName.'*'], 2);
|
||||
if (\is_array($aValueParts) && 2 === \count($aValueParts))
|
||||
{
|
||||
$sCharset = isset($aValueParts[0]) ? $aValueParts[0] : \MailSo\Base\Enumerations\Charset::UTF_8;
|
||||
|
@ -490,30 +490,30 @@ class BodyStructure
|
|||
$sResult = \urldecode($aParams[$sParamName.'*']);
|
||||
}
|
||||
}
|
||||
else if (isset($aParams[$sParamName.'*0*']))
|
||||
else
|
||||
{
|
||||
$sCharset = '';
|
||||
$sCharsetIndex = -1;
|
||||
|
||||
$aFileNames = array();
|
||||
foreach ($aParams as $sName => $sValue)
|
||||
{
|
||||
$aMatches = array();
|
||||
if ($sParamName.'*0*' === $sName)
|
||||
if (\preg_match('/^'.\preg_quote($sParamName, '/').'\*([0-9]+)\*$/i', $sName, $aMatches))
|
||||
{
|
||||
if (0 === \strlen($sCharset))
|
||||
$iIndex = (int) $aMatches[1];
|
||||
if ($sCharsetIndex < $iIndex && false !== \strpos($sValue, "''"))
|
||||
{
|
||||
$aValueParts = \explode('\'\'', $sValue, 2);
|
||||
$aValueParts = \explode("''", $sValue, 2);
|
||||
if (\is_array($aValueParts) && 2 === \count($aValueParts) && 0 < \strlen($aValueParts[0]))
|
||||
{
|
||||
$sCharsetIndex = $iIndex;
|
||||
$sCharset = $aValueParts[0];
|
||||
$sValue = $aValueParts[1];
|
||||
}
|
||||
}
|
||||
|
||||
$aFileNames[0] = $sValue;
|
||||
}
|
||||
else if ($sParamName.'*0*' !== $sName && \preg_match('/^'.\preg_quote($sParamName, '/').'\*([0-9]+)\*$/i', $sName, $aMatches) && 0 < \strlen($aMatches[1]))
|
||||
{
|
||||
$aFileNames[(int) $aMatches[1]] = $sValue;
|
||||
|
||||
$aFileNames[$iIndex] = $sValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -662,7 +662,7 @@ class BodyStructure
|
|||
{
|
||||
$sCharset = $aBodyParams['charset'];
|
||||
}
|
||||
|
||||
|
||||
if (\is_array($aBodyParams))
|
||||
{
|
||||
$sName = self::decodeAttrParamenter($aBodyParams, 'name', $sContentType);
|
||||
|
@ -675,7 +675,7 @@ class BodyStructure
|
|||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
$sContentID = $aBodyStructure[3];
|
||||
}
|
||||
|
||||
|
@ -685,7 +685,7 @@ class BodyStructure
|
|||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
$sDescription = $aBodyStructure[4];
|
||||
}
|
||||
|
||||
|
@ -867,7 +867,7 @@ class BodyStructure
|
|||
/**
|
||||
* @param array $aList
|
||||
* @param string $sPartID
|
||||
*
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
private static function findPartByIndexInArray(array $aList, $sPartID)
|
||||
|
|
|
@ -26,7 +26,7 @@ class ParameterCollection extends \MailSo\Base\Collection
|
|||
{
|
||||
parent::__construct();
|
||||
|
||||
if (0 < strlen($sRawParams))
|
||||
if (0 < \strlen($sRawParams))
|
||||
{
|
||||
$this->Parse($sRawParams);
|
||||
}
|
||||
|
@ -74,12 +74,12 @@ class ParameterCollection extends \MailSo\Base\Collection
|
|||
public function ParameterValueByName($sName)
|
||||
{
|
||||
$sResult = '';
|
||||
$sName = trim($sName);
|
||||
$sName = \trim($sName);
|
||||
|
||||
$aParams =& $this->GetAsArray();
|
||||
foreach ($aParams as /* @var $oParam \MailSo\Mime\ParameterCollection */ $oParam)
|
||||
{
|
||||
if (strtolower($sName) === strtolower($oParam->Name()))
|
||||
if (\strtolower($sName) === \strtolower($oParam->Name()))
|
||||
{
|
||||
$sResult = $oParam->Value();
|
||||
break;
|
||||
|
@ -98,7 +98,7 @@ class ParameterCollection extends \MailSo\Base\Collection
|
|||
{
|
||||
$this->Clear();
|
||||
|
||||
$aDataToParse = explode(';', $sRawParams);
|
||||
$aDataToParse = \explode(';', $sRawParams);
|
||||
|
||||
foreach ($aDataToParse as $sParam)
|
||||
{
|
||||
|
@ -122,13 +122,13 @@ class ParameterCollection extends \MailSo\Base\Collection
|
|||
foreach ($aParams as /* @var $oParam \MailSo\Mime\Parameter */ $oParam)
|
||||
{
|
||||
$sLine = $oParam->ToString($bConvertSpecialsName);
|
||||
if (0 < strlen($sLine))
|
||||
if (0 < \strlen($sLine))
|
||||
{
|
||||
$aResult[] = $sLine;
|
||||
}
|
||||
}
|
||||
|
||||
return 0 < count($aResult) ? implode('; ', $aResult) : '';
|
||||
return 0 < \count($aResult) ? \implode('; ', $aResult) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -147,8 +147,8 @@ class ParameterCollection extends \MailSo\Base\Collection
|
|||
$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 (\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]]))
|
||||
{
|
||||
|
@ -156,16 +156,20 @@ class ParameterCollection extends \MailSo\Base\Collection
|
|||
}
|
||||
|
||||
$sValue = $oParam->Value();
|
||||
$aValueParts = explode('\'\'', $sValue, 2);
|
||||
if (is_array($aValueParts) && 2 === count($aValueParts) && 0 < strlen($aValueParts[1]))
|
||||
|
||||
if (false !== \strpos($sValue, "''"))
|
||||
{
|
||||
$sCharset = $aValueParts[0];
|
||||
$sValue = $aValueParts[1];
|
||||
$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]))
|
||||
else if (\preg_match('/([^\*]+)\*/', $sParamName, $aMatch) && isset($aMatch[1]))
|
||||
{
|
||||
if (!isset($aPreParams[$aMatch[1]]))
|
||||
{
|
||||
|
@ -173,11 +177,14 @@ class ParameterCollection extends \MailSo\Base\Collection
|
|||
}
|
||||
|
||||
$sValue = $oParam->Value();
|
||||
$aValueParts = explode('\'\'', $sValue, 2);
|
||||
if (is_array($aValueParts) && 2 === count($aValueParts) && 0 < strlen($aValueParts[1]))
|
||||
if (false !== \strpos($sValue, "''"))
|
||||
{
|
||||
$sCharset = $aValueParts[0];
|
||||
$sValue = $aValueParts[1];
|
||||
$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;
|
||||
|
@ -191,10 +198,10 @@ class ParameterCollection extends \MailSo\Base\Collection
|
|||
foreach ($aPreParams as $sName => $aValues)
|
||||
{
|
||||
ksort($aValues);
|
||||
$sResult = implode(array_values($aValues));
|
||||
$sResult = urldecode($sResult);
|
||||
$sResult = \implode(\array_values($aValues));
|
||||
$sResult = \urldecode($sResult);
|
||||
|
||||
if (0 < strlen($sCharset))
|
||||
if (0 < \strlen($sCharset))
|
||||
{
|
||||
$sResult = \MailSo\Base\Utils::ConvertEncoding($sResult,
|
||||
$sCharset, \MailSo\Base\Enumerations\Charset::UTF_8);
|
||||
|
|
|
@ -958,7 +958,14 @@ class Actions
|
|||
*/
|
||||
private function PremType()
|
||||
{
|
||||
return false;
|
||||
static $bResult = null;
|
||||
if (null === $bResult)
|
||||
{
|
||||
// $bResult = $this->licenseParser($this->licenseHelper(false, true));
|
||||
$bResult = true;
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -993,6 +1000,7 @@ class Actions
|
|||
'LoginLogo' => '',
|
||||
'LoginDescription' => '',
|
||||
'LoginCss' => '',
|
||||
'LoginPowered' => true,
|
||||
'Token' => $oConfig->Get('security', 'csrf_protection', false) ? \RainLoop\Utils::GetCsrfToken() : '',
|
||||
'InIframe' => (bool) $oConfig->Get('labs', 'in_iframe', false),
|
||||
'AllowAdminPanel' => (bool) $oConfig->Get('security', 'allow_admin_panel', true),
|
||||
|
@ -1038,14 +1046,15 @@ class Actions
|
|||
$aResult['AuthAccountHash'] = $sAuthAccountHash;
|
||||
}
|
||||
|
||||
if ($this->PremType() || true)
|
||||
{
|
||||
$aResult['Title'] = $oConfig->Get('webmail', 'title', '');
|
||||
$aResult['LoadingDescription'] = $oConfig->Get('webmail', 'loading_description', '');
|
||||
$aResult['Title'] = $oConfig->Get('webmail', 'title', '');
|
||||
$aResult['LoadingDescription'] = $oConfig->Get('webmail', 'loading_description', '');
|
||||
|
||||
if ($this->PremType())
|
||||
{
|
||||
$aResult['LoginLogo'] = $oConfig->Get('branding', 'login_logo', '');
|
||||
$aResult['LoginDescription'] = $oConfig->Get('branding', 'login_desc', '');
|
||||
$aResult['LoginCss'] = $oConfig->Get('branding', 'login_css', '');
|
||||
$aResult['LoginPowered'] = !!$oConfig->Get('branding', 'login_powered', true);
|
||||
}
|
||||
|
||||
$oSettings = null;
|
||||
|
@ -2460,14 +2469,15 @@ class Actions
|
|||
$this->setConfigFromParams($oConfig, 'DetermineUserLanguage', 'login', 'determine_user_language', 'bool');
|
||||
$this->setConfigFromParams($oConfig, 'DetermineUserDomain', 'login', 'determine_user_domain', 'bool');
|
||||
|
||||
if ($this->PremType() || true)
|
||||
{
|
||||
$this->setConfigFromParams($oConfig, 'Title', 'webmail', 'title', 'string');
|
||||
$this->setConfigFromParams($oConfig, 'LoadingDescription', 'webmail', 'loading_description', 'string');
|
||||
$this->setConfigFromParams($oConfig, 'Title', 'webmail', 'title', 'string');
|
||||
$this->setConfigFromParams($oConfig, 'LoadingDescription', 'webmail', 'loading_description', 'string');
|
||||
|
||||
if ($this->HasOneOfActionParams(array('LoginLogo', 'LoginDescription', 'LoginCss', 'LoginPowered')) && $this->PremType())
|
||||
{
|
||||
$this->setConfigFromParams($oConfig, 'LoginLogo', 'branding', 'login_logo', 'string');
|
||||
$this->setConfigFromParams($oConfig, 'LoginDescription', 'branding', 'login_desc', 'string');
|
||||
$this->setConfigFromParams($oConfig, 'LoginCss', 'branding', 'login_css', 'string');
|
||||
$this->setConfigFromParams($oConfig, 'LoginPowered', 'branding', 'login_powered', 'bool');
|
||||
}
|
||||
|
||||
$this->setConfigFromParams($oConfig, 'TokenProtection', 'security', 'csrf_protection', 'bool');
|
||||
|
@ -2567,7 +2577,7 @@ class Actions
|
|||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function licenseHelper($sForce = false, $iCacheTimeInMin = 5)
|
||||
public function licenseHelper($sForce = false, $bLongCache = false, $iFastCacheTimeInMin = 5, $iLongCacheTimeInDays = 2)
|
||||
{
|
||||
$sDomain = APP_SITE;
|
||||
|
||||
|
@ -2582,15 +2592,31 @@ class Actions
|
|||
$sValue = '';
|
||||
if (!$sForce && $oCacher)
|
||||
{
|
||||
$iTime = $oCacher->GetTimer(\RainLoop\KeyPathHelper::LicensingDomainKeyValue($sDomain));
|
||||
if ($iTime + 60 * $iCacheTimeInMin > \time())
|
||||
if (!$bLongCache)
|
||||
{
|
||||
$sValue = $oCacher->Get(\RainLoop\KeyPathHelper::LicensingDomainKeyValue($sDomain));
|
||||
$iTime = $oCacher->GetTimer(\RainLoop\KeyPathHelper::LicensingDomainKeyValue($sDomain));
|
||||
if ($iTime + 60 * $iFastCacheTimeInMin > \time())
|
||||
{
|
||||
$sValue = $oCacher->Get(\RainLoop\KeyPathHelper::LicensingDomainKeyValue($sDomain));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$iTime = $oCacher->GetTimer(\RainLoop\KeyPathHelper::LicensingDomainKeyOtherValue($sDomain));
|
||||
if ($iTime + (60 * 60 * 24) * $iLongCacheTimeInDays > \time())
|
||||
{
|
||||
$sValue = $oCacher->Get(\RainLoop\KeyPathHelper::LicensingDomainKeyOtherValue($sDomain));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0 === \strlen($sValue))
|
||||
{
|
||||
if ($bLongCache && (!$oCacher || !$oCacher->SetTimer(\RainLoop\KeyPathHelper::LicensingDomainKeyOtherValue($sDomain))))
|
||||
{
|
||||
return 'NO';
|
||||
}
|
||||
|
||||
$iCode = 0;
|
||||
$sContentType = '';
|
||||
|
||||
|
@ -2607,14 +2633,33 @@ class Actions
|
|||
|
||||
if ($oCacher)
|
||||
{
|
||||
$oCacher->Set(\RainLoop\KeyPathHelper::LicensingDomainKeyValue($sDomain), $sValue);
|
||||
$oCacher->SetTimer(\RainLoop\KeyPathHelper::LicensingDomainKeyValue($sDomain));
|
||||
|
||||
$oCacher->Set(\RainLoop\KeyPathHelper::LicensingDomainKeyValue($sDomain), $sValue);
|
||||
$oCacher->Set(\RainLoop\KeyPathHelper::LicensingDomainKeyOtherValue($sDomain), $sValue);
|
||||
}
|
||||
}
|
||||
|
||||
return $sValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sInput
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function licenseParser($sInput)
|
||||
{
|
||||
$aMatch = array();
|
||||
if (\preg_match('/^EXPIRED:([\d]+)$/', $sInput, $aMatch))
|
||||
{
|
||||
$iTime = (int) $aMatch[1];
|
||||
return \time() < $iTime;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
|
@ -7183,6 +7228,24 @@ class Actions
|
|||
return isset($this->aCurrentActionParams[$sKey]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aKeys
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function HasOneOfActionParams($aKeys)
|
||||
{
|
||||
foreach ($aKeys as $sKey)
|
||||
{
|
||||
if ($this->HasActionParam($sKey))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sUrl
|
||||
*/
|
||||
|
|
|
@ -81,7 +81,8 @@ class Application extends \RainLoop\Config\AbstractConfig
|
|||
'branding' => array(
|
||||
'login_logo' => array(''),
|
||||
'login_desc' => array(''),
|
||||
'login_css' => array('')
|
||||
'login_css' => array(''),
|
||||
'login_powered' => array(true)
|
||||
),
|
||||
|
||||
'contacts' => array(
|
||||
|
|
|
@ -64,6 +64,16 @@ class KeyPathHelper
|
|||
return '/Licensing/DomainKey/Value/'.$sDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sDomain
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function LicensingDomainKeyOtherValue($sDomain)
|
||||
{
|
||||
return '/Licensing/DomainKeyOther/Value/'.$sDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sRepo
|
||||
* @param string $sRepoFile
|
||||
|
|
|
@ -1,66 +1,77 @@
|
|||
<div class="b-admin-branding">
|
||||
<div class="row" data-bind="visible: !capa">
|
||||
<div class="alert alert-error span8" style="margin-top: 10px;">
|
||||
<h4>Premium version only</h4>
|
||||
<br />
|
||||
<strong><a href="#/licensing">Licensing</a></strong>
|
||||
<div class="alert span8" style="margin-top: 10px;">
|
||||
Full functionality available in <strong><a href="#/licensing">Premium version</a></strong> only.
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-horizontal" data-bind="css: {'disabled-form': !capa}">
|
||||
<div class="legend">
|
||||
Branding
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">
|
||||
Page Title
|
||||
</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="span5" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-bind="value: title, saveTrigger: title.trigger, enable: capa" />
|
||||
<div data-bind="saveTrigger: title.trigger"></div>
|
||||
<div class="form-horizontal">
|
||||
<div>
|
||||
<div class="legend">
|
||||
Branding
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">
|
||||
Loading Description
|
||||
</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="span5" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-bind="value: loadingDesc, saveTrigger: loadingDesc.trigger, enable: capa" />
|
||||
<div data-bind="saveTrigger: loadingDesc.trigger"></div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">
|
||||
Page Title
|
||||
</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="span5" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-bind="value: title, saveTrigger: title.trigger" />
|
||||
<div data-bind="saveTrigger: title.trigger"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">
|
||||
Loading Description
|
||||
</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="span5" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-bind="value: loadingDesc, saveTrigger: loadingDesc.trigger" />
|
||||
<div data-bind="saveTrigger: loadingDesc.trigger"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div class="legend">
|
||||
Login Screen
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">
|
||||
Logo
|
||||
</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="span5" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
placeholder="https://" data-bind="value: loginLogo, saveTrigger: loginLogo.trigger, enable: capa" />
|
||||
<div data-bind="saveTrigger: loginLogo.trigger"></div>
|
||||
<div data-bind="css: {'disabled-form': !capa}">
|
||||
<div class="legend">
|
||||
Login Screen
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">
|
||||
Description
|
||||
</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="span5" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-bind="value: loginDescription, saveTrigger: loginDescription.trigger, enable: capa" />
|
||||
<div data-bind="saveTrigger: loginDescription.trigger"></div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">
|
||||
Logo
|
||||
</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="span5" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
placeholder="https://" data-bind="value: loginLogo, saveTrigger: loginLogo.trigger, enable: capa" />
|
||||
<div data-bind="saveTrigger: loginLogo.trigger"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">
|
||||
Custom CSS
|
||||
</label>
|
||||
<div class="controls">
|
||||
<textarea class="input-xxlarge" data-bind="value: loginCss, saveTrigger: loginCss.trigger, enable: capa" rows="7" spellcheck="true"></textarea>
|
||||
<div style="vertical-align: top;" data-bind="saveTrigger: loginCss.trigger"></div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">
|
||||
Description
|
||||
</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="span5" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-bind="value: loginDescription, saveTrigger: loginDescription.trigger, enable: capa" />
|
||||
<div data-bind="saveTrigger: loginDescription.trigger"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="control-group">
|
||||
<label class="control-label"></label>
|
||||
<div class="controls">
|
||||
<label data-bind="click: function () { if (capa) { loginPowered(!loginPowered()); }}">
|
||||
<i data-bind="css: loginPowered() ? 'icon-checkbox-checked' : 'icon-checkbox-unchecked'"></i>
|
||||
Show "Powered by RainLoop" link
|
||||
</label>
|
||||
</div>
|
||||
</div>-->
|
||||
<div class="control-group">
|
||||
<label class="control-label">
|
||||
Custom CSS
|
||||
</label>
|
||||
<div class="controls">
|
||||
<textarea class="input-xxlarge" data-bind="value: loginCss, saveTrigger: loginCss.trigger, enable: capa" rows="7" spellcheck="true"></textarea>
|
||||
<div style="vertical-align: top;" data-bind="saveTrigger: loginCss.trigger"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -113,7 +113,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="e-powered thm-powered">
|
||||
<div class="e-powered thm-powered" data-bind="visible: logoPowered">
|
||||
Powered by <a href="http://rainloop.net" target="_blank">RainLoop</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue