summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorAleksander Machniak <alec@alec.pl>2015-01-14 07:30:31 -0500
committerAleksander Machniak <alec@alec.pl>2015-01-14 07:30:31 -0500
commit6af79f1517d4a5c34088eaf6d0e5af69733f3eef (patch)
tree10168e78df7d23298c02ae4742524ae898de29a6 /plugins
parent1f9c9fea5529b2b2218f7b3f0e09bd804afc89ac (diff)
Support "not allof" test as a negation of all sub-tests
Fixes also last commit change.
Diffstat (limited to 'plugins')
-rw-r--r--plugins/managesieve/Changelog1
-rw-r--r--plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php56
-rw-r--r--plugins/managesieve/lib/Roundcube/rcube_sieve_script.php18
3 files changed, 58 insertions, 17 deletions
diff --git a/plugins/managesieve/Changelog b/plugins/managesieve/Changelog
index 13ef57764..af22bccc9 100644
--- a/plugins/managesieve/Changelog
+++ b/plugins/managesieve/Changelog
@@ -1,4 +1,5 @@
- Fix bug where actions without if/elseif/else in sieve scripts were skipped
+- Support "not allof" test as a negation of all sub-tests
* version 8.1 [2014-12-09]
-----------------------------------------------------------
diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php b/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php
index 6ed876267..035b26720 100644
--- a/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php
+++ b/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php
@@ -1270,7 +1270,7 @@ class rcube_sieve_engine
$out .= $hiddenfields->show();
// 'any' flag
- if ((!isset($this->form) && empty($scr['tests']) && !empty($src))
+ if ((!isset($this->form) && empty($scr['tests']) && !empty($scr))
|| (sizeof($scr['tests']) == 1 && $scr['tests'][0]['test'] == 'true' && !$scr['tests'][0]['not'])
) {
$any = true;
@@ -1335,7 +1335,7 @@ class rcube_sieve_engine
$out .= sprintf("%s<label for=\"%s\">%s</label>\n",
$input_join, $field_id, rcube::Q($this->plugin->gettext('filterany')));
- $rows_num = isset($scr) ? sizeof($scr['tests']) : 1;
+ $rows_num = !empty($scr['tests']) ? sizeof($scr['tests']) : 1;
$out .= '<div id="rules"'.($any ? ' style="display: none"' : '').'>';
for ($x=0; $x<$rows_num; $x++)
@@ -1466,31 +1466,26 @@ class rcube_sieve_engine
$select_op->add(rcube::Q($this->plugin->gettext('valuenotequals')), 'value-ne');
}
+ $test = self::rule_test($rule);
+ $target = '';
+
// target(s) input
if (in_array($rule['test'], array('header', 'address', 'envelope'))) {
- $test = ($rule['not'] ? 'not' : '').($rule['type'] ? $rule['type'] : 'is');
$target = $rule['arg2'];
}
else if (in_array($rule['test'], array('body', 'date', 'currentdate'))) {
- $test = ($rule['not'] ? 'not' : '').($rule['type'] ? $rule['type'] : 'is');
$target = $rule['arg'];
}
else if ($rule['test'] == 'size') {
- $test = '';
- $target = '';
if (preg_match('/^([0-9]+)(K|M|G)?$/', $rule['arg'], $matches)) {
$sizetarget = $matches[1];
- $sizeitem = $matches[2];
+ $sizeitem = $matches[2];
}
else {
$sizetarget = $rule['arg'];
- $sizeitem = $rule['item'];
+ $sizeitem = $rule['item'];
}
}
- else {
- $test = ($rule['not'] ? 'not' : '').$rule['test'];
- $target = '';
- }
// (current)date part select
if (in_array('date', $this->exts) || in_array('currentdate', $this->exts)) {
@@ -1640,6 +1635,43 @@ class rcube_sieve_engine
return $out;
}
+ private static function rule_test(&$rule)
+ {
+ // first modify value/count tests with 'not' keyword
+ // we'll revert the meaning of operators
+ if ($rule['not'] && preg_match('/^(count|value)-([gteqnl]{2})/', $rule['type'], $m)) {
+ $rule['not'] = false;
+
+ switch ($m[2]) {
+ case 'gt': $rule['type'] = $m[1] . '-le'; break;
+ case 'ge': $rule['type'] = $m[1] . '-lt'; break;
+ case 'lt': $rule['type'] = $m[1] . '-ge'; break;
+ case 'le': $rule['type'] = $m[1] . '-gt'; break;
+ case 'eq': $rule['type'] = $m[1] . '-ne'; break;
+ case 'ne': $rule['type'] = $m[1] . '-eq'; break;
+ }
+ }
+ else if ($rule['not'] && $rule['test'] == 'size') {
+ $rule['not'] = false;
+ $rule['type'] = $rule['type'] == 'over' ? 'under' : 'over';
+ }
+
+ $set = array('header', 'address', 'envelope', 'body', 'date', 'currentdate');
+
+ // build test string supported by select element
+ if ($rule['size']) {
+ $test = $rule['type'];
+ }
+ else if (in_array($rule['test'], $set)) {
+ $test = ($rule['not'] ? 'not' : '') . ($rule['type'] ? $rule['type'] : 'is');
+ }
+ else {
+ $test = ($rule['not'] ? 'not' : '') . $rule['test'];
+ }
+
+ return $test;
+ }
+
function action_div($fid, $id, $div=true)
{
$action = isset($this->form) ? $this->form['actions'][$id] : $this->script[$fid]['actions'][$id];
diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php b/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php
index bc62d2ff4..518d79d35 100644
--- a/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php
+++ b/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php
@@ -622,6 +622,7 @@ class rcube_sieve_script
$disabled = false;
$join = false;
+ $join_not = false;
// disabled rule (false + comment): if false # .....
if (preg_match('/^\s*false\s+#/i', $content)) {
@@ -650,15 +651,22 @@ class rcube_sieve_script
$not = false;
}
+ // we support "not allof" as a negation of allof sub-tests
+ if ($join_not) {
+ $not = !$not;
+ }
+
switch ($token) {
case 'allof':
- $join = true;
+ $join = true;
+ $join_not = $not;
break;
+
case 'anyof':
break;
case 'size':
- $test = array('test' => 'size', 'not' => $not);
+ $test = array('test' => 'size', 'not' => $not);
$test['arg'] = array_pop($tokens);
@@ -740,16 +748,16 @@ class rcube_sieve_script
break;
case 'exists':
- $tests[] = array('test' => 'exists', 'not' => $not,
+ $tests[] = array('test' => 'exists', 'not' => $not,
'arg' => array_pop($tokens));
break;
case 'true':
- $tests[] = array('test' => 'true', 'not' => $not);
+ $tests[] = array('test' => 'true', 'not' => $not);
break;
case 'false':
- $tests[] = array('test' => 'true', 'not' => !$not);
+ $tests[] = array('test' => 'true', 'not' => !$not);
break;
}