Changeset 5441 in subversion
- Timestamp:
- Nov 17, 2011 8:18:48 AM (18 months ago)
- Location:
- trunk/plugins/managesieve
- Files:
-
- 7 added
- 11 edited
-
Changelog (modified) (1 diff)
-
lib/rcube_sieve.php (modified) (3 diffs)
-
lib/rcube_sieve_script.php (modified) (10 diffs)
-
localization/en_US.inc (modified) (1 diff)
-
localization/pl_PL.inc (modified) (1 diff)
-
managesieve.js (modified) (4 diffs)
-
managesieve.php (modified) (9 diffs)
-
skins/default/images/down_small.gif (added)
-
skins/default/images/up_small.gif (added)
-
skins/default/managesieve.css (modified) (5 diffs)
-
tests/parser.phpt (modified) (7 diffs)
-
tests/parser_body.phpt (added)
-
tests/parser_imapflags.phpt (modified) (1 diff)
-
tests/parser_include.phpt (added)
-
tests/parser_kep14.phpt (modified) (1 diff)
-
tests/parser_prefix.phpt (added)
-
tests/parser_variables.phpt (added)
-
tests/parset_subaddress.phpt (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/plugins/managesieve/Changelog
r5440 r5441 1 * version 5.0-rc1 [2011-11-17] 2 ----------------------------------------------------------- 1 3 - Fixed sorting of scripts, scripts including aware of the sort order 2 4 - Fixed import of rules with unsupported tests 5 - Added 'address' and 'envelope' tests support 6 - Added 'body' extension support (RFC5173) 7 - Added 'subaddress' extension support (RFC5233) 8 - Added comparators support 9 - Changed Sender/Recipient labels to From/To 10 - Fixed importing rule names from Ingo 11 - Fixed handling of extensions disabled in config 3 12 4 13 * version 5.0-beta [2011-10-17] -
trunk/plugins/managesieve/lib/rcube_sieve.php
r5300 r5441 45 45 public $script; // rcube_sieve_script object 46 46 public $current; // name of currently loaded script 47 private $disabled; // array of disabled extensions48 47 private $exts; // array of supported extensions 49 48 … … 90 89 91 90 $this->exts = $this->get_extensions(); 92 $this->disabled = $disabled; 91 92 // disable features by config 93 if (!empty($disabled)) { 94 // we're working on lower-cased names 95 $disabled = array_map('strtolower', (array) $disabled); 96 foreach ($disabled as $ext) { 97 if (($idx = array_search($ext, $this->exts)) !== false) { 98 unset($this->exts[$idx]); 99 } 100 } 101 } 93 102 } 94 103 … … 302 311 { 303 312 // parse 304 $script = new rcube_sieve_script($txt, $this-> disabled, $this->exts);313 $script = new rcube_sieve_script($txt, $this->exts); 305 314 306 315 // fix/convert to Roundcube format -
trunk/plugins/managesieve/lib/rcube_sieve_script.php
r5440 r5441 32 32 private $capabilities = array(); // Sieve extensions supported by server 33 33 private $supported = array( // Sieve extensions supported by class 34 'fileinto', // RFC3028 34 'fileinto', // RFC5228 35 'envelope', // RFC5228 35 36 'reject', // RFC5429 36 37 'ereject', // RFC5429 … … 43 44 'include', // draft-ietf-sieve-include-12 44 45 'variables', // RFC5229 45 // TODO: body, notify 46 'body', // RFC5173 47 'subaddress', // RFC5233 48 // @TODO: enotify/notify, spamtest+virustest, mailbox, date 46 49 ); 47 50 … … 50 53 * 51 54 * @param string Script's text content 52 * @param array List of disabled extensions53 55 * @param array List of capabilities supported by server 54 56 */ 55 public function __construct($script, $disabled=array(), $capabilities=array()) 56 { 57 if (!empty($disabled)) { 58 // we're working on lower-cased names 59 $disabled = array_map('strtolower', (array) $disabled); 60 foreach ($disabled as $ext) { 61 if (($idx = array_search($ext, $this->supported)) !== false) { 57 public function __construct($script, $capabilities=array()) 58 { 59 $this->capabilities = array_map('strtolower', (array) $capabilities); 60 61 // disable features by server capabilities 62 if (!empty($this->capabilities)) { 63 foreach ($this->supported as $idx => $ext) { 64 if (!in_array($ext, $this->capabilities)) { 62 65 unset($this->supported[$idx]); 63 66 } 64 67 } 65 68 } 66 67 $this->capabilities = array_map('strtolower', (array) $capabilities);68 69 69 70 // Parse text content of the script … … 183 184 184 185 if (!empty($this->vars)) { 185 if (in_array('variables', (array)$this-> capabilities)) {186 if (in_array('variables', (array)$this->supported)) { 186 187 $has_vars = true; 187 188 array_push($exts, 'variables'); … … 223 224 $tests[$i] .= 'size :' . ($test['type']=='under' ? 'under ' : 'over ') . $test['arg']; 224 225 break; 226 225 227 case 'true': 226 228 $tests[$i] .= ($test['not'] ? 'false' : 'true'); 227 229 break; 230 228 231 case 'exists': 229 232 $tests[$i] .= ($test['not'] ? 'not ' : ''); 230 233 $tests[$i] .= 'exists ' . self::escape_string($test['arg']); 231 234 break; 235 232 236 case 'header': 233 237 $tests[$i] .= ($test['not'] ? 'not ' : ''); 234 235 // relational operator + comparator 236 if (preg_match('/^(value|count)-([gteqnl]{2})/', $test['type'], $m)) { 237 array_push($exts, 'relational'); 238 array_push($exts, 'comparator-i;ascii-numeric'); 239 240 $tests[$i] .= 'header :' . $m[1] . ' "' . $m[2] . '" :comparator "i;ascii-numeric"'; 241 } 242 else { 238 $tests[$i] .= 'header'; 239 240 if (!empty($test['type'])) { 241 // relational operator + comparator 242 if (preg_match('/^(value|count)-([gteqnl]{2})/', $test['type'], $m)) { 243 array_push($exts, 'relational'); 244 array_push($exts, 'comparator-i;ascii-numeric'); 245 246 $tests[$i] .= ' :' . $m[1] . ' "' . $m[2] . '" :comparator "i;ascii-numeric"'; 247 } 248 else { 249 $this->add_comparator($test, $tests[$i], $exts); 250 251 if ($test['type'] == 'regex') { 252 array_push($exts, 'regex'); 253 } 254 255 $tests[$i] .= ' :' . $test['type']; 256 } 257 } 258 259 $tests[$i] .= ' ' . self::escape_string($test['arg1']); 260 $tests[$i] .= ' ' . self::escape_string($test['arg2']); 261 break; 262 263 case 'address': 264 case 'envelope': 265 if ($test['test'] == 'envelope') { 266 array_push($exts, 'envelope'); 267 } 268 269 $tests[$i] .= ($test['not'] ? 'not ' : ''); 270 $tests[$i] .= $test['test']; 271 272 if (!empty($test['part'])) { 273 $tests[$i] .= ' :' . $test['part']; 274 if ($test['part'] == 'user' || $test['part'] == 'detail') { 275 array_push($exts, 'subaddress'); 276 } 277 } 278 279 $this->add_comparator($test, $tests[$i], $exts); 280 281 if (!empty($test['type'])) { 243 282 if ($test['type'] == 'regex') { 244 283 array_push($exts, 'regex'); 245 284 } 246 247 $tests[$i] .= 'header :' . $test['type']; 285 $tests[$i] .= ' :' . $test['type']; 248 286 } 249 287 250 288 $tests[$i] .= ' ' . self::escape_string($test['arg1']); 251 289 $tests[$i] .= ' ' . self::escape_string($test['arg2']); 290 break; 291 292 case 'body': 293 array_push($exts, 'body'); 294 295 $tests[$i] .= ($test['not'] ? 'not ' : '') . 'body'; 296 297 $this->add_comparator($test, $tests[$i], $exts); 298 299 if (!empty($test['part'])) { 300 $tests[$i] .= ' :' . $test['part']; 301 302 if (!empty($test['content']) && $test['part'] == 'content') { 303 $tests[$i] .= ' ' . self::escape_string($test['content']); 304 } 305 } 306 307 if (!empty($test['type'])) { 308 if ($test['type'] == 'regex') { 309 array_push($exts, 'regex'); 310 } 311 $tests[$i] .= ' :' . $test['type']; 312 } 313 314 $tests[$i] .= ' ' . self::escape_string($test['arg']); 252 315 break; 253 316 } … … 312 375 case 'setflag': 313 376 case 'removeflag': 314 if (i s_array($this->capabilities) && in_array('imap4flags', $this->capabilities))377 if (in_array('imap4flags', $this->supported)) 315 378 array_push($exts, 'imap4flags'); 316 379 else … … 449 512 if (empty($options['prefix'])) { 450 513 $options['prefix'] = true; 451 if ($prefix && strpos($prefix, ' Generated by Ingo')) {514 if ($prefix && strpos($prefix, 'horde.org/ingo')) { 452 515 $options['format'] = 'INGO'; 453 516 } … … 560 623 for ($i=0, $len=count($tokens); $i<$len; $i++) { 561 624 if (!is_array($tokens[$i]) && preg_match('/^:comparator$/i', $tokens[$i])) { 562 $ i++;625 $header['comparator'] = $tokens[++$i]; 563 626 } 564 627 else if (!is_array($tokens[$i]) && preg_match('/^:(count|value)$/i', $tokens[$i])) { … … 571 634 $header['arg1'] = $header['arg2']; 572 635 $header['arg2'] = $tokens[$i]; 636 } 637 } 638 639 $tests[] = $header; 640 break; 641 642 case 'address': 643 case 'envelope': 644 $header = array('test' => $token, 'not' => $not, 'arg1' => '', 'arg2' => ''); 645 for ($i=0, $len=count($tokens); $i<$len; $i++) { 646 if (!is_array($tokens[$i]) && preg_match('/^:comparator$/i', $tokens[$i])) { 647 $header['comparator'] = $tokens[++$i]; 648 } 649 else if (!is_array($tokens[$i]) && preg_match('/^:(is|contains|matches|regex)$/i', $tokens[$i])) { 650 $header['type'] = strtolower(substr($tokens[$i], 1)); 651 } 652 else if (!is_array($tokens[$i]) && preg_match('/^:(localpart|domain|all|user|detail)$/i', $tokens[$i])) { 653 $header['part'] = strtolower(substr($tokens[$i], 1)); 654 } 655 else { 656 $header['arg1'] = $header['arg2']; 657 $header['arg2'] = $tokens[$i]; 658 } 659 } 660 661 $tests[] = $header; 662 break; 663 664 case 'body': 665 $header = array('test' => 'body', 'not' => $not, 'arg' => ''); 666 for ($i=0, $len=count($tokens); $i<$len; $i++) { 667 if (!is_array($tokens[$i]) && preg_match('/^:comparator$/i', $tokens[$i])) { 668 $header['comparator'] = $tokens[++$i]; 669 } 670 else if (!is_array($tokens[$i]) && preg_match('/^:(is|contains|matches|regex)$/i', $tokens[$i])) { 671 $header['type'] = strtolower(substr($tokens[$i], 1)); 672 } 673 else if (!is_array($tokens[$i]) && preg_match('/^:(raw|content|text)$/i', $tokens[$i])) { 674 $header['part'] = strtolower(substr($tokens[$i], 1)); 675 676 if ($header['part'] == 'content') { 677 $header['content'] = $tokens[++$i]; 678 } 679 } 680 else { 681 $header['arg'] = $tokens[$i]; 573 682 } 574 683 } … … 743 852 744 853 return $result; 854 } 855 856 /** 857 * 858 */ 859 private function add_comparator($test, &$out, &$exts) 860 { 861 if (empty($test['comparator'])) { 862 return; 863 } 864 865 if ($test['comparator'] == 'i;ascii-numeric') { 866 array_push($exts, 'relational'); 867 array_push($exts, 'comparator-i;ascii-numeric'); 868 } 869 else if (!in_array($test['comparator'], array('i;octet', 'i;ascii-casemap'))) { 870 array_push($exts, 'comparator-' . $test['comparator']); 871 } 872 873 // skip default comparator 874 if ($test['comparator'] != 'i;ascii-casemap') { 875 $out .= ' :comparator ' . self::escape_string($test['comparator']); 876 } 745 877 } 746 878 -
trunk/plugins/managesieve/localization/en_US.inc
r5340 r5441 83 83 $labels['nextstep'] = 'Next Step'; 84 84 $labels['...'] = '...'; 85 $labels['advancedopts'] = 'Advanced options'; 86 $labels['body'] = 'Body'; 87 $labels['address'] = 'address'; 88 $labels['envelope'] = 'envelope'; 89 $labels['modifier'] = 'modifier:'; 90 $labels['text'] = 'text'; 91 $labels['undecoded'] = 'undecoded (raw)'; 92 $labels['contenttype'] = 'content type'; 93 $labels['modtype'] = 'type:'; 94 $labels['allparts'] = 'all'; 95 $labels['domain'] = 'domain'; 96 $labels['localpart'] = 'local part'; 97 $labels['user'] = 'user'; 98 $labels['detail'] = 'detail'; 99 $labels['comparator'] = 'comparator:'; 100 $labels['default'] = 'default'; 101 $labels['octet'] = 'strict (octet)'; 102 $labels['asciicasemap'] = 'case insensitive (ascii-casemap)'; 103 $labels['asciinumeric'] = 'numeric (ascii-numeric)'; 85 104 86 105 $messages = array(); -
trunk/plugins/managesieve/localization/pl_PL.inc
r5340 r5441 97 97 $labels['nextstep'] = 'NastÄpny krok'; 98 98 $labels['...'] = '...'; 99 $labels['advancedopts'] = 'Zaawansowane opcje'; 100 $labels['body'] = 'TreÅÄ'; 101 $labels['address'] = 'adres'; 102 $labels['envelope'] = 'koperta (envelope)'; 103 $labels['modifier'] = 'modyfikator:'; 104 $labels['text'] = 'tekst'; 105 $labels['undecoded'] = 'nie (raw)'; 106 $labels['contenttype'] = 'typ czÄÅci (content type)'; 107 $labels['modtype'] = 'typ:'; 108 $labels['allparts'] = 'wszystkie'; 109 $labels['domain'] = 'domena'; 110 $labels['localpart'] = 'czÄÅÄ lokalna'; 111 $labels['user'] = 'uÅŒytkownik'; 112 $labels['detail'] = 'detal'; 113 $labels['comparator'] = 'komparator:'; 114 $labels['default'] = 'domyÅlny'; 115 $labels['octet'] = 'dokÅadny (octet)'; 116 $labels['asciicasemap'] = 'nierozróŌniajÄ 117 cy wielkoÅci liter (ascii-casemap)'; 118 $labels['asciinumeric'] = 'numeryczny (ascii-numeric)'; 99 119 100 120 $messages = array(); -
trunk/plugins/managesieve/managesieve.js
r5348 r5441 543 543 op = document.getElementById('rule_op' + id), 544 544 target = document.getElementById('rule_target' + id), 545 header = document.getElementById('custom_header' + id); 545 header = document.getElementById('custom_header' + id), 546 mod = document.getElementById('rule_mod' + id), 547 trans = document.getElementById('rule_trans' + id), 548 comp = document.getElementById('rule_comp' + id); 546 549 547 550 if (obj.value == 'size') { … … 550 553 target.style.display = 'none'; 551 554 header.style.display = 'none'; 555 mod.style.display = 'none'; 556 trans.style.display = 'none'; 557 comp.style.display = 'none'; 552 558 } 553 559 else { … … 555 561 size.style.display = 'none'; 556 562 op.style.display = 'inline'; 563 comp.style.display = ''; 557 564 rule_op_select(id); 565 mod.style.display = obj.value == 'body' ? 'none' : 'block'; 566 trans.style.display = obj.value == 'body' ? 'block' : 'none'; 558 567 } 559 568 … … 569 578 }; 570 579 580 function rule_trans_select(id) 581 { 582 var obj = document.getElementById('rule_trans_op' + id), 583 target = document.getElementById('rule_trans_type' + id); 584 585 target.style.display = obj.value != 'content' ? 'none' : 'inline'; 586 }; 587 588 function rule_mod_select(id) 589 { 590 var obj = document.getElementById('rule_mod_op' + id), 591 target = document.getElementById('rule_mod_type' + id); 592 593 target.style.display = obj.value != 'address' && obj.value != 'envelope' ? 'none' : 'inline'; 594 }; 595 571 596 function rule_join_radio(value) 572 597 { 573 598 $('#rules').css('display', value == 'any' ? 'none' : 'block'); 574 599 }; 600 601 function rule_adv_switch(id, elem) 602 { 603 var elem = $(elem), enabled = elem.hasClass('hide'), adv = $('#rule_advanced'+id); 604 605 if (enabled) { 606 adv.hide(); 607 elem.removeClass('hide').addClass('show'); 608 } 609 else { 610 adv.show(); 611 elem.removeClass('show').addClass('hide'); 612 } 613 } 575 614 576 615 function action_type_select(id) -
trunk/plugins/managesieve/managesieve.php
r5348 r5441 46 46 private $active = array(); 47 47 private $headers = array( 48 'subject' => 'Subject', 49 'sender' => 'From', 50 'recipient' => 'To', 48 'subject' => 'Subject', 49 'from' => 'From', 50 'to' => 'To', 51 ); 52 private $addr_headers = array( 53 // Required 54 "from", "to", "cc", "bcc", "sender", "resent-from", "resent-to", 55 // Additional (RFC 822 / RFC 2822) 56 "reply-to", "resent-reply-to", "resent-sender", "resent-cc", "resent-bcc", 57 // Non-standard (RFC 2076, draft-palme-mailext-headers-08.txt) 58 "for-approval", "for-handling", "for-comment", "apparently-to", "errors-to", 59 "delivered-to", "return-receipt-to", "x-admin", "read-receipt-to", 60 "x-confirm-reading-to", "return-receipt-requested", 61 "registered-mail-reply-requested-by", "mail-followup-to", "mail-reply-to", 62 "abuse-reports-to", "x-complaints-to", "x-report-abuse-to", 63 // Undocumented 64 "x-beenthere", 51 65 ); 52 66 … … 589 603 $sizetargets = get_input_value('_rule_size_target', RCUBE_INPUT_POST); 590 604 $targets = get_input_value('_rule_target', RCUBE_INPUT_POST, true); 605 $mods = get_input_value('_rule_mod', RCUBE_INPUT_POST); 606 $mod_types = get_input_value('_rule_mod_type', RCUBE_INPUT_POST); 607 $body_trans = get_input_value('_rule_trans', RCUBE_INPUT_POST); 608 $body_types = get_input_value('_rule_trans_type', RCUBE_INPUT_POST, true); 609 $comparators = get_input_value('_rule_comp', RCUBE_INPUT_POST); 591 610 $act_types = get_input_value('_action_type', RCUBE_INPUT_POST, true); 592 611 $mailboxes = get_input_value('_action_mailbox', RCUBE_INPUT_POST, true); … … 626 645 else { 627 646 foreach ($headers as $idx => $header) { 628 $header = $this->strip_value($header); 629 $target = $this->strip_value($targets[$idx], true); 630 $op = $this->strip_value($ops[$idx]); 631 632 // normal header 633 if (in_array($header, $this->headers)) { 634 if (preg_match('/^not/', $op)) 647 $header = $this->strip_value($header); 648 $target = $this->strip_value($targets[$idx], true); 649 $operator = $this->strip_value($ops[$idx]); 650 $comparator = $this->strip_value($comparators[$idx]); 651 652 if ($header == 'size') { 653 $sizeop = $this->strip_value($sizeops[$idx]); 654 $sizeitem = $this->strip_value($items[$idx]); 655 $sizetarget = $this->strip_value($sizetargets[$idx]); 656 657 $this->form['tests'][$i]['test'] = 'size'; 658 $this->form['tests'][$i]['type'] = $sizeop; 659 $this->form['tests'][$i]['arg'] = $sizetarget; 660 661 if ($sizetarget == '') 662 $this->errors['tests'][$i]['sizetarget'] = $this->gettext('cannotbeempty'); 663 else if (!preg_match('/^[0-9]+(K|M|G)?$/i', $sizetarget.$sizeitem, $m)) { 664 $this->errors['tests'][$i]['sizetarget'] = $this->gettext('forbiddenchars'); 665 $this->form['tests'][$i]['item'] = $sizeitem; 666 } 667 else 668 $this->form['tests'][$i]['arg'] .= $m[1]; 669 } 670 else if ($header == 'body') { 671 $trans = $this->strip_value($body_trans[$idx]); 672 $trans_type = $this->strip_value($body_types[$idx], true); 673 674 if (preg_match('/^not/', $operator)) 635 675 $this->form['tests'][$i]['not'] = true; 636 $type = preg_replace('/^not/', '', $op); 676 $type = preg_replace('/^not/', '', $operator); 677 678 if ($type == 'exists') { 679 $this->errors['tests'][$i]['op'] = true; 680 } 681 682 $this->form['tests'][$i]['test'] = 'body'; 683 $this->form['tests'][$i]['type'] = $type; 684 $this->form['tests'][$i]['arg'] = $target; 685 686 if ($target == '' && $type != 'exists') 687 $this->errors['tests'][$i]['target'] = $this->gettext('cannotbeempty'); 688 else if (preg_match('/^(value|count)-/', $type) && !preg_match('/[0-9]+/', $target)) 689 $this->errors['tests'][$i]['target'] = $this->gettext('forbiddenchars'); 690 691 $this->form['tests'][$i]['part'] = $trans; 692 if ($trans == 'content') { 693 $this->form['tests'][$i]['content'] = $trans_type; 694 } 695 } 696 else { 697 $cust_header = $headers = $this->strip_value($cust_headers[$idx]); 698 $mod = $this->strip_value($mods[$idx]); 699 $mod_type = $this->strip_value($mod_types[$idx]); 700 701 if (preg_match('/^not/', $operator)) 702 $this->form['tests'][$i]['not'] = true; 703 $type = preg_replace('/^not/', '', $operator); 704 705 if ($header == '...') { 706 $headers = preg_split('/[\s,]+/', $cust_header, -1, PREG_SPLIT_NO_EMPTY); 707 708 if (!count($headers)) 709 $this->errors['tests'][$i]['header'] = $this->gettext('cannotbeempty'); 710 else { 711 foreach ($headers as $hr) 712 if (!preg_match('/^[a-z0-9-]+$/i', $hr)) 713 $this->errors['tests'][$i]['header'] = $this->gettext('forbiddenchars'); 714 } 715 716 if (empty($this->errors['tests'][$i]['header'])) 717 $cust_header = (is_array($headers) && count($headers) == 1) ? $headers[0] : $headers; 718 } 637 719 638 720 if ($type == 'exists') { 639 721 $this->form['tests'][$i]['test'] = 'exists'; 640 $this->form['tests'][$i]['arg'] = $header ;722 $this->form['tests'][$i]['arg'] = $header == '...' ? $cust_header : $header; 641 723 } 642 724 else { 725 $test = 'header'; 726 $header = $header == '...' ? $cust_header : $header; 727 728 if ($mod == 'address' || $mod == 'envelope') { 729 $found = false; 730 if (empty($this->errors['tests'][$i]['header'])) { 731 foreach ((array)$header as $hdr) { 732 if (!in_array(strtolower(trim($hdr)), $this->addr_headers)) 733 $found = true; 734 } 735 } 736 if (!$found) 737 $test = $mod; 738 } 739 643 740 $this->form['tests'][$i]['type'] = $type; 644 $this->form['tests'][$i]['test'] = 'header';741 $this->form['tests'][$i]['test'] = $test; 645 742 $this->form['tests'][$i]['arg1'] = $header; 646 743 $this->form['tests'][$i]['arg2'] = $target; … … 650 747 else if (preg_match('/^(value|count)-/', $type) && !preg_match('/[0-9]+/', $target)) 651 748 $this->errors['tests'][$i]['target'] = $this->gettext('forbiddenchars'); 749 750 if ($mod) { 751 $this->form['tests'][$i]['part'] = $mod_type; 752 } 652 753 } 653 754 } 654 else 655 switch ($header) { 656 case 'size': 657 $sizeop = $this->strip_value($sizeops[$idx]); 658 $sizeitem = $this->strip_value($items[$idx]); 659 $sizetarget = $this->strip_value($sizetargets[$idx]); 660 661 $this->form['tests'][$i]['test'] = 'size'; 662 $this->form['tests'][$i]['type'] = $sizeop; 663 $this->form['tests'][$i]['arg'] = $sizetarget.$sizeitem; 664 665 if ($sizetarget == '') 666 $this->errors['tests'][$i]['sizetarget'] = $this->gettext('cannotbeempty'); 667 else if (!preg_match('/^[0-9]+(K|M|G)*$/i', $sizetarget)) 668 $this->errors['tests'][$i]['sizetarget'] = $this->gettext('forbiddenchars'); 669 break; 670 case '...': 671 $cust_header = $headers = $this->strip_value($cust_headers[$idx]); 672 673 if (preg_match('/^not/', $op)) 674 $this->form['tests'][$i]['not'] = true; 675 $type = preg_replace('/^not/', '', $op); 676 677 if ($cust_header == '') 678 $this->errors['tests'][$i]['header'] = $this->gettext('cannotbeempty'); 679 else { 680 $headers = preg_split('/[\s,]+/', $cust_header, -1, PREG_SPLIT_NO_EMPTY); 681 682 if (!count($headers)) 683 $this->errors['tests'][$i]['header'] = $this->gettext('cannotbeempty'); 684 else { 685 foreach ($headers as $hr) 686 if (!preg_match('/^[a-z0-9-]+$/i', $hr)) 687 $this->errors['tests'][$i]['header'] = $this->gettext('forbiddenchars'); 688 } 689 } 690 691 if (empty($this->errors['tests'][$i]['header'])) 692 $cust_header = (is_array($headers) && count($headers) == 1) ? $headers[0] : $headers; 693 694 if ($type == 'exists') { 695 $this->form['tests'][$i]['test'] = 'exists'; 696 $this->form['tests'][$i]['arg'] = $cust_header; 697 } 698 else { 699 $this->form['tests'][$i]['test'] = 'header'; 700 $this->form['tests'][$i]['type'] = $type; 701 $this->form['tests'][$i]['arg1'] = $cust_header; 702 $this->form['tests'][$i]['arg2'] = $target; 703 704 if ($target == '') 705 $this->errors['tests'][$i]['target'] = $this->gettext('cannotbeempty'); 706 else if (preg_match('/^(value|count)-/', $type) && !preg_match('/[0-9]+/', $target)) 707 $this->errors['tests'][$i]['target'] = $this->gettext('forbiddenchars'); 708 } 709 break; 710 } 755 756 if ($header != 'size' && $comparator) { 757 if (preg_match('/^(value|count)/', $this->form['tests'][$i]['type'])) 758 $comparator = 'i;ascii-numeric'; 759 760 $this->form['tests'][$i]['comparator'] = $comparator; 761 } 762 711 763 $i++; 712 764 } … … 1141 1193 $rows_num = isset($this->form) ? sizeof($this->form['tests']) : sizeof($this->script[$fid]['tests']); 1142 1194 1143 $out = $div ? '<div class="rulerow" id="rulerow' .$id .'">'."\n" : '';1144 1145 $out .= '<table><tr><td class="rowactions">';1146 1147 1195 // headers select 1148 1196 $select_header = new html_select(array('name' => "_header[]", 'id' => 'header'.$id, … … 1150 1198 foreach($this->headers as $name => $val) 1151 1199 $select_header->add(Q($this->gettext($name)), Q($val)); 1200 if (in_array('body', $this->exts)) 1201 $select_header->add(Q($this->gettext('body')), 'body'); 1152 1202 $select_header->add(Q($this->gettext('size')), 'size'); 1153 1203 $select_header->add(Q($this->gettext('...')), '...'); 1154 1204 1155 1205 // TODO: list arguments 1156 1157 if ((isset($rule['test']) && $rule['test'] == 'header') 1158 && !is_array($rule['arg1']) && in_array($rule['arg1'], $this->headers)) 1159 $out .= $select_header->show($rule['arg1']); 1206 $aout = ''; 1207 1208 if ((isset($rule['test']) && in_array($rule['test'], array('header', 'address', 'envelope'))) 1209 && !is_array($rule['arg1']) && in_array($rule['arg1'], $this->headers) 1210 ) { 1211 $aout .= $select_header->show($rule['arg1']); 1212 } 1160 1213 else if ((isset($rule['test']) && $rule['test'] == 'exists') 1161 && !is_array($rule['arg']) && in_array($rule['arg'], $this->headers)) 1162 $out .= $select_header->show($rule['arg']); 1214 && !is_array($rule['arg']) && in_array($rule['arg'], $this->headers) 1215 ) { 1216 $aout .= $select_header->show($rule['arg']); 1217 } 1163 1218 else if (isset($rule['test']) && $rule['test'] == 'size') 1164 $out .= $select_header->show('size'); 1219 $aout .= $select_header->show('size'); 1220 else if (isset($rule['test']) && $rule['test'] == 'body') 1221 $aout .= $select_header->show('body'); 1165 1222 else if (isset($rule['test']) && $rule['test'] != 'true') 1166 $ out .= $select_header->show('...');1223 $aout .= $select_header->show('...'); 1167 1224 else 1168 $out .= $select_header->show(); 1169 1170 $out .= '</td><td class="rowtargets">'; 1171 1172 if ((isset($rule['test']) && $rule['test'] == 'header') 1173 && (is_array($rule['arg1']) || !in_array($rule['arg1'], $this->headers))) 1174 $custom = is_array($rule['arg1']) ? implode(', ', $rule['arg1']) : $rule['arg1']; 1175 else if ((isset($rule['test']) && $rule['test'] == 'exists') 1176 && (is_array($rule['arg']) || !in_array($rule['arg'], $this->headers))) 1177 $custom = is_array($rule['arg']) ? implode(', ', $rule['arg']) : $rule['arg']; 1178 1179 $out .= '<div id="custom_header' .$id. '" style="display:' .(isset($custom) ? 'inline' : 'none'). '"> 1225 $aout .= $select_header->show(); 1226 1227 if (isset($rule['test']) && in_array($rule['test'], array('header', 'address', 'envelope'))) { 1228 if (is_array($rule['arg1'])) 1229 $custom = implode(', ', $rule['arg1']); 1230 else if (!in_array($rule['arg1'], $this->headers)) 1231 $custom = $rule['arg1']; 1232 } 1233 else if (isset($rule['test']) && $rule['test'] == 'exists') { 1234 if (is_array($rule['arg'])) 1235 $custom = implode(', ', $rule['arg']); 1236 else if (!in_array($rule['arg'], $this->headers)) 1237 $custom = $rule['arg']; 1238 } 1239 1240 $tout = '<div id="custom_header' .$id. '" style="display:' .(isset($custom) ? 'inline' : 'none'). '"> 1180 1241 <input type="text" name="_custom_header[]" id="custom_header_i'.$id.'" ' 1181 1242 . $this->error_class($id, 'test', 'header', 'custom_header_i') … … 1216 1277 // target input (TODO: lists) 1217 1278 1218 if ( $rule['test'] == 'header') {1219 $ out .= $select_op->show(($rule['not'] ? 'not' : '').$rule['type']);1279 if (in_array($rule['test'], array('header', 'address', 'envelope'))) { 1280 $tout .= $select_op->show(($rule['not'] ? 'not' : '').$rule['type']); 1220 1281 $target = $rule['arg2']; 1221 1282 } 1222 1283 else if ($rule['test'] == 'size') { 1223 $ out .= $select_op->show();1224 if (preg_match('/^([0-9]+)(K|M|G) *$/', $rule['arg'], $matches)) {1284 $tout .= $select_op->show(); 1285 if (preg_match('/^([0-9]+)(K|M|G)?$/', $rule['arg'], $matches)) { 1225 1286 $sizetarget = $matches[1]; 1226 1287 $sizeitem = $matches[2]; 1227 1288 } 1289 else { 1290 $sizetarget = $rule['arg']; 1291 $sizeitem = $rule['item']; 1292 } 1228 1293 } 1229 1294 else { 1230 $ out .= $select_op->show(($rule['not'] ? 'not' : '').$rule['test']);1231 $target = '';1232 } 1233 1234 $ out .= '<input type="text" name="_rule_target[]" id="rule_target' .$id. '"1295 $tout .= $select_op->show(($rule['not'] ? 'not' : '').$rule['test']); 1296 $target = $rule['test'] == 'body' ? $rule['arg'] : ''; 1297 } 1298 1299 $tout .= '<input type="text" name="_rule_target[]" id="rule_target' .$id. '" 1235 1300 value="' .Q($target). '" size="20" ' . $this->error_class($id, 'test', 'target', 'rule_target') 1236 1301 . ' style="display:' . ($rule['test']!='size' && $rule['test'] != 'exists' ? 'inline' : 'none') . '" />'."\n"; 1237 1302 1238 1303 $select_size_op = new html_select(array('name' => "_rule_size_op[]", 'id' => 'rule_size_op'.$id)); 1304 $select_size_op->add(Q($this->gettext('filterover')), 'over'); 1239 1305 $select_size_op->add(Q($this->gettext('filterunder')), 'under'); 1240 $select_size_op->add(Q($this->gettext('filterover')), 'over'); 1241 1242 $out .= '<div id="rule_size' .$id. '" style="display:' . ($rule['test']=='size' ? 'inline' : 'none') .'">'; 1243 $out .= $select_size_op->show($rule['test']=='size' ? $rule['type'] : ''); 1244 $out .= '<input type="text" name="_rule_size_target[]" id="rule_size_i'.$id.'" value="'.$sizetarget.'" size="10" ' 1306 1307 $tout .= '<div id="rule_size' .$id. '" style="display:' . ($rule['test']=='size' ? 'inline' : 'none') .'">'; 1308 $tout .= $select_size_op->show($rule['test']=='size' ? $rule['type'] : ''); 1309 $tout .= '<input type="text" name="_rule_size_target[]" id="rule_size_i'.$id.'" value="'.$sizetarget.'" size="10" ' 1245 1310 . $this->error_class($id, 'test', 'sizetarget', 'rule_size_i') .' /> 1246 1311 <input type="radio" name="_rule_size_item['.$id.']" value=""' … … 1252 1317 <input type="radio" name="_rule_size_item['.$id.']" value="G"' 1253 1318 . ($sizeitem=='G' ? ' checked="checked"' : '') .' class="radio" />'.rcube_label('GB'); 1254 $out .= '</div>'; 1319 $tout .= '</div>'; 1320 1321 // Advanced modifiers (address, envelope) 1322 $select_mod = new html_select(array('name' => "_rule_mod[]", 'id' => 'rule_mod_op'.$id, 1323 'onchange' => 'rule_mod_select(' .$id .')')); 1324 $select_mod->add(Q($this->gettext('none')), ''); 1325 $select_mod->add(Q($this->gettext('address')), 'address'); 1326 if (in_array('envelope', $this->exts)) 1327 $select_mod->add(Q($this->gettext('envelope')), 'envelope'); 1328 1329 $select_type = new html_select(array('name' => "_rule_mod_type[]", 'id' => 'rule_mod_type'.$id)); 1330 $select_type->add(Q($this->gettext('allparts')), 'all'); 1331 $select_type->add(Q($this->gettext('domain')), 'domain'); 1332 $select_type->add(Q($this->gettext('localpart')), 'localpart'); 1333 if (in_array('subaddress', $this->exts)) { 1334 $select_type->add(Q($this->gettext('user')), 'user'); 1335 $select_type->add(Q($this->gettext('detail')), 'detail'); 1336 } 1337 1338 $need_mod = $rule['test'] != 'size' && $rule['test'] != 'body'; 1339 $mout = '<div id="rule_mod' .$id. '" class="adv" style="display:' . ($need_mod ? 'block' : 'none') .'">'; 1340 $mout .= ' <span>'; 1341 $mout .= Q($this->gettext('modifier')) . ' '; 1342 $mout .= $select_mod->show($rule['test']); 1343 $mout .= '</span>'; 1344 $mout .= ' <span id="rule_mod_type' . $id . '"'; 1345 $mout .= ' style="display:' . (in_array($rule['test'], array('address', 'envelope')) ? 'inline' : 'none') .'">'; 1346 $mout .= Q($this->gettext('modtype')) . ' '; 1347 $mout .= $select_type->show($rule['part']); 1348 $mout .= '</span>'; 1349 $mout .= '</div>'; 1350 1351 // Advanced modifiers (body transformations) 1352 $select_mod = new html_select(array('name' => "_rule_trans[]", 'id' => 'rule_trans_op'.$id, 1353 'onchange' => 'rule_trans_select(' .$id .')')); 1354 $select_mod->add(Q($this->gettext('text')), 'text'); 1355 $select_mod->add(Q($this->gettext('undecoded')), 'raw'); 1356 $select_mod->add(Q($this->gettext('contenttype')), 'content'); 1357 1358 $mout .= '<div id="rule_trans' .$id. '" class="adv" style="display:' . ($rule['test'] == 'body' ? 'block' : 'none') .'">'; 1359 $mout .= ' <span>'; 1360 $mout .= Q($this->gettext('modifier')) . ' '; 1361 $mout .= $select_mod->show($rule['part']); 1362 $mout .= '<input type="text" name="_rule_trans_type[]" id="rule_trans_type'.$id 1363 . '" value="'.(is_array($rule['content']) ? implode(',', $rule['content']) : $rule['content']) 1364 .'" size="20" style="display:' . ($rule['part'] == 'content' ? 'inline' : 'none') .'"' 1365 . $this->error_class($id, 'test', 'part', 'rule_trans_type') .' />'; 1366 $mout .= '</span>'; 1367 $mout .= '</div>'; 1368 1369 // Advanced modifiers (body transformations) 1370 $select_comp = new html_select(array('name' => "_rule_comp[]", 'id' => 'rule_comp_op'.$id)); 1371 $select_comp->add(Q($this->gettext('default')), ''); 1372 $select_comp->add(Q($this->gettext('octet')), 'i;octet'); 1373 $select_comp->add(Q($this->gettext('asciicasemap')), 'i;ascii-casemap'); 1374 if (in_array('comparator-i;ascii-numeric', $this->exts)) { 1375 $select_comp->add(Q($this->gettext('asciinumeric')), 'i;ascii-numeric'); 1376 } 1377 1378 $mout .= '<div id="rule_comp' .$id. '" class="adv" style="display:' . ($rule['test'] != 'size' ? 'block' : 'none') .'">'; 1379 $mout .= ' <span>'; 1380 $mout .= Q($this->gettext('comparator')) . ' '; 1381 $mout .= $select_comp->show($rule['comparator']); 1382 $mout .= '</span>'; 1383 $mout .= '</div>'; 1384 1385 // Build output table 1386 $out = $div ? '<div class="rulerow" id="rulerow' .$id .'">'."\n" : ''; 1387 $out .= '<table><tr>'; 1388 $out .= '<td class="advbutton">'; 1389 $out .= '<a href="#" id="ruleadv' . $id .'" title="'. Q($this->gettext('advancedopts')). '" 1390 onclick="rule_adv_switch(' . $id .', this)" class="show"> </a>'; 1391 $out .= '</td>'; 1392 $out .= '<td class="rowactions">' . $aout . '</td>'; 1393 $out .= '<td class="rowtargets">' . $tout . "\n"; 1394 $out .= '<div id="rule_advanced' .$id. '" style="display:none">' . $mout . '</div>'; 1255 1395 $out .= '</td>'; 1256 1396 … … 1261 1401 $out .= '<a href="#" id="ruledel' . $id .'" title="'. Q($this->gettext('del')). '" 1262 1402 onclick="rcmail.managesieve_ruledel(' . $id .')" class="button del' . ($rows_num<2 ? ' disabled' : '') .'"></a>'; 1263 $out .= '</td></tr></table>'; 1403 $out .= '</td>'; 1404 $out .= '</tr></table>'; 1264 1405 1265 1406 $out .= $div ? "</div>\n" : ''; -
trunk/plugins/managesieve/skins/default/managesieve.css
r5340 r5441 150 150 } 151 151 152 td 153 { 154 vertical-align: top; 155 } 156 157 td.advbutton 158 { 159 width: 1%; 160 } 161 162 td.advbutton a 163 { 164 display: block; 165 padding-top: 14px; 166 height: 6px; 167 width: 12px; 168 text-decoration: none; 169 } 170 171 td.advbutton a.show 172 { 173 background: url(images/down_small.gif) center no-repeat; 174 } 175 176 td.advbutton a.hide 177 { 178 background: url(images/up_small.gif) center no-repeat; 179 } 180 152 181 td.rowbuttons 153 182 { … … 170 199 } 171 200 201 td.rowtargets div.adv 202 { 203 padding-top: 3px; 204 } 205 172 206 input.disabled, input.disabled:hover 173 207 { … … 184 218 { 185 219 border: 0; 220 margin-top: 0; 186 221 } 187 222 … … 191 226 } 192 227 228 td.rowtargets span, 193 229 span.label 194 230 { … … 244 280 width: 30px; 245 281 height: 20px; 246 margin-right: 4px; 282 margin-right: 4px; 247 283 display: inline-block; 248 284 } -
trunk/plugins/managesieve/tests/parser.phpt
r5440 r5441 7 7 8 8 $txt = ' 9 require ["fileinto","reject" ];9 require ["fileinto","reject","envelope"]; 10 10 # rule:[spam] 11 11 if anyof (header :contains "X-DSPAM-Result" "Spam") … … 15 15 } 16 16 # rule:[test1] 17 if anyof (header :co ntains ["From","To"] "test@domain.tld")17 if anyof (header :comparator "i;ascii-casemap" :contains ["From","To"] "test@domain.tld") 18 18 { 19 19 discard; … … 21 21 } 22 22 # rule:[test2] 23 if anyof (not header :co ntains ["Subject"] "[test]", header :contains "Subject" "[test2]")23 if anyof (not header :comparator "i;octet" :contains ["Subject"] "[test]", header :contains "Subject" "[test2]") 24 24 { 25 25 fileinto "test"; … … 47 47 } 48 48 fileinto "Test"; 49 # rule:[address test] 50 if address :all :is "From" "nagios@domain.tld" 51 { 52 fileinto "domain.tld"; 53 stop; 54 } 55 # rule:[envelope test] 56 if envelope :domain :is "From" "domain.tld" 57 { 58 fileinto "domain.tld"; 59 stop; 60 } 49 61 '; 50 62 … … 52 64 echo $s->as_text(); 53 65 66 // ------------------------------------------------------------------------------- 54 67 ?> 55 68 --EXPECT-- 56 require ["fileinto","reject" ];69 require ["fileinto","reject","envelope"]; 57 70 # rule:[spam] 58 71 if header :contains "X-DSPAM-Result" "Spam" … … 68 81 } 69 82 # rule:[test2] 70 if anyof (not header :co ntains "Subject" "[test]", header :contains "Subject" "[test2]")83 if anyof (not header :comparator "i;octet" :contains "Subject" "[test]", header :contains "Subject" "[test2]") 71 84 { 72 85 fileinto "test"; … … 94 107 } 95 108 fileinto "Test"; 109 # rule:[address test] 110 if address :all :is "From" "nagios@domain.tld" 111 { 112 fileinto "domain.tld"; 113 stop; 114 } 115 # rule:[envelope test] 116 if envelope :domain :is "From" "domain.tld" 117 { 118 fileinto "domain.tld"; 119 stop; 120 } -
trunk/plugins/managesieve/tests/parser_imapflags.phpt
r5437 r5441 15 15 '; 16 16 17 $s = new rcube_sieve_script($txt );17 $s = new rcube_sieve_script($txt, array('imapflags')); 18 18 echo $s->as_text(); 19 19 -
trunk/plugins/managesieve/tests/parser_kep14.phpt
r5340 r5441 11 11 '; 12 12 13 $s = new rcube_sieve_script($txt, array( ));13 $s = new rcube_sieve_script($txt, array('body')); 14 14 echo $s->as_text(); 15 15
Note: See TracChangeset
for help on using the changeset viewer.
