diff --git a/CHANGELOG b/CHANGELOG index beb87c82d..7a51eefce 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ CHANGELOG Roundcube Webmail =========================== +- Managesieve: Added support for 'editheader' extension - RFC5293 (#5954) - Password: Added 'modoboa' driver (#6361) - Plugin API: Added 'raise_error' hook (#6199) - Fix so invalid smtp_helo_host is never used, fallback to localhost (#6408) diff --git a/plugins/managesieve/Changelog b/plugins/managesieve/Changelog index 266771c69..ee94ca07c 100644 --- a/plugins/managesieve/Changelog +++ b/plugins/managesieve/Changelog @@ -1,3 +1,4 @@ +- Added support for 'editheader' extension - RFC5293 (#5954) - Fix bug where show_real_foldernames setting wasn't respected (#6422) * version 9.1 [2018-05-19] diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve.php b/plugins/managesieve/lib/Roundcube/rcube_sieve.php index 6c751696a..fb610e8da 100644 --- a/plugins/managesieve/lib/Roundcube/rcube_sieve.php +++ b/plugins/managesieve/lib/Roundcube/rcube_sieve.php @@ -313,14 +313,10 @@ class rcube_sieve if ($this->script) { $supported = $this->script->get_extensions(); - foreach ($ext as $idx => $ext_name) { - if (!in_array($ext_name, $supported)) { - unset($ext[$idx]); - } - } + $ext = array_values(array_intersect($ext, $supported)); } - return array_values($ext); + return $ext; } /** diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php b/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php index 8ef58f65d..929701f89 100644 --- a/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php +++ b/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php @@ -688,6 +688,15 @@ class rcube_sieve_engine $notifymessages = rcube_utils::get_input_value('_action_notifymessage', rcube_utils::INPUT_POST, true); $notifyfrom = rcube_utils::get_input_value('_action_notifyfrom', rcube_utils::INPUT_POST); $notifyimp = rcube_utils::get_input_value('_action_notifyimportance', rcube_utils::INPUT_POST); + $addheader_name = rcube_utils::get_input_value('_action_addheader_name', rcube_utils::INPUT_POST); + $addheader_value = rcube_utils::get_input_value('_action_addheader_value', rcube_utils::INPUT_POST, true); + $addheader_pos = rcube_utils::get_input_value('_action_addheader_pos', rcube_utils::INPUT_POST); + $delheader_name = rcube_utils::get_input_value('_action_delheader_name', rcube_utils::INPUT_POST); + $delheader_value = rcube_utils::get_input_value('_action_delheader_value', rcube_utils::INPUT_POST, true); + $delheader_pos = rcube_utils::get_input_value('_action_delheader_pos', rcube_utils::INPUT_POST); + $delheader_index = rcube_utils::get_input_value('_action_delheader_index', rcube_utils::INPUT_POST); + $delheader_op = rcube_utils::get_input_value('_action_delheader_op', rcube_utils::INPUT_POST); + $delheader_comp = rcube_utils::get_input_value('_action_delheader_comp', rcube_utils::INPUT_POST); // we need a "hack" for radiobuttons foreach ($sizeitems as $item) @@ -1091,6 +1100,42 @@ class rcube_sieve_engine $this->form['actions'][$i]['target'] = $_target; break; + case 'addheader': + case 'deleteheader': + $this->form['actions'][$i]['name'] = trim($type == 'addheader' ? $addheader_name[$idx] : $delheader_name[$idx]); + $this->form['actions'][$i]['value'] = $type == 'addheader' ? $addheader_value[$idx] : $delheader_value[$idx]; + $this->form['actions'][$i]['last'] = ($type == 'addheader' ? $addheader_pos[$idx] : $delheader_pos[$idx]) == 'last'; + + if (empty($this->form['actions'][$i]['name'])) { + $this->errors['actions'][$i]['name'] = $this->plugin->gettext('cannotbeempty'); + } + else if (!preg_match('/^[0-9a-z_-]+$/i', $this->form['actions'][$i]['name'])) { + $this->errors['actions'][$i]['name'] = $this->plugin->gettext('forbiddenchars'); + } + + if ($type == 'deleteheader') { + foreach ((array) $this->form['actions'][$i]['value'] as $pidx => $pattern) { + if (empty($pattern)) { + unset($this->form['actions'][$i]['value'][$pidx]); + } + } + + $this->form['actions'][$i]['match-type'] = $delheader_op[$idx]; + $this->form['actions'][$i]['comparator'] = $delheader_comp[$idx]; + $this->form['actions'][$i]['index'] = $delheader_index[$idx]; + + if (!preg_match('/^[0-9]+$/i', $this->form['actions'][$i]['index'])) { + $this->errors['actions'][$i]['index'] = $this->plugin->gettext('forbiddenchars'); + } + } + else { + if (empty($this->form['actions'][$i]['value'])) { + $this->errors['actions'][$i]['value'] = $this->plugin->gettext('cannotbeempty'); + } + } + + break; + case 'vacation': $reason = $this->strip_value($reasons[$idx]); $interval_type = $interval_types[$idx] == 'seconds' ? 'seconds' : 'days'; @@ -1714,38 +1759,6 @@ class rcube_sieve_engine $aout .= $this->list_input($id, 'custom_var', $customv, isset($customv), $this->error_class($id, 'test', 'header', 'custom_var'), 15) . "\n"; - // matching type select (operator) - $select_op = new html_select(array('name' => "_rule_op[]", 'id' => 'rule_op'.$id, - 'style' => 'display:' .(!in_array($rule['test'], array('size', 'duplicate')) ? 'inline' : 'none'), - 'class' => 'operator_selector', - 'onchange' => 'rule_op_select(this, '.$id.')')); - $select_op->add(rcube::Q($this->plugin->gettext('filtercontains')), 'contains'); - $select_op->add(rcube::Q($this->plugin->gettext('filternotcontains')), 'notcontains'); - $select_op->add(rcube::Q($this->plugin->gettext('filteris')), 'is'); - $select_op->add(rcube::Q($this->plugin->gettext('filterisnot')), 'notis'); - $select_op->add(rcube::Q($this->plugin->gettext('filterexists')), 'exists'); - $select_op->add(rcube::Q($this->plugin->gettext('filternotexists')), 'notexists'); - $select_op->add(rcube::Q($this->plugin->gettext('filtermatches')), 'matches'); - $select_op->add(rcube::Q($this->plugin->gettext('filternotmatches')), 'notmatches'); - if (in_array('regex', $this->exts)) { - $select_op->add(rcube::Q($this->plugin->gettext('filterregex')), 'regex'); - $select_op->add(rcube::Q($this->plugin->gettext('filternotregex')), 'notregex'); - } - if (in_array('relational', $this->exts)) { - $select_op->add(rcube::Q($this->plugin->gettext('countisgreaterthan')), 'count-gt'); - $select_op->add(rcube::Q($this->plugin->gettext('countisgreaterthanequal')), 'count-ge'); - $select_op->add(rcube::Q($this->plugin->gettext('countislessthan')), 'count-lt'); - $select_op->add(rcube::Q($this->plugin->gettext('countislessthanequal')), 'count-le'); - $select_op->add(rcube::Q($this->plugin->gettext('countequals')), 'count-eq'); - $select_op->add(rcube::Q($this->plugin->gettext('countnotequals')), 'count-ne'); - $select_op->add(rcube::Q($this->plugin->gettext('valueisgreaterthan')), 'value-gt'); - $select_op->add(rcube::Q($this->plugin->gettext('valueisgreaterthanequal')), 'value-ge'); - $select_op->add(rcube::Q($this->plugin->gettext('valueislessthan')), 'value-lt'); - $select_op->add(rcube::Q($this->plugin->gettext('valueislessthanequal')), 'value-le'); - $select_op->add(rcube::Q($this->plugin->gettext('valueequals')), 'value-eq'); - $select_op->add(rcube::Q($this->plugin->gettext('valuenotequals')), 'value-ne'); - } - $test = self::rule_test($rule); $target = ''; @@ -1796,7 +1809,7 @@ class rcube_sieve_engine $tout .= $select_msg->show($test); } - $tout .= $select_op->show($test); + $tout .= $this->match_type_selector('rule_op', $id, $test, $rule['test']); $tout .= $this->list_input($id, 'rule_target', $target, $rule['test'] != 'size' && $rule['test'] != 'exists' && $rule['test'] != 'duplicate', $this->error_class($id, 'test', 'target', 'rule_target')) . "\n"; @@ -1854,18 +1867,10 @@ class rcube_sieve_engine $mout .= ''; // Advanced modifiers (comparators) - $select_comp = new html_select(array('name' => "_rule_comp[]", 'id' => 'rule_comp_op'.$id)); - $select_comp->add(rcube::Q($this->plugin->gettext('default')), ''); - $select_comp->add(rcube::Q($this->plugin->gettext('octet')), 'i;octet'); - $select_comp->add(rcube::Q($this->plugin->gettext('asciicasemap')), 'i;ascii-casemap'); - if (in_array('comparator-i;ascii-numeric', $this->exts)) { - $select_comp->add(rcube::Q($this->plugin->gettext('asciinumeric')), 'i;ascii-numeric'); - } - $need_comp = $rule['test'] != 'size' && $rule['test'] != 'duplicate'; $mout .= '
'; // Advanced modifiers (mime) @@ -2096,32 +2101,36 @@ class rcube_sieve_engine $select_action = new html_select(array('name' => "_action_type[$id]", 'id' => 'action_type'.$id, 'onchange' => 'action_type_select(' .$id .')')); if (in_array('fileinto', $this->exts)) - $select_action->add(rcube::Q($this->plugin->gettext('messagemoveto')), 'fileinto'); + $select_action->add($this->plugin->gettext('messagemoveto'), 'fileinto'); if (in_array('fileinto', $this->exts) && in_array('copy', $this->exts)) - $select_action->add(rcube::Q($this->plugin->gettext('messagecopyto')), 'fileinto_copy'); - $select_action->add(rcube::Q($this->plugin->gettext('messageredirect')), 'redirect'); + $select_action->add($this->plugin->gettext('messagecopyto'), 'fileinto_copy'); + $select_action->add($this->plugin->gettext('messageredirect'), 'redirect'); if (in_array('copy', $this->exts)) - $select_action->add(rcube::Q($this->plugin->gettext('messagesendcopy')), 'redirect_copy'); + $select_action->add($this->plugin->gettext('messagesendcopy'), 'redirect_copy'); if (in_array('reject', $this->exts)) - $select_action->add(rcube::Q($this->plugin->gettext('messagediscard')), 'reject'); + $select_action->add($this->plugin->gettext('messagediscard'), 'reject'); else if (in_array('ereject', $this->exts)) - $select_action->add(rcube::Q($this->plugin->gettext('messagediscard')), 'ereject'); + $select_action->add($this->plugin->gettext('messagediscard'), 'ereject'); if (in_array('vacation', $this->exts)) - $select_action->add(rcube::Q($this->plugin->gettext('messagereply')), 'vacation'); - $select_action->add(rcube::Q($this->plugin->gettext('messagedelete')), 'discard'); + $select_action->add($this->plugin->gettext('messagereply'), 'vacation'); + $select_action->add($this->plugin->gettext('messagedelete'), 'discard'); if (in_array('imapflags', $this->exts) || in_array('imap4flags', $this->exts)) { - $select_action->add(rcube::Q($this->plugin->gettext('setflags')), 'setflag'); - $select_action->add(rcube::Q($this->plugin->gettext('addflags')), 'addflag'); - $select_action->add(rcube::Q($this->plugin->gettext('removeflags')), 'removeflag'); + $select_action->add($this->plugin->gettext('setflags'), 'setflag'); + $select_action->add($this->plugin->gettext('addflags'), 'addflag'); + $select_action->add($this->plugin->gettext('removeflags'), 'removeflag'); + } + if (in_array('editheader', $this->exts)) { + $select_action->add($this->plugin->gettext('addheader'), 'addheader'); + $select_action->add($this->plugin->gettext('deleteheader'), 'deleteheader'); } if (in_array('variables', $this->exts)) { - $select_action->add(rcube::Q($this->plugin->gettext('setvariable')), 'set'); + $select_action->add($this->plugin->gettext('setvariable'), 'set'); } if (in_array('enotify', $this->exts) || in_array('notify', $this->exts)) { - $select_action->add(rcube::Q($this->plugin->gettext('notify')), 'notify'); + $select_action->add($this->plugin->gettext('notify'), 'notify'); } - $select_action->add(rcube::Q($this->plugin->gettext('messagekeep')), 'keep'); - $select_action->add(rcube::Q($this->plugin->gettext('rulestop')), 'stop'); + $select_action->add($this->plugin->gettext('messagekeep'), 'keep'); + $select_action->add($this->plugin->gettext('rulestop'), 'stop'); $select_type = $action['type']; if (in_array($action['type'], array('fileinto', 'redirect')) && $action['copy']) { @@ -2190,7 +2199,7 @@ class rcube_sieve_engine } } - $out .= '