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
|
|
@ -70,7 +70,15 @@ class ManageSieveClient extends \MailSo\Net\NetClient
|
|||
*/
|
||||
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]));
|
||||
break;
|
||||
case 'SIEVE':
|
||||
$this->aModules = \explode(' ', \strtoupper($aTokens[1]));
|
||||
$this->aModules = \explode(' ', \strtolower($aTokens[1]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -513,7 +521,6 @@ class ManageSieveClient extends \MailSo\Net\NetClient
|
|||
|
||||
$this->IsConnected(true);
|
||||
|
||||
$sRequest = \trim($sRequest);
|
||||
$this->sendRaw($sRequest);
|
||||
}
|
||||
|
||||
|
|
@ -617,7 +624,7 @@ class ManageSieveClient extends \MailSo\Net\NetClient
|
|||
*/
|
||||
protected function getLogName()
|
||||
{
|
||||
return 'MANAGE-SIEVE';
|
||||
return 'SIEVE';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -251,8 +251,10 @@ class Actions
|
|||
case 'filters':
|
||||
// \RainLoop\Providers\Filters\FiltersInterface
|
||||
$oResult = new \RainLoop\Providers\Filters\SieveStorage(
|
||||
!!$this->Config()->Get('labs', 'sieve_utf8_folder_name', true)
|
||||
$this->Plugins(), $this->Config()
|
||||
);
|
||||
|
||||
$oResult->SetLogger($this->Logger());
|
||||
break;
|
||||
case 'address-book':
|
||||
// \RainLoop\Providers\AddressBook\AddressBookInterface
|
||||
|
|
@ -2053,7 +2055,9 @@ class Actions
|
|||
*/
|
||||
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()
|
||||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
$aIncFilters = $this->GetActionParam('Filters', array());
|
||||
|
||||
$sRaw = $this->GetActionParam('Raw', '');
|
||||
$bRawIsActive = '1' === (string) $this->GetActionParam('RawIsActive', '0');
|
||||
|
||||
$aFilters = array();
|
||||
foreach ($aIncFilters as $aFilter)
|
||||
{
|
||||
|
|
@ -2078,8 +2087,8 @@ class Actions
|
|||
}
|
||||
}
|
||||
|
||||
return $this->DefaultResponse(__FUNCTION__, $this->FiltersProvider()->Save($aFilters));
|
||||
// return $this->TrueResponse(__FUNCTION__);
|
||||
return $this->DefaultResponse(__FUNCTION__, $this->FiltersProvider()->Save($oAccount,
|
||||
$aFilters, $sRaw, $bRawIsActive));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ class Application extends \RainLoop\Config\AbstractConfig
|
|||
'admin_password' => array('12345'),
|
||||
'allow_admin_panel' => array(true, 'Access settings'),
|
||||
'allow_two_factor_auth' => array(false),
|
||||
'allow_universal_login' => array(true),
|
||||
'allow_universal_login' => array(false),
|
||||
'admin_panel_host' => array(''),
|
||||
'core_install_access_domain' => array('')
|
||||
),
|
||||
|
|
|
|||
|
|
@ -305,6 +305,38 @@ class Account extends \RainLoop\Account // for backward compatibility
|
|||
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
|
||||
*/
|
||||
|
|
@ -443,4 +475,52 @@ class Account extends \RainLoop\Account // for backward compatibility
|
|||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bSieveAllowRaw;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
|
|
@ -130,6 +135,8 @@ class Domain
|
|||
$this->iSievePort = $iSievePort;
|
||||
$this->iSieveSecure = $iSieveSecure;
|
||||
|
||||
$this->bSieveAllowRaw = false;
|
||||
|
||||
$this->sWhiteList = \trim($sWhiteList);
|
||||
}
|
||||
|
||||
|
|
@ -184,6 +191,7 @@ class Domain
|
|||
!empty($aDomain['imap_secure']) ? $aDomain['imap_secure'] : '');
|
||||
|
||||
$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'];
|
||||
$iSievePort = empty($aDomain['sieve_port']) ? 2000 : (int) $aDomain['sieve_port'];
|
||||
|
|
@ -207,6 +215,8 @@ class Domain
|
|||
$bUseSieve, $sSieveHost, $iSievePort, $iSieveSecure,
|
||||
$sOutHost, $iOutPort, $iOutSecure, $bOutShortLogin, $bOutAuth, $bOutUsePhpMail,
|
||||
$sWhiteList);
|
||||
|
||||
$oDomain->SetSieveAllowRaw($bSieveAllowRaw);
|
||||
}
|
||||
|
||||
return $oDomain;
|
||||
|
|
@ -257,6 +267,7 @@ class Domain
|
|||
'imap_secure = "'.self::ConstConnectionSecurityTypeToStr($this->iIncSecure).'"',
|
||||
'imap_short_login = '.($this->bIncShortLogin ? 'On' : 'Off'),
|
||||
'sieve_use = '.($this->bUseSieve ? 'On' : 'Off'),
|
||||
'sieve_allow_raw = '.($this->bSieveAllowRaw ? 'On' : 'Off'),
|
||||
'sieve_host = "'.$this->encodeIniString($this->sSieveHost).'"',
|
||||
'sieve_port = '.$this->iSievePort,
|
||||
'sieve_secure = "'.self::ConstConnectionSecurityTypeToStr($this->iSieveSecure).'"',
|
||||
|
|
@ -427,6 +438,22 @@ class Domain
|
|||
return $this->iSieveSecure;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function SieveAllowRaw()
|
||||
{
|
||||
return $this->bSieveAllowRaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bSieveAllowRaw
|
||||
*/
|
||||
public function SetSieveAllowRaw($bSieveAllowRaw)
|
||||
{
|
||||
$this->bSieveAllowRaw = !!$bSieveAllowRaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
|
@ -524,6 +551,7 @@ class Domain
|
|||
'SieveHost' => $bAjax ? \MailSo\Base\Utils::IdnToUtf8($this->SieveHost()) : $this->SieveHost(),
|
||||
'SievePort' => $this->SievePort(),
|
||||
'SieveSecure' => $this->SieveSecure(),
|
||||
'SieveAllowRaw' => $this->SieveAllowRaw(),
|
||||
'OutHost' => $bAjax ? \MailSo\Base\Utils::IdnToUtf8($this->OutHost()) : $this->OutHost(),
|
||||
'OutPort' => $this->OutPort(),
|
||||
'OutSecure' => $this->OutSecure(),
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ class Domain extends \RainLoop\Providers\AbstractProvider
|
|||
$iIncSecure = (int) $oActions->GetActionParam('IncSecure', \MailSo\Net\Enumerations\ConnectionSecurityType::NONE);
|
||||
$bIncShortLogin = '1' === (string) $oActions->GetActionParam('IncShortLogin', '0');
|
||||
$bUseSieve = '1' === (string) $oActions->GetActionParam('UseSieve', '0');
|
||||
$bSieveAllowRaw = '1' === (string) $oActions->GetActionParam('SieveAllowRaw', '0');
|
||||
$sSieveHost = (string) $oActions->GetActionParam('SieveHost', '');
|
||||
$iSievePort = (int) $oActions->GetActionParam('SievePort', 2000);
|
||||
$iSieveSecure = (int) $oActions->GetActionParam('SieveSecure', \MailSo\Net\Enumerations\ConnectionSecurityType::NONE);
|
||||
|
|
@ -173,6 +174,11 @@ class Domain extends \RainLoop\Providers\AbstractProvider
|
|||
$sWhiteList);
|
||||
}
|
||||
}
|
||||
|
||||
if ($oDomain)
|
||||
{
|
||||
$oDomain->SetSieveAllowRaw($bSieveAllowRaw);
|
||||
}
|
||||
}
|
||||
|
||||
return $oDomain;
|
||||
|
|
|
|||
|
|
@ -18,21 +18,28 @@ class Filters extends \RainLoop\Providers\AbstractProvider
|
|||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param bool $bAllowRaw = false
|
||||
*
|
||||
* @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 string $sRaw = ''
|
||||
* @param bool $bRawIsActive = false
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
private $bKeepForward;
|
||||
private $bKeep;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -81,7 +81,7 @@ class Filter
|
|||
|
||||
$this->bMarkAsRead = false;
|
||||
$this->bSkipOthers = false;
|
||||
$this->bKeepForward = true;
|
||||
$this->bKeep = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -167,9 +167,9 @@ class Filter
|
|||
/**
|
||||
* @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->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->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(
|
||||
isset($aFilter['Conditions']) ? $aFilter['Conditions'] : array());
|
||||
|
|
@ -255,6 +255,7 @@ class Filter
|
|||
'ActionType' => $this->ActionType(),
|
||||
'ActionValue' => $this->ActionValue(),
|
||||
'ActionValueSecond' => $this->ActionValueSecond(),
|
||||
'Keep' => $this->Keep(),
|
||||
'MarkAsRead' => $this->MarkAsRead(),
|
||||
'SkipOthers' => $this->SkipOthers()
|
||||
);
|
||||
|
|
|
|||
|
|
@ -8,5 +8,6 @@ class ActionType
|
|||
const MOVE_TO = 'MoveTo';
|
||||
const DISCARD = 'Discard';
|
||||
const VACATION = 'Vacation';
|
||||
const REJECT = 'Reject';
|
||||
const FORWARD = 'Forward';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,14 +5,18 @@ namespace RainLoop\Providers\Filters;
|
|||
interface FiltersInterface
|
||||
{
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param bool $bAllowRaw = false
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function Load();
|
||||
public function Load($oAccount, $bAllowRaw = false);
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param array $aFilters
|
||||
*
|
||||
* @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
|
||||
{
|
||||
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
|
||||
|
|
@ -12,31 +30,130 @@ class SieveStorage implements \RainLoop\Providers\Filters\FiltersInterface
|
|||
private $bUtf8FolderName;
|
||||
|
||||
/**
|
||||
* @param bool $bUtf8FolderName = true
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
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 string $sRaw = ''
|
||||
* @param bool $bRawIsActive = false
|
||||
*
|
||||
* @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';
|
||||
}
|
||||
break;
|
||||
case \RainLoop\Providers\Filters\Enumerations\ActionType::REJECT:
|
||||
$sValue = \trim($oFilter->ActionValue());
|
||||
if (0 < \strlen($sValue))
|
||||
{
|
||||
$aCapa['reject'] = true;
|
||||
|
||||
$aResult[] = $sTab.'reject "'.$this->quote($sValue).'";';
|
||||
$aResult[] = $sTab.'stop;';
|
||||
}
|
||||
else
|
||||
{
|
||||
$aResult[] = $sTab.'# @Error (reject): empty action value';
|
||||
}
|
||||
break;
|
||||
case \RainLoop\Providers\Filters\Enumerations\ActionType::FORWARD:
|
||||
$sValue = $oFilter->ActionValue();
|
||||
if (0 < \strlen($sValue))
|
||||
{
|
||||
if ($oFilter->KeepForward())
|
||||
if ($oFilter->Keep())
|
||||
{
|
||||
$aCapa['copy'] = true;
|
||||
$aResult[] = $sTab.'redirect :copy "'.$this->quote($sValue).'";';
|
||||
}
|
||||
else
|
||||
{
|
||||
$aResult[] = $sTab.'redirect "'.$this->quote($sValue).'";';
|
||||
$aCapa['fileinto'] = true;
|
||||
$aResult[] = $sTab.'fileinto "INBOX";';
|
||||
}
|
||||
|
||||
$aResult[] = $sTab.'redirect "'.$this->quote($sValue).'";';
|
||||
$aResult[] = $sTab.'stop;';
|
||||
}
|
||||
else
|
||||
|
|
@ -246,8 +374,6 @@ class SieveStorage implements \RainLoop\Providers\Filters\FiltersInterface
|
|||
$sValue = $oFilter->ActionValue();
|
||||
if (0 < \strlen($sValue))
|
||||
{
|
||||
$aCapa['fileinto'] = true;
|
||||
|
||||
$sFolderName = $sValue; // utf7-imap
|
||||
if ($this->bUtf8FolderName) // to utf-8
|
||||
{
|
||||
|
|
@ -256,6 +382,7 @@ class SieveStorage implements \RainLoop\Providers\Filters\FiltersInterface
|
|||
\MailSo\Base\Enumerations\Charset::UTF_8);
|
||||
}
|
||||
|
||||
$aCapa['fileinto'] = true;
|
||||
$aResult[] = $sTab.'fileinto "'.$this->quote($sFolderName).'";';
|
||||
$aResult[] = $sTab.'stop;';
|
||||
}
|
||||
|
|
@ -359,4 +486,12 @@ class SieveStorage implements \RainLoop\Providers\Filters\FiltersInterface
|
|||
{
|
||||
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: {
|
||||
name: 'Checkbox',
|
||||
params: {
|
||||
label: 'use Sieve for this domain',
|
||||
label: 'Use Sieve for this domain',
|
||||
value: useSieve
|
||||
}
|
||||
}"></div>
|
||||
</div>
|
||||
</div>
|
||||
<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 />
|
||||
<div class="row">
|
||||
<div class="span3">
|
||||
|
|
|
|||
|
|
@ -11,7 +11,12 @@
|
|||
|
||||
<span class="i18n" data-i18n-text="SETTINGS_FILTERS/BUTTON_ADD_FILTER"></span>
|
||||
</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">
|
||||
<i data-bind="css: {'icon-floppy': !filters.saving(), 'icon-spinner animated': filters.saving()}"></i>
|
||||
|
||||
|
|
@ -36,7 +41,11 @@
|
|||
|
||||
<span data-bind="text: processText"></span>
|
||||
</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>
|
||||
<col style="width: 30px" />
|
||||
<col />
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@
|
|||
name: 'Checkbox',
|
||||
params: {
|
||||
label: 'keep in INBOX @i18n',
|
||||
value: keepForward
|
||||
value: actionKeep
|
||||
}
|
||||
}"></div>
|
||||
<div data-bind="component: {
|
||||
<div data-bind="visible: $root.allowMarkAsRead, component: {
|
||||
name: 'Checkbox',
|
||||
params: {
|
||||
label: 'Mark as read @i18n',
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
</div>
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<div data-bind="component: {
|
||||
<div data-bind="visible: $root.allowMarkAsRead, component: {
|
||||
name: 'Checkbox',
|
||||
params: {
|
||||
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" />
|
||||
|
||||
<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>
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -173,7 +173,6 @@ LABEL_EMAIL = "Email"
|
|||
LABEL_PHONE = "Phone"
|
||||
LABEL_WEB = "Web"
|
||||
LABEL_BIRTHDAY = "Birthday"
|
||||
LABEL_TAGS = "Tags"
|
||||
LINK_ADD_EMAIL = "Add an email address"
|
||||
LINK_ADD_PHONE = "Add a phone"
|
||||
LINK_BIRTHDAY = "Birthday"
|
||||
|
|
@ -376,10 +375,8 @@ TITLE_EDIT_FILTER = "Update filter?"
|
|||
LEGEND_FILTERS = "Filters"
|
||||
BUTTON_SAVE = "Save"
|
||||
BUTTON_DONE = "Done"
|
||||
BUTTON_ADD_FILTER = "Add Filter"
|
||||
BUTTON_SAVE_FILTER = "Save Filter"
|
||||
BUTTON_DELETE_FILTER = "Delete Filter"
|
||||
BUTTON_ADD_CONDITION = "Add Condition"
|
||||
BUTTON_ADD_FILTER = "Add a Filter"
|
||||
BUTTON_ADD_CONDITION = "Add a Condition"
|
||||
BUTTON_DELETE = "Delete"
|
||||
LOADING_PROCESS = "Updating filter list"
|
||||
DELETING_ASK = "Are you sure?"
|
||||
|
|
|
|||
|
|
@ -548,7 +548,7 @@ LABEL_SAVE_MESSAGE = "Guardar aviso"
|
|||
LABEL_SEND_MESSAGE = "Enviar mensaje"
|
||||
LABEL_CLOSE_COMPOSE = "Cerrar componer"
|
||||
|
||||
[ PGP_NOTIFICATIONS ]
|
||||
[PGP_NOTIFICATIONS]
|
||||
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_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.
|
||||
Abilitare il supporto a JavaScript e riprovare."
|
||||
|
||||
NO_SCRIPT_TITLE = "Sono richiesti i Cookie per questa applicazione."
|
||||
NO_SCRIPT_DESC = "Il supporto ai Cookie è disabilitato.
|
||||
NO_COOKIE_TITLE = "Sono richiesti i Cookie per questa applicazione."
|
||||
NO_COOKIE_DESC = "Il supporto ai Cookie è disabilitato.
|
||||
Abilitare il supporto ai Cookie e riprovare."
|
||||
|
||||
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_SEND_MESSAGE = "Kan ikke sende melding"
|
||||
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_DELETE_FOLDER = "Kan ikke slette mappen"
|
||||
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"
|
||||
UNSUPPORTED_PLUGIN_PACKAGE = "Plugin-ul necesită sprijinul complet al serverului"
|
||||
LICENSING_SERVER_IS_UNAVAILABLE = "Server de abonamente este temporar indisponibil."
|
||||
LICENSING_EXPIRED = "Licența a expirat."
|
||||
LICENSING_BANNED = "Licență restricționată."
|
||||
LICENSING_DOMAIN_EXPIRED = "Subscription for this domain has expired."
|
||||
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ă!"
|
||||
ACCOUNT_ALREADY_EXISTS = "Contul deja există"
|
||||
MAIL_SERVER_ERROR = "Nu am reușit să accesez serverul de e-mail"
|
||||
|
|
|
|||
|
|
@ -601,8 +601,8 @@ CANT_DELETE_PACKAGE = "Ошибка удаления пакета"
|
|||
INVALID_PLUGIN_PACKAGE = "Ошибка пакета плагина"
|
||||
UNSUPPORTED_PLUGIN_PACKAGE = "Для работы плагина необходима полная поддержка сервера"
|
||||
LICENSING_SERVER_IS_UNAVAILABLE = "Сервер подписок временно не доступен."
|
||||
LICENSING_EXPIRED = "Подписка на данный домен устарела."
|
||||
LICENSING_BANNED = "Подписка на данный домен заблокирована."
|
||||
LICENSING_DOMAIN_EXPIRED = "Подписка на данный домен устарела."
|
||||
LICENSING_DOMAIN_BANNED = "Подписка на данный домен заблокирована."
|
||||
DEMO_SEND_MESSAGE_ERROR = "Демо аккаунту отправка писем на внешние почтовые адреса запрещена!"
|
||||
ACCOUNT_ALREADY_EXISTS = "Аккаунт уже добавлен"
|
||||
MAIL_SERVER_ERROR = "Ошибка доступа к почтовому серверу"
|
||||
|
|
|
|||
|
|
@ -601,8 +601,8 @@ CANT_DELETE_PACKAGE = "Помилка видалення пакету"
|
|||
INVALID_PLUGIN_PACKAGE = "Помилка пакету плагіну"
|
||||
UNSUPPORTED_PLUGIN_PACKAGE = "Для роботи плагину необхідна повна підтримка серверу"
|
||||
LICENSING_SERVER_IS_UNAVAILABLE = "Сервер підписок тимчасово не доступний."
|
||||
LICENSING_EXPIRED = "Підписка на цей домен застаріла."
|
||||
LICENSING_BANNED = "Підписка на цей домен заблокована."
|
||||
LICENSING_DOMAIN_EXPIRED = "Підписка на цей домен застаріла."
|
||||
LICENSING_DOMAIN_BANNED = "Підписка на цей домен заблокована."
|
||||
DEMO_SEND_MESSAGE_ERROR = "Демо акаунту надсилання листів на зовнішні поштові адреси заборонена!"
|
||||
ACCOUNT_ALREADY_EXISTS = "акаунт вже додано"
|
||||
MAIL_SERVER_ERROR = "Помилка доступу до поштового серверу"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue