mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
Sieve filters (alpha / beta version coming soon)
This commit is contained in:
parent
02ba68868f
commit
94789632f0
33 changed files with 544 additions and 81 deletions
75
build/langs.php
Normal file
75
build/langs.php
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
define('LANGS_PATH', __DIR__.'/../rainloop/v/0.0.0/langs');
|
||||||
|
|
||||||
|
function getLangStructure($sLangFile)
|
||||||
|
{
|
||||||
|
$sEngLang = \file_get_contents(LANGS_PATH.'/'.$sLangFile);
|
||||||
|
return $sEngLang ? \parse_ini_string($sEngLang, true) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mergeLangStructure($aFromLang, $aEngLang, &$iCount = 0)
|
||||||
|
{
|
||||||
|
$iCount = 0;
|
||||||
|
foreach ($aEngLang as $sSectionKey => $aSectionValue)
|
||||||
|
{
|
||||||
|
foreach (\array_keys($aSectionValue) as $sParamKey)
|
||||||
|
{
|
||||||
|
if (isset($aFromLang[$sSectionKey][$sParamKey]))
|
||||||
|
{
|
||||||
|
$aEngLang[$sSectionKey][$sParamKey] = $aFromLang[$sSectionKey][$sParamKey];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// echo $sSectionKey.'/'.$sParamKey.','."\n";
|
||||||
|
$iCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $aEngLang;
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveLangStructure($sLangFile, $aLang)
|
||||||
|
{
|
||||||
|
$aResultLines = array();
|
||||||
|
$aResultLines[] = '; '.$sLangFile;
|
||||||
|
|
||||||
|
foreach ($aLang as $sSectionKey => $aSectionValue)
|
||||||
|
{
|
||||||
|
$aResultLines[] = '';
|
||||||
|
$aResultLines[] = '['.$sSectionKey.']';
|
||||||
|
|
||||||
|
foreach ($aSectionValue as $sParamKey => $sParamValue)
|
||||||
|
{
|
||||||
|
$aResultLines[] = $sParamKey.' = "'.
|
||||||
|
\str_replace(array('\\', '"'), array('\\\\', '\\"'), \trim($sParamValue)).'"';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
\file_put_contents(LANGS_PATH.'/'.$sLangFile, implode("\n", $aResultLines));
|
||||||
|
}
|
||||||
|
|
||||||
|
$sNL = "\n";
|
||||||
|
$aEngLang = \getLangStructure('en.ini');
|
||||||
|
|
||||||
|
$aFiles = \glob(LANGS_PATH.'/*.ini');
|
||||||
|
foreach ($aFiles as $sFile)
|
||||||
|
{
|
||||||
|
$iCount = 0;
|
||||||
|
$sFileName = \basename($sFile);
|
||||||
|
|
||||||
|
$aNextLang = \getLangStructure($sFileName);
|
||||||
|
$aNewLang = \mergeLangStructure($aNextLang, $aEngLang, $iCount);
|
||||||
|
|
||||||
|
if (\json_encode($aNextLang) === \json_encode($aNewLang))
|
||||||
|
{
|
||||||
|
echo $sFileName.': ok'.$sNL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
echo $sFileName.': changed ('.$iCount.')'.$sNL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// \saveLangStructure($sFileName, $aNewLang);
|
||||||
|
}
|
||||||
|
|
@ -307,6 +307,7 @@
|
||||||
'MoveTo': 'MoveTo',
|
'MoveTo': 'MoveTo',
|
||||||
'Discard': 'Discard',
|
'Discard': 'Discard',
|
||||||
'Vacation': 'Vacation',
|
'Vacation': 'Vacation',
|
||||||
|
'Reject': 'Reject',
|
||||||
'Forward': 'Forward'
|
'Forward': 'Forward'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@
|
||||||
|
|
||||||
this.actionSkipOthers = ko.observable(false);
|
this.actionSkipOthers = ko.observable(false);
|
||||||
|
|
||||||
this.keepForward = ko.observable(true);
|
this.actionKeep = ko.observable(true);
|
||||||
|
|
||||||
this.actionType = ko.observable(Enums.FiltersAction.MoveTo);
|
this.actionType = ko.observable(Enums.FiltersAction.MoveTo);
|
||||||
|
|
||||||
|
|
@ -79,6 +79,9 @@
|
||||||
case Enums.FiltersAction.Vacation:
|
case Enums.FiltersAction.Vacation:
|
||||||
sResult = 'Vacation message @i18n';
|
sResult = 'Vacation message @i18n';
|
||||||
break;
|
break;
|
||||||
|
case Enums.FiltersAction.Reject:
|
||||||
|
sResult = 'Reject @i18n';
|
||||||
|
break;
|
||||||
case Enums.FiltersAction.Discard:
|
case Enums.FiltersAction.Discard:
|
||||||
sResult = 'Discard @i18n';
|
sResult = 'Discard @i18n';
|
||||||
break;
|
break;
|
||||||
|
|
@ -103,6 +106,9 @@
|
||||||
case Enums.FiltersAction.Vacation:
|
case Enums.FiltersAction.Vacation:
|
||||||
sTemplate = 'SettingsFiltersActionVacation';
|
sTemplate = 'SettingsFiltersActionVacation';
|
||||||
break;
|
break;
|
||||||
|
case Enums.FiltersAction.Reject:
|
||||||
|
sTemplate = 'SettingsFiltersActionReject';
|
||||||
|
break;
|
||||||
case Enums.FiltersAction.None:
|
case Enums.FiltersAction.None:
|
||||||
sTemplate = 'SettingsFiltersActionNone';
|
sTemplate = 'SettingsFiltersActionNone';
|
||||||
break;
|
break;
|
||||||
|
|
@ -161,6 +167,7 @@
|
||||||
if (-1 < Utils.inArray(this.actionType(), [
|
if (-1 < Utils.inArray(this.actionType(), [
|
||||||
Enums.FiltersAction.MoveTo,
|
Enums.FiltersAction.MoveTo,
|
||||||
Enums.FiltersAction.Forward,
|
Enums.FiltersAction.Forward,
|
||||||
|
Enums.FiltersAction.Reject,
|
||||||
Enums.FiltersAction.Vacation
|
Enums.FiltersAction.Vacation
|
||||||
]))
|
]))
|
||||||
{
|
{
|
||||||
|
|
@ -197,8 +204,8 @@
|
||||||
'ActionValueSecond': this.actionValueSecond(),
|
'ActionValueSecond': this.actionValueSecond(),
|
||||||
'ActionType': this.actionType(),
|
'ActionType': this.actionType(),
|
||||||
|
|
||||||
|
'Keep': this.actionKeep() ? '1' : '0',
|
||||||
'MarkAsRead': this.actionMarkAsRead() ? '1' : '0',
|
'MarkAsRead': this.actionMarkAsRead() ? '1' : '0',
|
||||||
'KeepForward': this.keepForward() ? '1' : '0',
|
|
||||||
'SkipOthers': this.actionSkipOthers() ? '1' : '0'
|
'SkipOthers': this.actionSkipOthers() ? '1' : '0'
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -241,8 +248,8 @@
|
||||||
this.actionValue(Utils.pString(oItem['ActionValue']));
|
this.actionValue(Utils.pString(oItem['ActionValue']));
|
||||||
this.actionValueSecond(Utils.pString(oItem['ActionValueSecond']));
|
this.actionValueSecond(Utils.pString(oItem['ActionValueSecond']));
|
||||||
|
|
||||||
|
this.actionKeep(!!oItem['Keep']);
|
||||||
this.actionMarkAsRead(!!oItem['MarkAsRead']);
|
this.actionMarkAsRead(!!oItem['MarkAsRead']);
|
||||||
this.keepForward(!!oItem['KeepForward']);
|
|
||||||
this.actionSkipOthers(!!oItem['SkipOthers']);
|
this.actionSkipOthers(!!oItem['SkipOthers']);
|
||||||
|
|
||||||
bResult = true;
|
bResult = true;
|
||||||
|
|
@ -274,7 +281,7 @@
|
||||||
|
|
||||||
oClone.actionValueSecond(this.actionValueSecond());
|
oClone.actionValueSecond(this.actionValueSecond());
|
||||||
|
|
||||||
oClone.keepForward(this.keepForward());
|
oClone.actionKeep(this.actionKeep());
|
||||||
|
|
||||||
oClone.conditions(_.map(this.conditions(), function (oCondition) {
|
oClone.conditions(_.map(this.conditions(), function (oCondition) {
|
||||||
return oCondition.cloneSelf();
|
return oCondition.cloneSelf();
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@
|
||||||
Enums = require('Common/Enums'),
|
Enums = require('Common/Enums'),
|
||||||
Utils = require('Common/Utils'),
|
Utils = require('Common/Utils'),
|
||||||
|
|
||||||
|
Data = require('Storage/User/Data'),
|
||||||
|
|
||||||
Remote = require('Storage/User/Remote')
|
Remote = require('Storage/User/Remote')
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -25,12 +27,19 @@
|
||||||
this.processText = ko.observable('');
|
this.processText = ko.observable('');
|
||||||
this.visibility = ko.observable(false);
|
this.visibility = ko.observable(false);
|
||||||
|
|
||||||
|
this.modules = Data.filterModules;
|
||||||
|
|
||||||
this.filters = ko.observableArray([]);
|
this.filters = ko.observableArray([]);
|
||||||
this.filters.loading = ko.observable(false).extend({'throttle': 200});
|
this.filters.loading = ko.observable(false).extend({'throttle': 200});
|
||||||
this.filters.saving = ko.observable(false).extend({'throttle': 200});
|
this.filters.saving = ko.observable(false).extend({'throttle': 200});
|
||||||
|
|
||||||
this.filters.subscribe(Utils.windowResizeCallback);
|
this.filters.subscribe(Utils.windowResizeCallback);
|
||||||
|
|
||||||
|
this.filterRaw = ko.observable('');
|
||||||
|
this.filterRaw.capa = ko.observable('');
|
||||||
|
this.filterRaw.active = ko.observable(false);
|
||||||
|
this.filterRaw.allow = ko.observable(false);
|
||||||
|
|
||||||
this.processText = ko.computed(function () {
|
this.processText = ko.computed(function () {
|
||||||
return this.filters.loading() ? Utils.i18n('SETTINGS_FILTERS/LOADING_PROCESS') : '';
|
return this.filters.loading() ? Utils.i18n('SETTINGS_FILTERS/LOADING_PROCESS') : '';
|
||||||
}, this);
|
}, this);
|
||||||
|
|
@ -58,7 +67,7 @@
|
||||||
self.updateList();
|
self.updateList();
|
||||||
}
|
}
|
||||||
|
|
||||||
}, this.filters());
|
}, this.filters(), this.filterRaw(), this.filterRaw.active());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -70,6 +79,14 @@
|
||||||
this.filters.subscribe(function () {
|
this.filters.subscribe(function () {
|
||||||
this.haveChanges(true);
|
this.haveChanges(true);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
|
this.filterRaw.subscribe(function () {
|
||||||
|
this.haveChanges(true);
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.filterRaw.active.subscribe(function () {
|
||||||
|
this.haveChanges(true);
|
||||||
|
}, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
FiltersUserSettings.prototype.scrollableOptions = function ()
|
FiltersUserSettings.prototype.scrollableOptions = function ()
|
||||||
|
|
@ -93,18 +110,28 @@
|
||||||
self.filters.loading(false);
|
self.filters.loading(false);
|
||||||
|
|
||||||
if (Enums.StorageResultType.Success === sResult && oData &&
|
if (Enums.StorageResultType.Success === sResult && oData &&
|
||||||
oData.Result && Utils.isArray(oData.Result))
|
oData.Result && Utils.isArray(oData.Result.Filters))
|
||||||
{
|
{
|
||||||
var aResult = _.compact(_.map(oData.Result, function (aItem) {
|
var aResult = _.compact(_.map(oData.Result.Filters, function (aItem) {
|
||||||
var oNew = new FilterModel();
|
var oNew = new FilterModel();
|
||||||
return (oNew && oNew.parse(aItem)) ? oNew : null;
|
return (oNew && oNew.parse(aItem)) ? oNew : null;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
self.filters(aResult);
|
self.filters(aResult);
|
||||||
|
|
||||||
|
self.modules(oData.Result.Modules ? oData.Result.Modules : {});
|
||||||
|
|
||||||
|
self.filterRaw(oData.Result.Raw || '');
|
||||||
|
self.filterRaw.capa(Utils.isArray(oData.Result.Capa) ? oData.Result.Capa.join(' ') : '');
|
||||||
|
self.filterRaw.active(!!oData.Result.RawIsActive);
|
||||||
|
self.filterRaw.allow(!!oData.Result.RawIsAllow);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
self.filters([]);
|
self.filters([]);
|
||||||
|
self.modules({});
|
||||||
|
self.filterRaw('');
|
||||||
|
self.filterRaw.capa({});
|
||||||
}
|
}
|
||||||
|
|
||||||
self.haveChanges(false);
|
self.haveChanges(false);
|
||||||
|
|
@ -130,6 +157,7 @@
|
||||||
require('View/Popup/Filter'), [oNew, function () {
|
require('View/Popup/Filter'), [oNew, function () {
|
||||||
self.filters.push(oNew);
|
self.filters.push(oNew);
|
||||||
self.haveChanges(true);
|
self.haveChanges(true);
|
||||||
|
self.filterRaw.active(false);
|
||||||
}, false]);
|
}, false]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,7 @@
|
||||||
RemoteAdminStorage.prototype.createOrUpdateDomain = function (fCallback,
|
RemoteAdminStorage.prototype.createOrUpdateDomain = function (fCallback,
|
||||||
bCreate, sName,
|
bCreate, sName,
|
||||||
sIncHost, iIncPort, sIncSecure, bIncShortLogin,
|
sIncHost, iIncPort, sIncSecure, bIncShortLogin,
|
||||||
bUseSieve, sSieveHost, iSievePort, sSieveSecure,
|
bUseSieve, sSieveAllowRaw, sSieveHost, iSievePort, sSieveSecure,
|
||||||
sOutHost, iOutPort, sOutSecure, bOutShortLogin, bOutAuth, bOutPhpMail,
|
sOutHost, iOutPort, sOutSecure, bOutShortLogin, bOutAuth, bOutPhpMail,
|
||||||
sWhiteList)
|
sWhiteList)
|
||||||
{
|
{
|
||||||
|
|
@ -226,6 +226,7 @@
|
||||||
'IncShortLogin': bIncShortLogin ? '1' : '0',
|
'IncShortLogin': bIncShortLogin ? '1' : '0',
|
||||||
|
|
||||||
'UseSieve': bUseSieve ? '1' : '0',
|
'UseSieve': bUseSieve ? '1' : '0',
|
||||||
|
'SieveAllowRaw': sSieveAllowRaw ? '1' : '0',
|
||||||
'SieveHost': sSieveHost,
|
'SieveHost': sSieveHost,
|
||||||
'SievePort': iSievePort,
|
'SievePort': iSievePort,
|
||||||
'SieveSecure': sSieveSecure,
|
'SieveSecure': sSieveSecure,
|
||||||
|
|
|
||||||
|
|
@ -445,6 +445,7 @@
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
// other
|
// other
|
||||||
|
this.filterModules = ko.observable({});
|
||||||
this.composeInEdit = ko.observable(false);
|
this.composeInEdit = ko.observable(false);
|
||||||
this.capaOpenPGP = ko.observable(false);
|
this.capaOpenPGP = ko.observable(false);
|
||||||
this.openpgpkeys = ko.observableArray([]);
|
this.openpgpkeys = ko.observableArray([]);
|
||||||
|
|
|
||||||
|
|
@ -233,9 +233,12 @@
|
||||||
/**
|
/**
|
||||||
* @param {?Function} fCallback
|
* @param {?Function} fCallback
|
||||||
*/
|
*/
|
||||||
RemoteUserStorage.prototype.filtersSave = function (fCallback, aFilters)
|
RemoteUserStorage.prototype.filtersSave = function (fCallback,
|
||||||
|
aFilters, sRaw, bRawIsActive)
|
||||||
{
|
{
|
||||||
this.defaultRequest(fCallback, 'FiltersSave', {
|
this.defaultRequest(fCallback, 'FiltersSave', {
|
||||||
|
'Raw': sRaw,
|
||||||
|
'RawIsActive': bRawIsActive ? '1' : '0',
|
||||||
'Filters': _.map(aFilters, function (oItem) {
|
'Filters': _.map(aFilters, function (oItem) {
|
||||||
return oItem.toJson();
|
return oItem.toJson();
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@
|
||||||
this.imapSecure = ko.observable(Enums.ServerSecure.None);
|
this.imapSecure = ko.observable(Enums.ServerSecure.None);
|
||||||
this.imapShortLogin = ko.observable(false);
|
this.imapShortLogin = ko.observable(false);
|
||||||
this.useSieve = ko.observable(false);
|
this.useSieve = ko.observable(false);
|
||||||
|
this.sieveAllowRaw = ko.observable(false);
|
||||||
this.sieveServer = ko.observable('');
|
this.sieveServer = ko.observable('');
|
||||||
this.sievePort = ko.observable('' + Consts.Values.SieveDefaulPort);
|
this.sievePort = ko.observable('' + Consts.Values.SieveDefaulPort);
|
||||||
this.sieveSecure = ko.observable(Enums.ServerSecure.None);
|
this.sieveSecure = ko.observable(Enums.ServerSecure.None);
|
||||||
|
|
@ -126,6 +127,7 @@
|
||||||
this.imapShortLogin(),
|
this.imapShortLogin(),
|
||||||
|
|
||||||
this.useSieve(),
|
this.useSieve(),
|
||||||
|
this.sieveAllowRaw(),
|
||||||
this.sieveServer(),
|
this.sieveServer(),
|
||||||
Utils.pInt(this.sievePort()),
|
Utils.pInt(this.sievePort()),
|
||||||
this.sieveSecure(),
|
this.sieveSecure(),
|
||||||
|
|
@ -353,6 +355,7 @@
|
||||||
this.imapSecure(Utils.trim(oDomain.IncSecure));
|
this.imapSecure(Utils.trim(oDomain.IncSecure));
|
||||||
this.imapShortLogin(!!oDomain.IncShortLogin);
|
this.imapShortLogin(!!oDomain.IncShortLogin);
|
||||||
this.useSieve(!!oDomain.UseSieve);
|
this.useSieve(!!oDomain.UseSieve);
|
||||||
|
this.sieveAllowRaw(!!oDomain.SieveAllowRaw);
|
||||||
this.sieveServer(Utils.trim(oDomain.SieveHost));
|
this.sieveServer(Utils.trim(oDomain.SieveHost));
|
||||||
this.sievePort('' + Utils.pInt(oDomain.SievePort));
|
this.sievePort('' + Utils.pInt(oDomain.SievePort));
|
||||||
this.sieveSecure(Utils.trim(oDomain.SieveSecure));
|
this.sieveSecure(Utils.trim(oDomain.SieveSecure));
|
||||||
|
|
@ -396,6 +399,7 @@
|
||||||
this.imapShortLogin(false);
|
this.imapShortLogin(false);
|
||||||
|
|
||||||
this.useSieve(false);
|
this.useSieve(false);
|
||||||
|
this.sieveAllowRaw(false);
|
||||||
this.sieveServer('');
|
this.sieveServer('');
|
||||||
this.sievePort('' + Consts.Values.SieveDefaulPort);
|
this.sievePort('' + Consts.Values.SieveDefaulPort);
|
||||||
this.sieveSecure(Enums.ServerSecure.None);
|
this.sieveSecure(Enums.ServerSecure.None);
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,9 @@
|
||||||
this.fTrueCallback = null;
|
this.fTrueCallback = null;
|
||||||
this.filter = ko.observable(null);
|
this.filter = ko.observable(null);
|
||||||
|
|
||||||
|
this.modules = Data.filterModules;
|
||||||
|
this.allowMarkAsRead = ko.observable(false);
|
||||||
|
|
||||||
this.defautOptionsAfterRender = Utils.defautOptionsAfterRender;
|
this.defautOptionsAfterRender = Utils.defautOptionsAfterRender;
|
||||||
this.folderSelectList = Data.folderMenuForFilters;
|
this.folderSelectList = Data.folderMenuForFilters;
|
||||||
this.selectedFolderValue = ko.observable('');
|
this.selectedFolderValue = ko.observable('');
|
||||||
|
|
@ -68,13 +71,55 @@
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.actionTypeOptions = [
|
this.actionTypeOptions = [];
|
||||||
// {'id': Enums.FiltersAction.None, 'name': 'None @i18n'},
|
this.fieldOptions = [];
|
||||||
{'id': Enums.FiltersAction.MoveTo, 'name': ' Move to @i18n'},
|
this.typeOptions = [];
|
||||||
{'id': Enums.FiltersAction.Forward, 'name': 'Forward to @i18n'},
|
|
||||||
{'id': Enums.FiltersAction.Vacation, 'name': 'Vacation message @i18n'},
|
this.populateOptions();
|
||||||
{'id': Enums.FiltersAction.Discard, 'name': 'Discard @i18n'}
|
|
||||||
];
|
this.modules.subscribe(this.populateOptions, this)
|
||||||
|
|
||||||
|
kn.constructorEnd(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
kn.extendAsViewModel(['View/Popup/Filter', 'PopupsFilterViewModel'], FilterPopupView);
|
||||||
|
_.extend(FilterPopupView.prototype, AbstractView.prototype);
|
||||||
|
|
||||||
|
FilterPopupView.prototype.populateOptions = function ()
|
||||||
|
{
|
||||||
|
this.actionTypeOptions = []
|
||||||
|
// this.actionTypeOptions.push({'id': Enums.FiltersAction.None, 'name': 'None @i18n'});
|
||||||
|
|
||||||
|
var oModules = this.modules();
|
||||||
|
if (oModules)
|
||||||
|
{
|
||||||
|
if (oModules.markasread)
|
||||||
|
{
|
||||||
|
this.allowMarkAsRead(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oModules.moveto)
|
||||||
|
{
|
||||||
|
this.actionTypeOptions.push({'id': Enums.FiltersAction.MoveTo, 'name': 'Move to @i18n'});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oModules.redirect)
|
||||||
|
{
|
||||||
|
this.actionTypeOptions.push({'id': Enums.FiltersAction.Forward, 'name': 'Forward to @i18n'});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oModules.reject)
|
||||||
|
{
|
||||||
|
this.actionTypeOptions.push({'id': Enums.FiltersAction.Reject, 'name': 'Reject @i18n'});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oModules.vacation)
|
||||||
|
{
|
||||||
|
this.actionTypeOptions.push({'id': Enums.FiltersAction.Vacation, 'name': 'Vacation message @i18n'});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.actionTypeOptions.push({'id': Enums.FiltersAction.Discard, 'name': 'Discard @i18n'});
|
||||||
|
|
||||||
this.fieldOptions = [
|
this.fieldOptions = [
|
||||||
{'id': Enums.FilterConditionField.From, 'name': 'From @i18n'},
|
{'id': Enums.FilterConditionField.From, 'name': 'From @i18n'},
|
||||||
|
|
@ -88,12 +133,8 @@
|
||||||
{'id': Enums.FilterConditionType.EqualTo, 'name': 'Equal To @i18n'},
|
{'id': Enums.FilterConditionType.EqualTo, 'name': 'Equal To @i18n'},
|
||||||
{'id': Enums.FilterConditionType.NotEqualTo, 'name': 'Not Equal To @i18n'}
|
{'id': Enums.FilterConditionType.NotEqualTo, 'name': 'Not Equal To @i18n'}
|
||||||
];
|
];
|
||||||
|
};
|
||||||
|
|
||||||
kn.constructorEnd(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
kn.extendAsViewModel(['View/Popup/Filter', 'PopupsFilterViewModel'], FilterPopupView);
|
|
||||||
_.extend(FilterPopupView.prototype, AbstractView.prototype);
|
|
||||||
|
|
||||||
FilterPopupView.prototype.removeCondition = function (oConditionToDelete)
|
FilterPopupView.prototype.removeCondition = function (oConditionToDelete)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,15 @@ class ManageSieveClient extends \MailSo\Net\NetClient
|
||||||
*/
|
*/
|
||||||
public function IsModuleSupported($sModule)
|
public function IsModuleSupported($sModule)
|
||||||
{
|
{
|
||||||
return $this->IsSupported('SIEVE') && \in_array(\strtoupper($sModule), $this->aModules);
|
return $this->IsSupported('SIEVE') && \in_array(\strtolower(\trim($sModule)), $this->aModules);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function Modules()
|
||||||
|
{
|
||||||
|
return $this->aModules;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -487,7 +495,7 @@ class ManageSieveClient extends \MailSo\Net\NetClient
|
||||||
$this->aAuth = \explode(' ', \strtoupper($aTokens[1]));
|
$this->aAuth = \explode(' ', \strtoupper($aTokens[1]));
|
||||||
break;
|
break;
|
||||||
case 'SIEVE':
|
case 'SIEVE':
|
||||||
$this->aModules = \explode(' ', \strtoupper($aTokens[1]));
|
$this->aModules = \explode(' ', \strtolower($aTokens[1]));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -513,7 +521,6 @@ class ManageSieveClient extends \MailSo\Net\NetClient
|
||||||
|
|
||||||
$this->IsConnected(true);
|
$this->IsConnected(true);
|
||||||
|
|
||||||
$sRequest = \trim($sRequest);
|
|
||||||
$this->sendRaw($sRequest);
|
$this->sendRaw($sRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -617,7 +624,7 @@ class ManageSieveClient extends \MailSo\Net\NetClient
|
||||||
*/
|
*/
|
||||||
protected function getLogName()
|
protected function getLogName()
|
||||||
{
|
{
|
||||||
return 'MANAGE-SIEVE';
|
return 'SIEVE';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -251,8 +251,10 @@ class Actions
|
||||||
case 'filters':
|
case 'filters':
|
||||||
// \RainLoop\Providers\Filters\FiltersInterface
|
// \RainLoop\Providers\Filters\FiltersInterface
|
||||||
$oResult = new \RainLoop\Providers\Filters\SieveStorage(
|
$oResult = new \RainLoop\Providers\Filters\SieveStorage(
|
||||||
!!$this->Config()->Get('labs', 'sieve_utf8_folder_name', true)
|
$this->Plugins(), $this->Config()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$oResult->SetLogger($this->Logger());
|
||||||
break;
|
break;
|
||||||
case 'address-book':
|
case 'address-book':
|
||||||
// \RainLoop\Providers\AddressBook\AddressBookInterface
|
// \RainLoop\Providers\AddressBook\AddressBookInterface
|
||||||
|
|
@ -2053,7 +2055,9 @@ class Actions
|
||||||
*/
|
*/
|
||||||
public function DoFilters()
|
public function DoFilters()
|
||||||
{
|
{
|
||||||
return $this->DefaultResponse(__FUNCTION__, $this->FiltersProvider()->Load());
|
$oAccount = $this->getAccountFromToken();
|
||||||
|
return $this->DefaultResponse(__FUNCTION__,
|
||||||
|
$this->FiltersProvider()->Load($oAccount, $oAccount->DomainSieveAllowRaw()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2063,8 +2067,13 @@ class Actions
|
||||||
*/
|
*/
|
||||||
public function DoFiltersSave()
|
public function DoFiltersSave()
|
||||||
{
|
{
|
||||||
|
$oAccount = $this->getAccountFromToken();
|
||||||
|
|
||||||
$aIncFilters = $this->GetActionParam('Filters', array());
|
$aIncFilters = $this->GetActionParam('Filters', array());
|
||||||
|
|
||||||
|
$sRaw = $this->GetActionParam('Raw', '');
|
||||||
|
$bRawIsActive = '1' === (string) $this->GetActionParam('RawIsActive', '0');
|
||||||
|
|
||||||
$aFilters = array();
|
$aFilters = array();
|
||||||
foreach ($aIncFilters as $aFilter)
|
foreach ($aIncFilters as $aFilter)
|
||||||
{
|
{
|
||||||
|
|
@ -2078,8 +2087,8 @@ class Actions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->DefaultResponse(__FUNCTION__, $this->FiltersProvider()->Save($aFilters));
|
return $this->DefaultResponse(__FUNCTION__, $this->FiltersProvider()->Save($oAccount,
|
||||||
// return $this->TrueResponse(__FUNCTION__);
|
$aFilters, $sRaw, $bRawIsActive));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ class Application extends \RainLoop\Config\AbstractConfig
|
||||||
'admin_password' => array('12345'),
|
'admin_password' => array('12345'),
|
||||||
'allow_admin_panel' => array(true, 'Access settings'),
|
'allow_admin_panel' => array(true, 'Access settings'),
|
||||||
'allow_two_factor_auth' => array(false),
|
'allow_two_factor_auth' => array(false),
|
||||||
'allow_universal_login' => array(true),
|
'allow_universal_login' => array(false),
|
||||||
'admin_panel_host' => array(''),
|
'admin_panel_host' => array(''),
|
||||||
'core_install_access_domain' => array('')
|
'core_install_access_domain' => array('')
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -305,6 +305,38 @@ class Account extends \RainLoop\Account // for backward compatibility
|
||||||
return $this->Domain()->OutAuth();
|
return $this->Domain()->OutAuth();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function DomainSieveHost()
|
||||||
|
{
|
||||||
|
return $this->Domain()->SieveHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function DomainSievePort()
|
||||||
|
{
|
||||||
|
return $this->Domain()->SievePort();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function DomainSieveSecure()
|
||||||
|
{
|
||||||
|
return $this->Domain()->SieveSecure();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function DomainSieveAllowRaw()
|
||||||
|
{
|
||||||
|
return $this->Domain()->SieveAllowRaw();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
|
|
@ -443,4 +475,52 @@ class Account extends \RainLoop\Account // for backward compatibility
|
||||||
|
|
||||||
return $bLogin;
|
return $bLogin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \RainLoop\Plugins\Manager $oPlugins
|
||||||
|
* @param \MailSo\Sieve\ManageSieveClient $oSieveClient
|
||||||
|
* @param \RainLoop\Application $oConfig
|
||||||
|
*/
|
||||||
|
public function SieveConnectAndLoginHelper($oPlugins, $oSieveClient, $oConfig)
|
||||||
|
{
|
||||||
|
$bLogin = false;
|
||||||
|
|
||||||
|
$aSieveCredentials = array(
|
||||||
|
'UseConnect' => true,
|
||||||
|
'UseAuth' => true,
|
||||||
|
'Host' => $this->DomainSieveHost(),
|
||||||
|
'Port' => $this->DomainSievePort(),
|
||||||
|
'Secure' => $this->DomainSieveSecure(),
|
||||||
|
'Login' => $this->IncLogin(),
|
||||||
|
'Password' => $this->Password(),
|
||||||
|
'VerifySsl' => !!$oConfig->Get('ssl', 'verify_certificate', false),
|
||||||
|
'AllowSelfSigned' => !!$oConfig->Get('ssl', 'allow_self_signed', true)
|
||||||
|
);
|
||||||
|
|
||||||
|
$oPlugins->RunHook('filter.sieve-credentials', array($this, &$aSieveCredentials));
|
||||||
|
|
||||||
|
$oPlugins->RunHook('event.sieve-pre-connect', array($this, $aSieveCredentials['UseConnect'], $aSieveCredentials));
|
||||||
|
|
||||||
|
if ($aSieveCredentials['UseConnect'] && $oSieveClient)
|
||||||
|
{
|
||||||
|
$oSieveClient->Connect($aSieveCredentials['Host'], $aSieveCredentials['Port'],
|
||||||
|
$aSieveCredentials['Secure'], $aSieveCredentials['VerifySsl'], $aSieveCredentials['AllowSelfSigned']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$oPlugins->RunHook('event.sieve-post-connect', array($this, $aSieveCredentials['UseConnect'], $aSieveCredentials));
|
||||||
|
|
||||||
|
$oPlugins->RunHook('event.sieve-pre-login', array($this, $aSieveCredentials['UseAuth'], $aSieveCredentials));
|
||||||
|
|
||||||
|
if ($aSieveCredentials['UseAuth'])
|
||||||
|
{
|
||||||
|
$oSieveClient->Login($aSieveCredentials['Login'], $aSieveCredentials['Password']);
|
||||||
|
|
||||||
|
$bLogin = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$oPlugins->RunHook('event.sieve-post-login', array($this, $aSieveCredentials['UseAuth'], $bLogin, $aSieveCredentials));
|
||||||
|
|
||||||
|
return $bLogin;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,11 @@ class Domain
|
||||||
*/
|
*/
|
||||||
private $iSieveSecure;
|
private $iSieveSecure;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $bSieveAllowRaw;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
|
|
@ -130,6 +135,8 @@ class Domain
|
||||||
$this->iSievePort = $iSievePort;
|
$this->iSievePort = $iSievePort;
|
||||||
$this->iSieveSecure = $iSieveSecure;
|
$this->iSieveSecure = $iSieveSecure;
|
||||||
|
|
||||||
|
$this->bSieveAllowRaw = false;
|
||||||
|
|
||||||
$this->sWhiteList = \trim($sWhiteList);
|
$this->sWhiteList = \trim($sWhiteList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -184,6 +191,7 @@ class Domain
|
||||||
!empty($aDomain['imap_secure']) ? $aDomain['imap_secure'] : '');
|
!empty($aDomain['imap_secure']) ? $aDomain['imap_secure'] : '');
|
||||||
|
|
||||||
$bUseSieve = isset($aDomain['sieve_use']) ? (bool) $aDomain['sieve_use'] : false;
|
$bUseSieve = isset($aDomain['sieve_use']) ? (bool) $aDomain['sieve_use'] : false;
|
||||||
|
$bSieveAllowRaw = isset($aDomain['sieve_allow_raw']) ? (bool) $aDomain['sieve_allow_raw'] : false;
|
||||||
|
|
||||||
$sSieveHost = empty($aDomain['sieve_host']) ? '' : (string) $aDomain['sieve_host'];
|
$sSieveHost = empty($aDomain['sieve_host']) ? '' : (string) $aDomain['sieve_host'];
|
||||||
$iSievePort = empty($aDomain['sieve_port']) ? 2000 : (int) $aDomain['sieve_port'];
|
$iSievePort = empty($aDomain['sieve_port']) ? 2000 : (int) $aDomain['sieve_port'];
|
||||||
|
|
@ -207,6 +215,8 @@ class Domain
|
||||||
$bUseSieve, $sSieveHost, $iSievePort, $iSieveSecure,
|
$bUseSieve, $sSieveHost, $iSievePort, $iSieveSecure,
|
||||||
$sOutHost, $iOutPort, $iOutSecure, $bOutShortLogin, $bOutAuth, $bOutUsePhpMail,
|
$sOutHost, $iOutPort, $iOutSecure, $bOutShortLogin, $bOutAuth, $bOutUsePhpMail,
|
||||||
$sWhiteList);
|
$sWhiteList);
|
||||||
|
|
||||||
|
$oDomain->SetSieveAllowRaw($bSieveAllowRaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $oDomain;
|
return $oDomain;
|
||||||
|
|
@ -257,6 +267,7 @@ class Domain
|
||||||
'imap_secure = "'.self::ConstConnectionSecurityTypeToStr($this->iIncSecure).'"',
|
'imap_secure = "'.self::ConstConnectionSecurityTypeToStr($this->iIncSecure).'"',
|
||||||
'imap_short_login = '.($this->bIncShortLogin ? 'On' : 'Off'),
|
'imap_short_login = '.($this->bIncShortLogin ? 'On' : 'Off'),
|
||||||
'sieve_use = '.($this->bUseSieve ? 'On' : 'Off'),
|
'sieve_use = '.($this->bUseSieve ? 'On' : 'Off'),
|
||||||
|
'sieve_allow_raw = '.($this->bSieveAllowRaw ? 'On' : 'Off'),
|
||||||
'sieve_host = "'.$this->encodeIniString($this->sSieveHost).'"',
|
'sieve_host = "'.$this->encodeIniString($this->sSieveHost).'"',
|
||||||
'sieve_port = '.$this->iSievePort,
|
'sieve_port = '.$this->iSievePort,
|
||||||
'sieve_secure = "'.self::ConstConnectionSecurityTypeToStr($this->iSieveSecure).'"',
|
'sieve_secure = "'.self::ConstConnectionSecurityTypeToStr($this->iSieveSecure).'"',
|
||||||
|
|
@ -427,6 +438,22 @@ class Domain
|
||||||
return $this->iSieveSecure;
|
return $this->iSieveSecure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function SieveAllowRaw()
|
||||||
|
{
|
||||||
|
return $this->bSieveAllowRaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $bSieveAllowRaw
|
||||||
|
*/
|
||||||
|
public function SetSieveAllowRaw($bSieveAllowRaw)
|
||||||
|
{
|
||||||
|
$this->bSieveAllowRaw = !!$bSieveAllowRaw;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
|
|
@ -524,6 +551,7 @@ class Domain
|
||||||
'SieveHost' => $bAjax ? \MailSo\Base\Utils::IdnToUtf8($this->SieveHost()) : $this->SieveHost(),
|
'SieveHost' => $bAjax ? \MailSo\Base\Utils::IdnToUtf8($this->SieveHost()) : $this->SieveHost(),
|
||||||
'SievePort' => $this->SievePort(),
|
'SievePort' => $this->SievePort(),
|
||||||
'SieveSecure' => $this->SieveSecure(),
|
'SieveSecure' => $this->SieveSecure(),
|
||||||
|
'SieveAllowRaw' => $this->SieveAllowRaw(),
|
||||||
'OutHost' => $bAjax ? \MailSo\Base\Utils::IdnToUtf8($this->OutHost()) : $this->OutHost(),
|
'OutHost' => $bAjax ? \MailSo\Base\Utils::IdnToUtf8($this->OutHost()) : $this->OutHost(),
|
||||||
'OutPort' => $this->OutPort(),
|
'OutPort' => $this->OutPort(),
|
||||||
'OutSecure' => $this->OutSecure(),
|
'OutSecure' => $this->OutSecure(),
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,7 @@ class Domain extends \RainLoop\Providers\AbstractProvider
|
||||||
$iIncSecure = (int) $oActions->GetActionParam('IncSecure', \MailSo\Net\Enumerations\ConnectionSecurityType::NONE);
|
$iIncSecure = (int) $oActions->GetActionParam('IncSecure', \MailSo\Net\Enumerations\ConnectionSecurityType::NONE);
|
||||||
$bIncShortLogin = '1' === (string) $oActions->GetActionParam('IncShortLogin', '0');
|
$bIncShortLogin = '1' === (string) $oActions->GetActionParam('IncShortLogin', '0');
|
||||||
$bUseSieve = '1' === (string) $oActions->GetActionParam('UseSieve', '0');
|
$bUseSieve = '1' === (string) $oActions->GetActionParam('UseSieve', '0');
|
||||||
|
$bSieveAllowRaw = '1' === (string) $oActions->GetActionParam('SieveAllowRaw', '0');
|
||||||
$sSieveHost = (string) $oActions->GetActionParam('SieveHost', '');
|
$sSieveHost = (string) $oActions->GetActionParam('SieveHost', '');
|
||||||
$iSievePort = (int) $oActions->GetActionParam('SievePort', 2000);
|
$iSievePort = (int) $oActions->GetActionParam('SievePort', 2000);
|
||||||
$iSieveSecure = (int) $oActions->GetActionParam('SieveSecure', \MailSo\Net\Enumerations\ConnectionSecurityType::NONE);
|
$iSieveSecure = (int) $oActions->GetActionParam('SieveSecure', \MailSo\Net\Enumerations\ConnectionSecurityType::NONE);
|
||||||
|
|
@ -173,6 +174,11 @@ class Domain extends \RainLoop\Providers\AbstractProvider
|
||||||
$sWhiteList);
|
$sWhiteList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($oDomain)
|
||||||
|
{
|
||||||
|
$oDomain->SetSieveAllowRaw($bSieveAllowRaw);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $oDomain;
|
return $oDomain;
|
||||||
|
|
|
||||||
|
|
@ -18,21 +18,28 @@ class Filters extends \RainLoop\Providers\AbstractProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param \RainLoop\Account $oAccount
|
||||||
|
* @param bool $bAllowRaw = false
|
||||||
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function Load()
|
public function Load($oAccount, $bAllowRaw = false)
|
||||||
{
|
{
|
||||||
return $this->IsActive() ? $this->oDriver->Load() : array();
|
return $this->IsActive() ? $this->oDriver->Load($oAccount, $bAllowRaw) : array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param \RainLoop\Account $oAccount
|
||||||
* @param array $aFilters
|
* @param array $aFilters
|
||||||
|
* @param string $sRaw = ''
|
||||||
|
* @param bool $bRawIsActive = false
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function Save($aFilters)
|
public function Save($oAccount, $aFilters, $sRaw = '', $bRawIsActive = false)
|
||||||
{
|
{
|
||||||
return $this->IsActive() ? $this->oDriver->Save($aFilters) : false;
|
return $this->IsActive() ? $this->oDriver->Save($oAccount,
|
||||||
|
$aFilters, $sRaw, $bRawIsActive) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ class Filter
|
||||||
/**
|
/**
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
private $bKeepForward;
|
private $bKeep;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
|
|
@ -81,7 +81,7 @@ class Filter
|
||||||
|
|
||||||
$this->bMarkAsRead = false;
|
$this->bMarkAsRead = false;
|
||||||
$this->bSkipOthers = false;
|
$this->bSkipOthers = false;
|
||||||
$this->bKeepForward = true;
|
$this->bKeep = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -167,9 +167,9 @@ class Filter
|
||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function KeepForward()
|
public function Keep()
|
||||||
{
|
{
|
||||||
return $this->bKeepForward;
|
return $this->bKeep;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -217,9 +217,9 @@ class Filter
|
||||||
$this->sActionValue = isset($aFilter['ActionValue']) ? $aFilter['ActionValue'] : '';
|
$this->sActionValue = isset($aFilter['ActionValue']) ? $aFilter['ActionValue'] : '';
|
||||||
$this->sActionValueSecond = isset($aFilter['ActionValueSecond']) ? $aFilter['ActionValueSecond'] : '';
|
$this->sActionValueSecond = isset($aFilter['ActionValueSecond']) ? $aFilter['ActionValueSecond'] : '';
|
||||||
|
|
||||||
|
$this->bKeep = isset($aFilter['Keep']) ? '1' === (string) $aFilter['Keep'] : true;
|
||||||
$this->bMarkAsRead = isset($aFilter['MarkAsRead']) ? '1' === (string) $aFilter['MarkAsRead'] : false;
|
$this->bMarkAsRead = isset($aFilter['MarkAsRead']) ? '1' === (string) $aFilter['MarkAsRead'] : false;
|
||||||
$this->bSkipOthers = isset($aFilter['SkipOthers']) ? '1' === (string) $aFilter['SkipOthers'] : false;
|
$this->bSkipOthers = isset($aFilter['SkipOthers']) ? '1' === (string) $aFilter['SkipOthers'] : false;
|
||||||
$this->bKeepForward = isset($aFilter['KeepForward']) ? '1' === (string) $aFilter['KeepForward'] : true;
|
|
||||||
|
|
||||||
$this->aConditions = \RainLoop\Providers\Filters\Classes\FilterCondition::CollectionFromJSON(
|
$this->aConditions = \RainLoop\Providers\Filters\Classes\FilterCondition::CollectionFromJSON(
|
||||||
isset($aFilter['Conditions']) ? $aFilter['Conditions'] : array());
|
isset($aFilter['Conditions']) ? $aFilter['Conditions'] : array());
|
||||||
|
|
@ -255,6 +255,7 @@ class Filter
|
||||||
'ActionType' => $this->ActionType(),
|
'ActionType' => $this->ActionType(),
|
||||||
'ActionValue' => $this->ActionValue(),
|
'ActionValue' => $this->ActionValue(),
|
||||||
'ActionValueSecond' => $this->ActionValueSecond(),
|
'ActionValueSecond' => $this->ActionValueSecond(),
|
||||||
|
'Keep' => $this->Keep(),
|
||||||
'MarkAsRead' => $this->MarkAsRead(),
|
'MarkAsRead' => $this->MarkAsRead(),
|
||||||
'SkipOthers' => $this->SkipOthers()
|
'SkipOthers' => $this->SkipOthers()
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -8,5 +8,6 @@ class ActionType
|
||||||
const MOVE_TO = 'MoveTo';
|
const MOVE_TO = 'MoveTo';
|
||||||
const DISCARD = 'Discard';
|
const DISCARD = 'Discard';
|
||||||
const VACATION = 'Vacation';
|
const VACATION = 'Vacation';
|
||||||
|
const REJECT = 'Reject';
|
||||||
const FORWARD = 'Forward';
|
const FORWARD = 'Forward';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,18 @@ namespace RainLoop\Providers\Filters;
|
||||||
interface FiltersInterface
|
interface FiltersInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
* @param \RainLoop\Account $oAccount
|
||||||
|
* @param bool $bAllowRaw = false
|
||||||
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function Load();
|
public function Load($oAccount, $bAllowRaw = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param \RainLoop\Account $oAccount
|
||||||
* @param array $aFilters
|
* @param array $aFilters
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function Save($aFilters);
|
public function Save($oAccount, $aFilters);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,25 @@ namespace RainLoop\Providers\Filters;
|
||||||
|
|
||||||
class SieveStorage implements \RainLoop\Providers\Filters\FiltersInterface
|
class SieveStorage implements \RainLoop\Providers\Filters\FiltersInterface
|
||||||
{
|
{
|
||||||
const NEW_LINE = "\n";
|
const NEW_LINE = "\r\n";
|
||||||
|
|
||||||
|
const SIEVE_FILE_NAME = 'rainloop.user';
|
||||||
|
const SIEVE_FILE_NAME_RAW = 'rainloop.raw';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \MailSo\Log\Logger
|
||||||
|
*/
|
||||||
|
private $oLogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \RainLoop\Plugins\Manager
|
||||||
|
*/
|
||||||
|
private $oPlugins;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \RainLoop\Application
|
||||||
|
*/
|
||||||
|
private $oConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var bool
|
* @var bool
|
||||||
|
|
@ -12,31 +30,130 @@ class SieveStorage implements \RainLoop\Providers\Filters\FiltersInterface
|
||||||
private $bUtf8FolderName;
|
private $bUtf8FolderName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $bUtf8FolderName = true
|
|
||||||
*
|
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __construct($bUtf8FolderName = true)
|
public function __construct($oPlugins, $oConfig)
|
||||||
{
|
{
|
||||||
$this->bUtf8FolderName = !!$bUtf8FolderName;
|
$this->oLogger = null;
|
||||||
|
|
||||||
|
$this->oPlugins = $oPlugins;
|
||||||
|
$this->oConfig = $oConfig;
|
||||||
|
|
||||||
|
$this->bUtf8FolderName = !!$this->oConfig->Get('labs', 'sieve_utf8_folder_name', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param \RainLoop\Model\Account $oAccount
|
||||||
|
* @param bool $bAllowRaw = false
|
||||||
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function Load()
|
public function Load($oAccount, $bAllowRaw = false)
|
||||||
{
|
{
|
||||||
return $this->fileStringToCollection(@\file_get_contents('e:/sieve.txt'));
|
$sRaw = '';
|
||||||
|
|
||||||
|
$bBasicIsActive = false;
|
||||||
|
$bRawIsActive = false;
|
||||||
|
|
||||||
|
$aModules = array();
|
||||||
|
$aFilters = array();
|
||||||
|
|
||||||
|
$oSieveClient = \MailSo\Sieve\ManageSieveClient::NewInstance()->SetLogger($this->oLogger);
|
||||||
|
|
||||||
|
if ($oAccount->SieveConnectAndLoginHelper($this->oPlugins, $oSieveClient, $this->oConfig))
|
||||||
|
{
|
||||||
|
$aModules = $oSieveClient->Modules();
|
||||||
|
$aList = $oSieveClient->ListScripts();
|
||||||
|
|
||||||
|
if (\is_array($aList) && 0 < \count($aList))
|
||||||
|
{
|
||||||
|
if (isset($aList[self::SIEVE_FILE_NAME]))
|
||||||
|
{
|
||||||
|
$bBasicIsActive = !!$aList[self::SIEVE_FILE_NAME];
|
||||||
|
$sS = $oSieveClient->GetScript(self::SIEVE_FILE_NAME);
|
||||||
|
if ($sS)
|
||||||
|
{
|
||||||
|
$aFilters = $this->fileStringToCollection($sS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($bAllowRaw && isset($aList[self::SIEVE_FILE_NAME_RAW]))
|
||||||
|
{
|
||||||
|
$bRawIsActive = !!$aList[self::SIEVE_FILE_NAME_RAW];
|
||||||
|
$sRaw = \trim($oSieveClient->GetScript(self::SIEVE_FILE_NAME_RAW));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$oSieveClient->LogoutAndDisconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'RawIsAllow' => $bAllowRaw,
|
||||||
|
'RawIsActive' => $bRawIsActive,
|
||||||
|
'Raw' => $bAllowRaw ? $sRaw : '',
|
||||||
|
'Filters' => !$bBasicIsActive && !$bRawIsActive ? array() : $aFilters,
|
||||||
|
'Capa' => $bAllowRaw ? $aModules : array(),
|
||||||
|
'Modules' => array(
|
||||||
|
'redirect' => \in_array('fileinto', $aModules),
|
||||||
|
'moveto' => \in_array('fileinto', $aModules),
|
||||||
|
'reject' => \in_array('reject', $aModules),
|
||||||
|
'vacation' => \in_array('vacation', $aModules),
|
||||||
|
'markasread' => \in_array('imap4flags', $aModules) && false
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param \RainLoop\Model\Account $oAccount
|
||||||
* @param array $aFilters
|
* @param array $aFilters
|
||||||
|
* @param string $sRaw = ''
|
||||||
|
* @param bool $bRawIsActive = false
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function Save($aFilters)
|
public function Save($oAccount, $aFilters, $sRaw = '', $bRawIsActive = false)
|
||||||
{
|
{
|
||||||
return @\file_put_contents('e:/sieve.txt', $this->collectionToFileString($aFilters));
|
$oSieveClient = \MailSo\Sieve\ManageSieveClient::NewInstance()->SetLogger($this->oLogger);
|
||||||
|
|
||||||
|
if ($oAccount->SieveConnectAndLoginHelper($this->oPlugins, $oSieveClient, $this->oConfig))
|
||||||
|
{
|
||||||
|
$aList = $oSieveClient->ListScripts();
|
||||||
|
|
||||||
|
$sUserFilter = $this->collectionToFileString($aFilters);
|
||||||
|
|
||||||
|
if (!empty($sUserFilter))
|
||||||
|
{
|
||||||
|
$oSieveClient->PutScript(self::SIEVE_FILE_NAME, $sUserFilter);
|
||||||
|
if (!$bRawIsActive)
|
||||||
|
{
|
||||||
|
$oSieveClient->SetActiveScript(self::SIEVE_FILE_NAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (isset($aList[self::SIEVE_FILE_NAME]))
|
||||||
|
{
|
||||||
|
$oSieveClient->DeleteScript(self::SIEVE_FILE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sRaw = \trim($sRaw);
|
||||||
|
if (!empty($sRaw))
|
||||||
|
{
|
||||||
|
$oSieveClient->PutScript(self::SIEVE_FILE_NAME_RAW, $sRaw);
|
||||||
|
if ($bRawIsActive)
|
||||||
|
{
|
||||||
|
$oSieveClient->SetActiveScript(self::SIEVE_FILE_NAME_RAW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (isset($aList[self::SIEVE_FILE_NAME_RAW]))
|
||||||
|
{
|
||||||
|
$oSieveClient->DeleteScript(self::SIEVE_FILE_NAME_RAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
$oSieveClient->LogoutAndDisconnect();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -221,20 +338,31 @@ class SieveStorage implements \RainLoop\Providers\Filters\FiltersInterface
|
||||||
$aResult[] = $sTab.'# @Error (vacation): empty action value';
|
$aResult[] = $sTab.'# @Error (vacation): empty action value';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case \RainLoop\Providers\Filters\Enumerations\ActionType::REJECT:
|
||||||
|
$sValue = \trim($oFilter->ActionValue());
|
||||||
|
if (0 < \strlen($sValue))
|
||||||
|
{
|
||||||
|
$aCapa['reject'] = true;
|
||||||
|
|
||||||
|
$aResult[] = $sTab.'reject "'.$this->quote($sValue).'";';
|
||||||
|
$aResult[] = $sTab.'stop;';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$aResult[] = $sTab.'# @Error (reject): empty action value';
|
||||||
|
}
|
||||||
|
break;
|
||||||
case \RainLoop\Providers\Filters\Enumerations\ActionType::FORWARD:
|
case \RainLoop\Providers\Filters\Enumerations\ActionType::FORWARD:
|
||||||
$sValue = $oFilter->ActionValue();
|
$sValue = $oFilter->ActionValue();
|
||||||
if (0 < \strlen($sValue))
|
if (0 < \strlen($sValue))
|
||||||
{
|
{
|
||||||
if ($oFilter->KeepForward())
|
if ($oFilter->Keep())
|
||||||
{
|
{
|
||||||
$aCapa['copy'] = true;
|
$aCapa['fileinto'] = true;
|
||||||
$aResult[] = $sTab.'redirect :copy "'.$this->quote($sValue).'";';
|
$aResult[] = $sTab.'fileinto "INBOX";';
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$aResult[] = $sTab.'redirect "'.$this->quote($sValue).'";';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$aResult[] = $sTab.'redirect "'.$this->quote($sValue).'";';
|
||||||
$aResult[] = $sTab.'stop;';
|
$aResult[] = $sTab.'stop;';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -246,8 +374,6 @@ class SieveStorage implements \RainLoop\Providers\Filters\FiltersInterface
|
||||||
$sValue = $oFilter->ActionValue();
|
$sValue = $oFilter->ActionValue();
|
||||||
if (0 < \strlen($sValue))
|
if (0 < \strlen($sValue))
|
||||||
{
|
{
|
||||||
$aCapa['fileinto'] = true;
|
|
||||||
|
|
||||||
$sFolderName = $sValue; // utf7-imap
|
$sFolderName = $sValue; // utf7-imap
|
||||||
if ($this->bUtf8FolderName) // to utf-8
|
if ($this->bUtf8FolderName) // to utf-8
|
||||||
{
|
{
|
||||||
|
|
@ -256,6 +382,7 @@ class SieveStorage implements \RainLoop\Providers\Filters\FiltersInterface
|
||||||
\MailSo\Base\Enumerations\Charset::UTF_8);
|
\MailSo\Base\Enumerations\Charset::UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$aCapa['fileinto'] = true;
|
||||||
$aResult[] = $sTab.'fileinto "'.$this->quote($sFolderName).'";';
|
$aResult[] = $sTab.'fileinto "'.$this->quote($sFolderName).'";';
|
||||||
$aResult[] = $sTab.'stop;';
|
$aResult[] = $sTab.'stop;';
|
||||||
}
|
}
|
||||||
|
|
@ -359,4 +486,12 @@ class SieveStorage implements \RainLoop\Providers\Filters\FiltersInterface
|
||||||
{
|
{
|
||||||
return \str_replace(array('\\', '"'), array('\\\\', '\\"'), \trim($sValue));
|
return \str_replace(array('\\', '"'), array('\\\\', '\\"'), \trim($sValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \MailSo\Log\Logger $oLogger
|
||||||
|
*/
|
||||||
|
public function SetLogger($oLogger)
|
||||||
|
{
|
||||||
|
$this->oLogger = $oLogger instanceof \MailSo\Log\Logger ? $oLogger : null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,13 +84,25 @@
|
||||||
<div data-bind="component: {
|
<div data-bind="component: {
|
||||||
name: 'Checkbox',
|
name: 'Checkbox',
|
||||||
params: {
|
params: {
|
||||||
label: 'use Sieve for this domain',
|
label: 'Use Sieve for this domain',
|
||||||
value: useSieve
|
value: useSieve
|
||||||
}
|
}
|
||||||
}"></div>
|
}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div data-bind="visible: useSieve">
|
<div data-bind="visible: useSieve">
|
||||||
|
<br />
|
||||||
|
<div class="row">
|
||||||
|
<div class="span5">
|
||||||
|
<div data-bind="component: {
|
||||||
|
name: 'Checkbox',
|
||||||
|
params: {
|
||||||
|
label: 'Allow custom raw script',
|
||||||
|
value: sieveAllowRaw
|
||||||
|
}
|
||||||
|
}"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<br />
|
<br />
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="span3">
|
<div class="span3">
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,12 @@
|
||||||
|
|
||||||
<span class="i18n" data-i18n-text="SETTINGS_FILTERS/BUTTON_ADD_FILTER"></span>
|
<span class="i18n" data-i18n-text="SETTINGS_FILTERS/BUTTON_ADD_FILTER"></span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
<a class="btn" data-bind="visible: filterRaw.allow, click: function () { filterRaw.active(!filterRaw.active()) },
|
||||||
|
css: {'active': filterRaw.active }">
|
||||||
|
<i class="icon-file-code"></i>
|
||||||
|
</a>
|
||||||
|
|
||||||
<a class="btn" data-bind="command: saveChanges">
|
<a class="btn" data-bind="command: saveChanges">
|
||||||
<i data-bind="css: {'icon-floppy': !filters.saving(), 'icon-spinner animated': filters.saving()}"></i>
|
<i data-bind="css: {'icon-floppy': !filters.saving(), 'icon-spinner animated': filters.saving()}"></i>
|
||||||
|
|
||||||
|
|
@ -36,7 +41,11 @@
|
||||||
|
|
||||||
<span data-bind="text: processText"></span>
|
<span data-bind="text: processText"></span>
|
||||||
</div>
|
</div>
|
||||||
<table class="table table-hover list-table g-ui-user-select-none" data-bind="i18nUpdate: filters">
|
<div data-bind="visible: filterRaw.allow() && filterRaw.active()">
|
||||||
|
<textarea class="span8" style="height: 300px" data-bind="value: filterRaw, valueUpdate: 'afterkeydown'"></textarea>
|
||||||
|
</div>
|
||||||
|
<table class="table table-hover list-table g-ui-user-select-none"
|
||||||
|
data-bind="visible: !filterRaw.active() || !filterRaw.active(), i18nUpdate: filters">
|
||||||
<colgroup>
|
<colgroup>
|
||||||
<col style="width: 30px" />
|
<col style="width: 30px" />
|
||||||
<col />
|
<col />
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,10 @@
|
||||||
name: 'Checkbox',
|
name: 'Checkbox',
|
||||||
params: {
|
params: {
|
||||||
label: 'keep in INBOX @i18n',
|
label: 'keep in INBOX @i18n',
|
||||||
value: keepForward
|
value: actionKeep
|
||||||
}
|
}
|
||||||
}"></div>
|
}"></div>
|
||||||
<div data-bind="component: {
|
<div data-bind="visible: $root.allowMarkAsRead, component: {
|
||||||
name: 'Checkbox',
|
name: 'Checkbox',
|
||||||
params: {
|
params: {
|
||||||
label: 'Mark as read @i18n',
|
label: 'Mark as read @i18n',
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<div data-bind="component: {
|
<div data-bind="visible: $root.allowMarkAsRead, component: {
|
||||||
name: 'Checkbox',
|
name: 'Checkbox',
|
||||||
params: {
|
params: {
|
||||||
label: 'Mark as read @i18n',
|
label: 'Mark as read @i18n',
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
<div class="control-group" data-bind="css: {'error': actionValue.error}" style="margin-bottom: 0">
|
||||||
|
<div class="controls">
|
||||||
|
<textarea class="span5" data-bind="value: actionValue" style="height: 100px;" placeholder="Reject message @i18n"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
@ -5,7 +5,8 @@
|
||||||
|
|
||||||
<input class="span3" type="text" data-bind="value: value" />
|
<input class="span3" type="text" data-bind="value: value" />
|
||||||
|
|
||||||
<span class="delete-action button-delete pull-right" data-bind="click: function (oCondition) { $root.removeCondition(oCondition); }">
|
<span class="delete-action button-delete pull-right" style="margin-top: 5px;"
|
||||||
|
data-bind="click: function (oCondition) { $root.removeCondition(oCondition); }">
|
||||||
<i class="icon-trash"></i>
|
<i class="icon-trash"></i>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -173,7 +173,6 @@ LABEL_EMAIL = "Email"
|
||||||
LABEL_PHONE = "Phone"
|
LABEL_PHONE = "Phone"
|
||||||
LABEL_WEB = "Web"
|
LABEL_WEB = "Web"
|
||||||
LABEL_BIRTHDAY = "Birthday"
|
LABEL_BIRTHDAY = "Birthday"
|
||||||
LABEL_TAGS = "Tags"
|
|
||||||
LINK_ADD_EMAIL = "Add an email address"
|
LINK_ADD_EMAIL = "Add an email address"
|
||||||
LINK_ADD_PHONE = "Add a phone"
|
LINK_ADD_PHONE = "Add a phone"
|
||||||
LINK_BIRTHDAY = "Birthday"
|
LINK_BIRTHDAY = "Birthday"
|
||||||
|
|
@ -376,10 +375,8 @@ TITLE_EDIT_FILTER = "Update filter?"
|
||||||
LEGEND_FILTERS = "Filters"
|
LEGEND_FILTERS = "Filters"
|
||||||
BUTTON_SAVE = "Save"
|
BUTTON_SAVE = "Save"
|
||||||
BUTTON_DONE = "Done"
|
BUTTON_DONE = "Done"
|
||||||
BUTTON_ADD_FILTER = "Add Filter"
|
BUTTON_ADD_FILTER = "Add a Filter"
|
||||||
BUTTON_SAVE_FILTER = "Save Filter"
|
BUTTON_ADD_CONDITION = "Add a Condition"
|
||||||
BUTTON_DELETE_FILTER = "Delete Filter"
|
|
||||||
BUTTON_ADD_CONDITION = "Add Condition"
|
|
||||||
BUTTON_DELETE = "Delete"
|
BUTTON_DELETE = "Delete"
|
||||||
LOADING_PROCESS = "Updating filter list"
|
LOADING_PROCESS = "Updating filter list"
|
||||||
DELETING_ASK = "Are you sure?"
|
DELETING_ASK = "Are you sure?"
|
||||||
|
|
|
||||||
|
|
@ -548,7 +548,7 @@ LABEL_SAVE_MESSAGE = "Guardar aviso"
|
||||||
LABEL_SEND_MESSAGE = "Enviar mensaje"
|
LABEL_SEND_MESSAGE = "Enviar mensaje"
|
||||||
LABEL_CLOSE_COMPOSE = "Cerrar componer"
|
LABEL_CLOSE_COMPOSE = "Cerrar componer"
|
||||||
|
|
||||||
[ PGP_NOTIFICATIONS ]
|
[PGP_NOTIFICATIONS]
|
||||||
NO_PUBLIC_KEYS_FOUND = "No se encontraron claves públicas"
|
NO_PUBLIC_KEYS_FOUND = "No se encontraron claves públicas"
|
||||||
NO_PUBLIC_KEYS_FOUND_FOR = "No hay claves públicas encontrados para el email %MAIL%"
|
NO_PUBLIC_KEYS_FOUND_FOR = "No hay claves públicas encontrados para el email %MAIL%"
|
||||||
NO_PRIVATE_KEY_FOUND = "No se encontró la clave privada "
|
NO_PRIVATE_KEY_FOUND = "No se encontró la clave privada "
|
||||||
|
|
|
||||||
|
|
@ -619,8 +619,8 @@ NO_SCRIPT_TITLE = "È richiesto JavaScript per questa applicazione."
|
||||||
NO_SCRIPT_DESC = "Il supporto a JavaScript è disabilitato.
|
NO_SCRIPT_DESC = "Il supporto a JavaScript è disabilitato.
|
||||||
Abilitare il supporto a JavaScript e riprovare."
|
Abilitare il supporto a JavaScript e riprovare."
|
||||||
|
|
||||||
NO_SCRIPT_TITLE = "Sono richiesti i Cookie per questa applicazione."
|
NO_COOKIE_TITLE = "Sono richiesti i Cookie per questa applicazione."
|
||||||
NO_SCRIPT_DESC = "Il supporto ai Cookie è disabilitato.
|
NO_COOKIE_DESC = "Il supporto ai Cookie è disabilitato.
|
||||||
Abilitare il supporto ai Cookie e riprovare."
|
Abilitare il supporto ai Cookie e riprovare."
|
||||||
|
|
||||||
BAD_BROWSER_TITLE = "Il tuo browser è vecchio"
|
BAD_BROWSER_TITLE = "Il tuo browser è vecchio"
|
||||||
|
|
|
||||||
|
|
@ -585,7 +585,7 @@ CANT_MOVE_MESSAGE = "Kan ikke flytte meldingen"
|
||||||
CANT_SAVE_MESSAGE = "Kan ikke lagre melding"
|
CANT_SAVE_MESSAGE = "Kan ikke lagre melding"
|
||||||
CANT_SEND_MESSAGE = "Kan ikke sende melding"
|
CANT_SEND_MESSAGE = "Kan ikke sende melding"
|
||||||
INVALID_RECIPIENTS = "Ugyldige mottakere"
|
INVALID_RECIPIENTS = "Ugyldige mottakere"
|
||||||
Cant_create_folder = "Kan ikke opprette mappe"
|
CANT_CREATE_FOLDER = "Kan ikke opprette mappe"
|
||||||
CANT_RENAME_FOLDER = "Kan ikke endre navn på mappen"
|
CANT_RENAME_FOLDER = "Kan ikke endre navn på mappen"
|
||||||
CANT_DELETE_FOLDER = "Kan ikke slette mappen"
|
CANT_DELETE_FOLDER = "Kan ikke slette mappen"
|
||||||
CANT_DELETE_NON_EMPTY_FOLDER = "Kan ikke slette katalog med innhold"
|
CANT_DELETE_NON_EMPTY_FOLDER = "Kan ikke slette katalog med innhold"
|
||||||
|
|
|
||||||
|
|
@ -599,8 +599,8 @@ CANT_DELETE_PACKAGE = "Nu pot șterge pachetul. Încercați din nou"
|
||||||
INVALID_PLUGIN_PACKAGE = "Pachetul este invalid"
|
INVALID_PLUGIN_PACKAGE = "Pachetul este invalid"
|
||||||
UNSUPPORTED_PLUGIN_PACKAGE = "Plugin-ul necesită sprijinul complet al serverului"
|
UNSUPPORTED_PLUGIN_PACKAGE = "Plugin-ul necesită sprijinul complet al serverului"
|
||||||
LICENSING_SERVER_IS_UNAVAILABLE = "Server de abonamente este temporar indisponibil."
|
LICENSING_SERVER_IS_UNAVAILABLE = "Server de abonamente este temporar indisponibil."
|
||||||
LICENSING_EXPIRED = "Licența a expirat."
|
LICENSING_DOMAIN_EXPIRED = "Subscription for this domain has expired."
|
||||||
LICENSING_BANNED = "Licență restricționată."
|
LICENSING_DOMAIN_BANNED = "Subscription for this domain is banned."
|
||||||
DEMO_SEND_MESSAGE_ERROR = "Cont demo trimite e-mail la adresele de e-mail externe este interzisă!"
|
DEMO_SEND_MESSAGE_ERROR = "Cont demo trimite e-mail la adresele de e-mail externe este interzisă!"
|
||||||
ACCOUNT_ALREADY_EXISTS = "Contul deja există"
|
ACCOUNT_ALREADY_EXISTS = "Contul deja există"
|
||||||
MAIL_SERVER_ERROR = "Nu am reușit să accesez serverul de e-mail"
|
MAIL_SERVER_ERROR = "Nu am reușit să accesez serverul de e-mail"
|
||||||
|
|
|
||||||
|
|
@ -601,8 +601,8 @@ CANT_DELETE_PACKAGE = "Ошибка удаления пакета"
|
||||||
INVALID_PLUGIN_PACKAGE = "Ошибка пакета плагина"
|
INVALID_PLUGIN_PACKAGE = "Ошибка пакета плагина"
|
||||||
UNSUPPORTED_PLUGIN_PACKAGE = "Для работы плагина необходима полная поддержка сервера"
|
UNSUPPORTED_PLUGIN_PACKAGE = "Для работы плагина необходима полная поддержка сервера"
|
||||||
LICENSING_SERVER_IS_UNAVAILABLE = "Сервер подписок временно не доступен."
|
LICENSING_SERVER_IS_UNAVAILABLE = "Сервер подписок временно не доступен."
|
||||||
LICENSING_EXPIRED = "Подписка на данный домен устарела."
|
LICENSING_DOMAIN_EXPIRED = "Подписка на данный домен устарела."
|
||||||
LICENSING_BANNED = "Подписка на данный домен заблокирована."
|
LICENSING_DOMAIN_BANNED = "Подписка на данный домен заблокирована."
|
||||||
DEMO_SEND_MESSAGE_ERROR = "Демо аккаунту отправка писем на внешние почтовые адреса запрещена!"
|
DEMO_SEND_MESSAGE_ERROR = "Демо аккаунту отправка писем на внешние почтовые адреса запрещена!"
|
||||||
ACCOUNT_ALREADY_EXISTS = "Аккаунт уже добавлен"
|
ACCOUNT_ALREADY_EXISTS = "Аккаунт уже добавлен"
|
||||||
MAIL_SERVER_ERROR = "Ошибка доступа к почтовому серверу"
|
MAIL_SERVER_ERROR = "Ошибка доступа к почтовому серверу"
|
||||||
|
|
|
||||||
|
|
@ -601,8 +601,8 @@ CANT_DELETE_PACKAGE = "Помилка видалення пакету"
|
||||||
INVALID_PLUGIN_PACKAGE = "Помилка пакету плагіну"
|
INVALID_PLUGIN_PACKAGE = "Помилка пакету плагіну"
|
||||||
UNSUPPORTED_PLUGIN_PACKAGE = "Для роботи плагину необхідна повна підтримка серверу"
|
UNSUPPORTED_PLUGIN_PACKAGE = "Для роботи плагину необхідна повна підтримка серверу"
|
||||||
LICENSING_SERVER_IS_UNAVAILABLE = "Сервер підписок тимчасово не доступний."
|
LICENSING_SERVER_IS_UNAVAILABLE = "Сервер підписок тимчасово не доступний."
|
||||||
LICENSING_EXPIRED = "Підписка на цей домен застаріла."
|
LICENSING_DOMAIN_EXPIRED = "Підписка на цей домен застаріла."
|
||||||
LICENSING_BANNED = "Підписка на цей домен заблокована."
|
LICENSING_DOMAIN_BANNED = "Підписка на цей домен заблокована."
|
||||||
DEMO_SEND_MESSAGE_ERROR = "Демо акаунту надсилання листів на зовнішні поштові адреси заборонена!"
|
DEMO_SEND_MESSAGE_ERROR = "Демо акаунту надсилання листів на зовнішні поштові адреси заборонена!"
|
||||||
ACCOUNT_ALREADY_EXISTS = "акаунт вже додано"
|
ACCOUNT_ALREADY_EXISTS = "акаунт вже додано"
|
||||||
MAIL_SERVER_ERROR = "Помилка доступу до поштового серверу"
|
MAIL_SERVER_ERROR = "Помилка доступу до поштового серверу"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue