diff options
| -rw-r--r-- | plugins/managesieve/Changelog | 1 | ||||
| -rw-r--r-- | plugins/managesieve/config.inc.php.dist | 3 | ||||
| -rw-r--r-- | plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php | 122 | ||||
| -rw-r--r-- | plugins/managesieve/lib/Roundcube/rcube_sieve_script.php | 66 | ||||
| -rw-r--r-- | plugins/managesieve/localization/en_US.inc | 11 | ||||
| -rw-r--r-- | plugins/managesieve/tests/src/parser_notify_a | 2 | ||||
| -rw-r--r-- | plugins/managesieve/tests/src/parser_notify_b | 2 | 
7 files changed, 122 insertions, 85 deletions
| diff --git a/plugins/managesieve/Changelog b/plugins/managesieve/Changelog index 00aaf53bf..29b359d7f 100644 --- a/plugins/managesieve/Changelog +++ b/plugins/managesieve/Changelog @@ -1,5 +1,6 @@  - Added optional separate interface for out-of-office management (#1488266)  - Fix disabled "create filter" action +- Fix enotify/notify extension handling  * version 7.2 [2014-02-14]  ----------------------------------------------------------- diff --git a/plugins/managesieve/config.inc.php.dist b/plugins/managesieve/config.inc.php.dist index 316eddd4f..14123c110 100644 --- a/plugins/managesieve/config.inc.php.dist +++ b/plugins/managesieve/config.inc.php.dist @@ -74,4 +74,5 @@ $config['managesieve_domains'] = array();  // 2 - add Vacation section, but hide Filters section  $config['managesieve_vacation'] = 0; -?> +// Supported methods of notify extension. Default: 'mailto' +$config['managesieve_notify_methods'] = array('mailto'); diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php b/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php index 4b57f760d..9900f16b5 100644 --- a/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php +++ b/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php @@ -52,6 +52,16 @@ class rcube_sieve_engine          // Undocumented          "x-beenthere",      ); +    protected $notify_methods = array( +        'mailto', +        // 'sms', +        // 'tel', +    ); +    protected $notify_importance_options = array( +        3 => 'notifyimportancelow', +        2 => 'notifyimportancenormal', +        1 => 'notifyimportancehigh' +    );      const VERSION  = '8.0';      const PROGNAME = 'Roundcube (Managesieve)'; @@ -558,9 +568,10 @@ class rcube_sieve_engine              $varnames       = rcube_utils::get_input_value('_action_varname', rcube_utils::INPUT_POST);              $varvalues      = rcube_utils::get_input_value('_action_varvalue', rcube_utils::INPUT_POST);              $varmods        = rcube_utils::get_input_value('_action_varmods', rcube_utils::INPUT_POST); -            $notifyaddrs    = rcube_utils::get_input_value('_action_notifyaddress', rcube_utils::INPUT_POST); -            $notifybodies   = rcube_utils::get_input_value('_action_notifybody', rcube_utils::INPUT_POST); -            $notifymessages = rcube_utils::get_input_value('_action_notifymessage', rcube_utils::INPUT_POST); +            $notifymethods  = rcube_utils::get_input_value('_action_notifymethod', rcube_utils::INPUT_POST); +            $notifytargets  = rcube_utils::get_input_value('_action_notifytarget', rcube_utils::INPUT_POST, true); +            $notifyoptions  = rcube_utils::get_input_value('_action_notifyoption', rcube_utils::INPUT_POST, true); +            $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); @@ -960,19 +971,27 @@ class rcube_sieve_engine                      break;                  case 'notify': -                    if (empty($notifyaddrs[$idx])) { -                        $this->errors['actions'][$i]['address'] = $this->plugin->gettext('cannotbeempty'); +                    if (empty($notifymethods[$idx])) { +                        $this->errors['actions'][$i]['method'] = $this->plugin->gettext('cannotbeempty');                      } -                    else if (!rcube_utils::check_email($notifyaddrs[$idx])) { -                        $this->errors['actions'][$i]['address'] = $this->plugin->gettext('noemailwarning'); +                    if (empty($notifytargets[$idx])) { +                        $this->errors['actions'][$i]['target'] = $this->plugin->gettext('cannotbeempty');                      }                      if (!empty($notifyfrom[$idx]) && !rcube_utils::check_email($notifyfrom[$idx])) {                          $this->errors['actions'][$i]['from'] = $this->plugin->gettext('noemailwarning');                      } -                    $this->form['actions'][$i]['address'] = $notifyaddrs[$idx]; -                    $this->form['actions'][$i]['body'] = $notifybodies[$idx]; -                    $this->form['actions'][$i]['message'] = $notifymessages[$idx]; -                    $this->form['actions'][$i]['from'] = $notifyfrom[$idx]; + +                    // skip empty options +                    foreach ((array)$notifyoptions[$idx] as $opt_idx => $opt) { +                        if (!strlen(trim($opt))) { +                            unset($notifyoptions[$idx][$opt_idx]); +                        } +                    } + +                    $this->form['actions'][$i]['method']     = $notifymethods[$idx] . ':' . $notifytargets[$idx]; +                    $this->form['actions'][$i]['options']    = $notifyoptions[$idx]; +                    $this->form['actions'][$i]['message']    = $notifymessages[$idx]; +                    $this->form['actions'][$i]['from']       = $notifyfrom[$idx];                      $this->form['actions'][$i]['importance'] = $notifyimp[$idx];                      break;                  } @@ -986,8 +1005,10 @@ class rcube_sieve_engine                  if (!isset($this->script[$fid])) {                      $fid = $this->sieve->script->add_rule($this->form);                      $new = true; -                } else +                } +                else {                      $fid = $this->sieve->script->update_rule($fid, $this->form); +                }                  if ($fid !== false)                      $save = $this->save_script(); @@ -1747,38 +1768,61 @@ class rcube_sieve_engine          $out .= '</div>';          // notify -        // skip :options tag - not used by the mailto method -        $out .= '<div id="action_notify' .$id.'" style="display:' .($action['type']=='notify' ? 'inline' : 'none') .'">'; -        $out .= '<span class="label">' .rcube::Q($this->plugin->gettext('notifyaddress')) . '</span><br />' -            .'<input type="text" name="_action_notifyaddress['.$id.']" id="action_notifyaddress'.$id.'" ' -            .'value="' . rcube::Q($action['address']) . '" size="35" ' -            . $this->error_class($id, 'action', 'address', 'action_notifyaddress') .' />'; -        $out .= '<br /><span class="label">'. rcube::Q($this->plugin->gettext('notifybody')) .'</span><br />' -            .'<textarea name="_action_notifybody['.$id.']" id="action_notifybody' .$id. '" ' -            .'rows="3" cols="35" '. $this->error_class($id, 'action', 'method', 'action_notifybody') . '>' -            . rcube::Q($action['body'], 'strict', false) . "</textarea>\n"; -        $out .= '<br /><span class="label">' .rcube::Q($this->plugin->gettext('notifysubject')) . '</span><br />' -            .'<input type="text" name="_action_notifymessage['.$id.']" id="action_notifymessage'.$id.'" ' -            .'value="' . rcube::Q($action['message']) . '" size="35" ' -            . $this->error_class($id, 'action', 'message', 'action_notifymessage') .' />'; -        $out .= '<br /><span class="label">' .rcube::Q($this->plugin->gettext('notifyfrom')) . '</span><br />' -            .'<input type="text" name="_action_notifyfrom['.$id.']" id="action_notifyfrom'.$id.'" ' -            .'value="' . rcube::Q($action['from']) . '" size="35" ' -            . $this->error_class($id, 'action', 'from', 'action_notifyfrom') .' />'; -        $importance_options = array( -            3 => 'notifyimportancelow', -            2 => 'notifyimportancenormal', -            1 => 'notifyimportancehigh' -        ); +        $notify_methods     = (array) $this->rc->config->get('managesieve_notify_methods'); +        $importance_options = $this->notify_importance_options; + +        if (empty($notify_methods)) { +            $notify_methods = $this->notify_methods; +        } + +        list($method, $target) = explode(':', $action['method'], 2); +        $method = strtolower($method); + +        if ($method && !in_array($method, $notify_methods)) { +            $notify_methods[] = $method; +        } + +        $select_method = new html_select(array( +            'name'  => "_action_notifymethod[$id]", +            'id'    => "_action_notifymethod$id", +            'class' => $this->error_class($id, 'action', 'method', 'action_notifymethod'), +        )); +        foreach ($notify_methods as $m_n) { +            $select_method->add(rcube::Q($this->rc->text_exists('managesieve.notifymethod'.$m_n) ? $this->plugin->gettext('managesieve.notifymethod'.$m_n) : $m_n), $m_n); +        } +          $select_importance = new html_select(array( -            'name' => '_action_notifyimportance[' . $id . ']', -            'id' => '_action_notifyimportance' . $id, -            'class' => $this->error_class($id, 'action', 'importance', 'action_notifyimportance'))); +            'name'  => "_action_notifyimportance[$id]", +            'id'    => "_action_notifyimportance$id", +            'class' => $this->error_class($id, 'action', 'importance', 'action_notifyimportance') +        ));          foreach ($importance_options as $io_v => $io_n) {              $select_importance->add(rcube::Q($this->plugin->gettext($io_n)), $io_v);          } + +        // @TODO: nice UI for mailto: (other methods too) URI parameters +        $out .= '<div id="action_notify' .$id.'" style="display:' .($action['type'] == 'notify' ? 'inline' : 'none') .'">'; +        $out .= '<span class="label">' .rcube::Q($this->plugin->gettext('notifytarget')) . '</span><br />' +            . $select_method->show($method) +            .'<input type="text" name="_action_notifytarget['.$id.']" id="action_notifytarget'.$id.'" ' +            .'value="' . rcube::Q($target) . '" size="25" ' +            . $this->error_class($id, 'action', 'target', 'action_notifytarget') .' />'; +        $out .= '<br /><span class="label">'. rcube::Q($this->plugin->gettext('notifymessage')) .'</span><br />' +            .'<textarea name="_action_notifymessage['.$id.']" id="action_notifymessage' .$id. '" ' +            .'rows="3" cols="35" '. $this->error_class($id, 'action', 'message', 'action_notifymessage') . '>' +            . rcube::Q($action['message'], 'strict', false) . "</textarea>\n"; +        if (in_array('enotify', $this->exts)) { +            $out .= '<br /><span class="label">' .rcube::Q($this->plugin->gettext('notifyfrom')) . '</span><br />' +                .'<input type="text" name="_action_notifyfrom['.$id.']" id="action_notifyfrom'.$id.'" ' +                .'value="' . rcube::Q($action['from']) . '" size="35" ' +                . $this->error_class($id, 'action', 'from', 'action_notifyfrom') .' />'; +        }          $out .= '<br /><span class="label">' . rcube::Q($this->plugin->gettext('notifyimportance')) . '</span><br />'; -        $out .= $select_importance->show($action['importance'] ? $action['importance'] : 2); +        $out .= $select_importance->show($action['importance'] ? (int) $action['importance'] : 2); +        $out .= '<div id="action_notifyoption_div' . $id  . '">' +            .'<span class="label">' . rcube::Q($this->plugin->gettext('notifyoptions')) . '</span><br />' +            .$this->list_input($id, 'action_notifyoption', (array)$action['options'], true, +                $this->error_class($id, 'action', 'options', 'action_notifyoption'), 30) . '</div>';          $out .= '</div>';          // mailbox select diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php b/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php index c6ad78add..bc62d2ff4 100644 --- a/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php +++ b/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php @@ -38,7 +38,7 @@ class rcube_sieve_script          'imap4flags',               // RFC5232          'include',                  // draft-ietf-sieve-include-12          'index',                    // RFC5260 -        'notify',                   // draft-ietf-sieve-notify-00 +        'notify',                   // draft-martin-sieve-notify-01,          'regex',                    // draft-ietf-sieve-regex-01          'reject',                   // RFC5429          'relational',               // RFC3431 @@ -411,38 +411,38 @@ class rcube_sieve_script                          array_push($exts, $notify);                          $action_script .= 'notify'; -                        // Here we support only 00 version of notify draft, there -                        // were a couple regressions in 00 to 04 changelog, we use -                        // the version used by Cyrus +                        $method = $action['method']; +                        unset($action['method']); +                        $action['options'] = (array) $action['options']; + +                        // Here we support draft-martin-sieve-notify-01 used by Cyrus                          if ($notify == 'notify') {                              switch ($action['importance']) {                                  case 1: $action_script .= " :high"; break; -                                case 2: $action_script .= " :normal"; break; +                                //case 2: $action_script .= " :normal"; break;                                  case 3: $action_script .= " :low"; break; +                            } +                            // Old-draft way: :method "mailto" :options "email@address" +                            if (!empty($method)) { +                                $parts = explode(':', $method, 2); +                                $action['method'] = $parts[0]; +                                array_unshift($action['options'], $parts[1]);                              } +                              unset($action['importance']); +                            unset($action['from']); +                            unset($method);                          } -                        foreach (array('from', 'importance', 'options', 'message') as $n_tag) { +                        foreach (array('id', 'importance', 'method', 'options', 'from', 'message') as $n_tag) {                              if (!empty($action[$n_tag])) {                                  $action_script .= " :$n_tag " . self::escape_string($action[$n_tag]);                              }                          } -                        if (!empty($action['address'])) { -                            $method = 'mailto:' . $action['address']; -                            if (!empty($action['body'])) { -                                $method .= '?body=' . rawurlencode($action['body']); -                            } -                        } -                        else { -                            $method = $action['method']; -                        } - -                        // method is optional in notify extension                          if (!empty($method)) { -                            $action_script .= ($notify == 'notify' ? " :method " : " ") . self::escape_string($method); +                            $action_script .= ' ' . self::escape_string($method);                          }                          break; @@ -849,13 +849,11 @@ class rcube_sieve_script              case 'notify':                  $action     = array('type' => 'notify');                  $priorities = array('high' => 1, 'normal' => 2, 'low' => 3); -                $vargs      = array('from', 'importance', 'options', 'message', 'method'); +                $vargs      = array('from', 'id', 'importance', 'options', 'message', 'method');                  $args       = array_keys($priorities);                  $action    += $this->action_arguments($tokens, $args, $vargs); -                // Here we support only 00 version of notify draft, there -                // were a couple regressions in 00 to 04 changelog, we use -                // the version used by Cyrus +                // Here we'll convert draft-martin-sieve-notify-01 into RFC 5435                  if (!isset($action['importance'])) {                      foreach ($priorities as $key => $val) {                          if (isset($action[$key])) { @@ -865,29 +863,19 @@ class rcube_sieve_script                      }                  } +                $action['options'] = (array) $action['options']; + +                // Old-draft way: :method "mailto" :options "email@address" +                if (!empty($action['method']) && !empty($action['options'])) { +                    $action['method'] .= ':' . array_shift($action['options']); +                }                  // unnamed parameter is a :method in enotify extension -                if (!isset($action['method'])) { +                else if (!isset($action['method'])) {                      $action['method'] = array_pop($tokens);                  } -                $method_components = parse_url($action['method']); -                if ($method_components['scheme'] == 'mailto') { -                    $action['address'] = $method_components['path']; -                    $method_params = array(); -                    if (array_key_exists('query', $method_components)) { -                        parse_str($method_components['query'], $method_params); -                    } -                    $method_params = array_change_key_case($method_params, CASE_LOWER); -                    // magic_quotes_gpc and magic_quotes_sybase affect the output of parse_str -                    if (ini_get('magic_quotes_gpc') || ini_get('magic_quotes_sybase')) { -                        array_map('stripslashes', $method_params); -                    } -                    $action['body'] = (array_key_exists('body', $method_params)) ? $method_params['body'] : ''; -                } -                  $result[] = $action;                  break; -              }              if ($separator == $end) diff --git a/plugins/managesieve/localization/en_US.inc b/plugins/managesieve/localization/en_US.inc index e732b4831..1ea7d969e 100644 --- a/plugins/managesieve/localization/en_US.inc +++ b/plugins/managesieve/localization/en_US.inc @@ -110,14 +110,17 @@ $labels['varupperfirst'] = 'first character upper-case';  $labels['varquotewildcard'] = 'quote special characters';  $labels['varlength'] = 'length';  $labels['notify'] = 'Send notification'; -$labels['notifyaddress'] = 'To e-mail address:'; -$labels['notifybody'] = 'Notification body:'; -$labels['notifysubject'] = 'Notification subject:'; -$labels['notifyfrom'] = 'Notification sender:'; +$labels['notifytarget'] = 'Notification target:'; +$labels['notifymessage'] = 'Notification message (optional):'; +$labels['notifyoptions'] = 'Notification options (optional):'; +$labels['notifyfrom'] = 'Notification sender (optional):';  $labels['notifyimportance'] = 'Importance:';  $labels['notifyimportancelow'] = 'low';  $labels['notifyimportancenormal'] = 'normal';  $labels['notifyimportancehigh'] = 'high'; +$labels['notifymethodmailto'] = 'Email'; +$labels['notifymethodtel'] = 'Phone'; +$labels['notifymethodsms'] = 'SMS';  $labels['filtercreate'] = 'Create filter';  $labels['usedata'] = 'Use following data in the filter:';  $labels['nextstep'] = 'Next Step'; diff --git a/plugins/managesieve/tests/src/parser_notify_a b/plugins/managesieve/tests/src/parser_notify_a index f1a57540e..e51e2aa8d 100644 --- a/plugins/managesieve/tests/src/parser_notify_a +++ b/plugins/managesieve/tests/src/parser_notify_a @@ -14,5 +14,5 @@ if header :matches "Subject" "*"  if header :matches "From" "*"  {  	set "from" "${1}"; -	notify :high :message "${from}: ${subject}" :method "mailto:test@example.org"; +	notify :high :method "mailto" :options "test@example.org" :message "${from}: ${subject}";  } diff --git a/plugins/managesieve/tests/src/parser_notify_b b/plugins/managesieve/tests/src/parser_notify_b index ab90ed48c..f942e155f 100644 --- a/plugins/managesieve/tests/src/parser_notify_b +++ b/plugins/managesieve/tests/src/parser_notify_b @@ -13,5 +13,5 @@ if header :matches "Subject" "*"  if address :matches "from" "*"  {  	set "from_addr" "${1}"; -	notify :message "${from_addr}${env_from}: ${subject}" :method "sms:1234567890"; +	notify :method "sms" :options "1234567890" :message "${from_addr}${env_from}: ${subject}";  } | 
