From 50a57e9b755e80885c7a608924e6e860b28be541 Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Fri, 14 Mar 2014 08:36:43 -0400
Subject: [PATCH] Added optional separate interface for out-of-office management (#1488266)

---
 plugins/managesieve/skins/classic/templates/vacation.html    |   31 ++
 plugins/managesieve/skins/classic/templates/setedit.html     |    1 
 plugins/managesieve/skins/larry/templates/filteredit.html    |    1 
 plugins/managesieve/Changelog                                |    2 
 plugins/managesieve/localization/en_US.inc                   |   21 +
 plugins/managesieve/skins/classic/managesieve.css            |   19 +
 plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php   |  303 +++++++++++++++++++++++++++
 plugins/managesieve/managesieve.php                          |   65 ++++-
 plugins/managesieve/skins/larry/templates/vacation.html      |   30 ++
 plugins/managesieve/config.inc.php.dist                      |    6 
 plugins/managesieve/skins/larry/images/vacation_icons.png    |    0 
 plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php     |   71 +++--
 plugins/managesieve/skins/classic/templates/filteredit.html  |    1 
 plugins/managesieve/skins/larry/managesieve.css              |   40 +++
 plugins/managesieve/skins/larry/templates/setedit.html       |    1 
 plugins/managesieve/managesieve.js                           |   18 +
 plugins/managesieve/skins/classic/templates/managesieve.html |    1 
 plugins/managesieve/skins/larry/templates/managesieve.html   |    1 
 18 files changed, 555 insertions(+), 57 deletions(-)

diff --git a/plugins/managesieve/Changelog b/plugins/managesieve/Changelog
index 559390f..afdafed 100644
--- a/plugins/managesieve/Changelog
+++ b/plugins/managesieve/Changelog
@@ -1,3 +1,5 @@
+- Added optional separate interface for out-of-office management (#1488266)
+
 * version 7.2 [2014-02-14]
 -----------------------------------------------------------
 - Nicely handle server-side modification of script names (#1489412)
diff --git a/plugins/managesieve/config.inc.php.dist b/plugins/managesieve/config.inc.php.dist
index 52d3a9b..316eddd 100644
--- a/plugins/managesieve/config.inc.php.dist
+++ b/plugins/managesieve/config.inc.php.dist
@@ -68,4 +68,10 @@
 // If not empty, user will need to select domain from a list
 $config['managesieve_domains'] = array();
 
+// Enables separate management interface for vacation responses (out-of-office)
+// 0 - no separate section (default),
+// 1 - add Vacation section,
+// 2 - add Vacation section, but hide Filters section
+$config['managesieve_vacation'] = 0;
+
 ?>
diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php b/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php
index c366afa..c73d503 100644
--- a/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php
+++ b/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php
@@ -24,21 +24,21 @@
 
 class rcube_sieve_engine
 {
-    private $rc;
-    private $sieve;
-    private $errors;
-    private $form;
-    private $tips = array();
-    private $script = array();
-    private $exts = array();
-    private $list;
-    private $active = array();
-    private $headers = array(
+    protected $rc;
+    protected $sieve;
+    protected $errors;
+    protected $form;
+    protected $tips = array();
+    protected $script = array();
+    protected $exts = array();
+    protected $list;
+    protected $active = array();
+    protected $headers = array(
         'subject' => 'Subject',
         'from'    => 'From',
         'to'      => 'To',
     );
-    private $addr_headers = array(
+    protected $addr_headers = array(
         // Required
         "from", "to", "cc", "bcc", "sender", "resent-from", "resent-to",
         // Additional (RFC 822 / RFC 2822)
@@ -53,7 +53,7 @@
         "x-beenthere",
     );
 
-    const VERSION  = '7.2';
+    const VERSION  = '8.0';
     const PROGNAME = 'Roundcube (Managesieve)';
     const PORT     = 4190;
 
@@ -70,7 +70,7 @@
     /**
      * Loads configuration, initializes plugin (including sieve connection)
      */
-    function start()
+    function start($mode = null)
     {
         // register UI objects
         $this->rc->output->add_handlers(array(
@@ -137,13 +137,16 @@
                 $this->rc->session->remove('managesieve_current');
             }
 
-            if (!empty($_GET['_set']) || !empty($_POST['_set'])) {
-                $script_name = rcube_utils::get_input_value('_set', rcube_utils::INPUT_GPC, true);
+            if ($mode != 'vacation') {
+                if (!empty($_GET['_set']) || !empty($_POST['_set'])) {
+                    $script_name = rcube_utils::get_input_value('_set', rcube_utils::INPUT_GPC, true);
+                }
+                else if (!empty($_SESSION['managesieve_current'])) {
+                    $script_name = $_SESSION['managesieve_current'];
+                }
             }
-            else if (!empty($_SESSION['managesieve_current'])) {
-                $script_name = $_SESSION['managesieve_current'];
-            }
-            else {
+
+            if ($script_name === null || $script_name === '') {
                 // get (first) active script
                 if (!empty($this->active[0])) {
                     $script_name = $this->active[0];
@@ -911,9 +914,12 @@
                     break;
 
                 case 'vacation':
+
                     $reason        = $this->strip_value($reasons[$idx]);
                     $interval_type = $interval_types[$idx] == 'seconds' ? 'seconds' : 'days';
-
+console('---------------');
+console($_POST);
+console($reason);
                     $this->form['actions'][$i]['reason']    = str_replace("\r\n", "\n", $reason);
                     $this->form['actions'][$i]['subject']   = $subject[$idx];
                     $this->form['actions'][$i]['addresses'] = array_shift($addresses);
@@ -980,7 +986,7 @@
             }
 
             if (!$this->errors && !$error) {
-                // zapis skryptu
+                // save the script
                 if (!isset($this->script[$fid])) {
                     $fid = $this->sieve->script->add_rule($this->form);
                     $new = true;
@@ -1016,7 +1022,7 @@
         $this->send();
     }
 
-    private function send()
+    protected function send()
     {
         // Handle form action
         if (isset($_GET['_framed']) || isset($_POST['_framed'])) {
@@ -1026,7 +1032,8 @@
             else {
                 $this->rc->output->send('managesieve.filteredit');
             }
-        } else {
+        }
+        else {
             $this->rc->output->set_pagetitle($this->plugin->gettext('filters'));
             $this->rc->output->send('managesieve.managesieve');
         }
@@ -1809,12 +1816,12 @@
         return $out;
     }
 
-    private function genid()
+    protected function genid()
     {
         return preg_replace('/[^0-9]/', '', microtime(true));
     }
 
-    private function strip_value($str, $allow_html = false, $trim = true)
+    protected function strip_value($str, $allow_html = false, $trim = true)
     {
         if (is_array($str)) {
             foreach ($str as $idx => $val) {
@@ -1835,7 +1842,7 @@
         return $trim ? trim($str) : $str;
     }
 
-    private function error_class($id, $type, $target, $elem_prefix='')
+    protected function error_class($id, $type, $target, $elem_prefix='')
     {
         // TODO: tooltips
         if (($type == 'test' && ($str = $this->errors['tests'][$id][$target])) ||
@@ -1848,7 +1855,7 @@
         return '';
     }
 
-    private function add_tip($id, $str, $error=false)
+    protected function add_tip($id, $str, $error=false)
     {
         if ($error)
             $str = html::span('sieve error', $str);
@@ -1856,7 +1863,7 @@
         $this->tips[] = array($id, $str);
     }
 
-    private function print_tips()
+    protected function print_tips()
     {
         if (empty($this->tips))
             return;
@@ -1865,7 +1872,7 @@
         $this->rc->output->add_script($script, 'foot');
     }
 
-    private function list_input($id, $name, $value, $enabled, $class, $size=null)
+    protected function list_input($id, $name, $value, $enabled, $class, $size=null)
     {
         $value = (array) $value;
         $value = array_map(array('rcube', 'Q'), $value);
@@ -1881,7 +1888,7 @@
     /**
      * Validate input for date part elements
      */
-    private function validate_date_part($type, $value)
+    protected function validate_date_part($type, $value)
     {
         // we do simple validation of date/part format
         switch ($type) {
@@ -1926,7 +1933,7 @@
      *
      * @return string Mailbox name
      */
-    private function mod_mailbox($mailbox, $mode = 'out')
+    protected function mod_mailbox($mailbox, $mode = 'out')
     {
         $delimiter         = $_SESSION['imap_delimiter'];
         $replace_delimiter = $this->rc->config->get('managesieve_replace_delimiter');
@@ -2218,7 +2225,7 @@
     /**
      * Initializes internal script data
      */
-    private function init_script()
+    protected function init_script()
     {
         $this->script = $this->sieve->script->as_array();
 
diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php b/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php
new file mode 100644
index 0000000..636b5fc
--- /dev/null
+++ b/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php
@@ -0,0 +1,303 @@
+<?php
+
+/**
+ * Managesieve Vacation Engine
+ *
+ * Engine part of Managesieve plugin implementing UI and backend access.
+ *
+ * Copyright (C) 2011-2014, Kolab Systems AG
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+class rcube_sieve_vacation extends rcube_sieve_engine
+{
+    function actions()
+    {
+        $error = $this->start('vacation');
+
+        // find current vacation rule
+        if (!$error) {
+            $this->vacation_rule();
+            $this->vacation_post();
+        }
+
+        $this->plugin->add_label('vacation.saving');
+        $this->rc->output->add_handlers(array(
+            'vacationform' => array($this, 'vacation_form'),
+        ));
+
+        $this->rc->output->set_pagetitle($this->plugin->gettext('vacation'));
+        $this->rc->output->send('managesieve.vacation');
+    }
+
+    private function vacation_rule()
+    {
+        $this->vacation = array();
+
+        if (empty($this->active)) {
+            return;
+        }
+
+        $list = array();
+
+        // find (first) vacation rule
+        foreach ($this->script as $idx => $rule) {
+            if (empty($this->vacation) && !empty($rule['actions']) && $rule['actions'][0]['type'] == 'vacation') {
+                $this->vacation = array_merge($rule['actions'][0], array(
+                        'idx'      => $idx,
+                        'disabled' => $rule['disabled'],
+                        'name'     => $rule['name'],
+                        'tests'    => $rule['tests'],
+                ));
+            }
+            else {
+                $list[$idx] = $rule['name'];
+            }
+        }
+
+        $this->vacation['list'] = $list;
+    }
+
+    private function vacation_post()
+    {
+        if (empty($_POST)) {
+            return;
+        }
+
+        $status        = rcube_utils::get_input_value('vacation_status', rcube_utils::INPUT_POST);
+        $subject       = rcube_utils::get_input_value('vacation_subject', rcube_utils::INPUT_POST, true);
+        $reason        = rcube_utils::get_input_value('vacation_reason', rcube_utils::INPUT_POST, true);
+        $addresses     = rcube_utils::get_input_value('vacation_addresses', rcube_utils::INPUT_POST, true);
+        $interval      = rcube_utils::get_input_value('vacation_interval', rcube_utils::INPUT_POST);
+        $interval_type = rcube_utils::get_input_value('vacation_interval_type', rcube_utils::INPUT_POST);
+        $date_from     = rcube_utils::get_input_value('vacation_datefrom', rcube_utils::INPUT_POST);
+        $date_to       = rcube_utils::get_input_value('vacation_dateto', rcube_utils::INPUT_POST);
+        $after         = rcube_utils::get_input_value('vacation_after', rcube_utils::INPUT_POST);
+
+        $interval_type                   = $interval_type == 'seconds' ? 'seconds' : 'days';
+        $vacation_action['type']         = 'vacation';
+        $vacation_action['reason']       = $this->strip_value(str_replace("\r\n", "\n", $reason));
+        $vacation_action['subject']      = $subject;
+        $vacation_action['addresses']    = $addresses;
+        $vacation_action[$interval_type] = $interval;
+        $vacation_tests                  = (array) $this->vacation['tests'];
+
+        foreach ((array) $vacation_action['addresses'] as $aidx => $address) {
+            $vacation_action['addresses'][$aidx] = $address = trim($address);
+
+            if (empty($address)) {
+                unset($vacation_action['addresses'][$aidx]);
+            }
+            else if (!rcube_utils::check_email($address)) {
+                $error = 'noemailwarning';
+                break;
+            }
+        }
+
+        if ($vacation_action['reason'] == '') {
+            $error = 'managesieve.cannotbeempty';
+        }
+        if ($vacation_action[$interval_type] && !preg_match('/^[0-9]+$/', $vacation_action[$interval_type])) {
+            $error = 'managesieve.forbiddenchars';
+        }
+
+        foreach (array('date_from', 'date_to') as $var) {
+            $date = $$var;
+
+            if ($date && ($dt = rcube_utils::anytodatetime($date))) {
+                $type = 'value-' . ($var == 'date_from' ? 'ge' : 'le');
+                $test = array(
+                    'test' => 'currentdate',
+                    'part' => 'date',
+                    'type' => $type,
+                    'arg'  => $dt->format('Y-m-d'),
+                );
+
+                // find existing date rule
+                foreach ((array) $vacation_tests as $idx => $t) {
+                    if ($t['test'] == 'currentdate' && $t['part'] == 'date' && $t['type'] == $type) {
+                        $vacation_tests[$idx] = $test;
+                        continue 2;
+                    }
+                }
+
+                $vacation_tests[] = $test;
+            }
+        }
+
+        if (empty($vacation_tests)) {
+            $vacation_tests = $this->rc->config->get('managesieve_vacation_test', array(array('test' => 'true')));
+        }
+
+        // @TODO: handle situation when there's no active script
+
+        if (!$error) {
+            $rule               = $this->vacation;
+            $rule['type']       = 'if';
+            $rule['name']       = $rule['name'] ?: $this->plugin->gettext('vacation');
+            $rule['disabled']   = $status == 'off';
+            $rule['actions'][0] = $vacation_action;
+            $rule['tests']      = $vacation_tests;
+            $rule['join']       = count($vacation_tests) > 1;
+
+            // reset original vacation rule
+            if (isset($this->vacation['idx'])) {
+                $this->script[$this->vacation['idx']] = null;
+            }
+
+            // re-order rules if needed
+            if (isset($after) && $after !== '') {
+                // add at target position
+                if ($after >= count($this->script) - 1) {
+                    $this->script[] = $rule;
+                }
+                else {
+                    $script = array();
+
+                    foreach ($this->script as $idx => $r) {
+                        if ($r) {
+                            $script[] = $r;
+                        }
+
+                        if ($idx == $after) {
+                            $script[] = $rule;
+                        }
+                    }
+
+                    $this->script = $script;
+                }
+            }
+            else {
+                array_unshift($this->script, $rule);
+            }
+
+            $this->sieve->script->content = array_values(array_filter($this->script));
+
+            if ($this->save_script()) {
+                $this->rc->output->show_message('managesieve.vacationsaved', 'confirmation');
+                $this->rc->output->send();
+            }
+        }
+
+        $this->rc->output->show_message($error ? $error : 'managesieve.saveerror', 'error');
+        $this->rc->output->send();
+    }
+
+    /**
+     * Independent vacation form
+     */
+    public function vacation_form($attrib)
+    {
+        // check supported extensions
+        $date_extension    = in_array('date', $this->exts);
+        $seconds_extension = in_array('vacation-seconds', $this->exts);
+
+        // build FORM tag
+        $form_id = !empty($attrib['id']) ? $attrib['id'] : 'form';
+        $out     = $this->rc->output->request_form(array(
+            'id'      => $form_id,
+            'name'    => $form_id,
+            'method'  => 'post',
+            'task'    => 'settings',
+            'action'  => 'plugin.managesieve-vacation',
+            'noclose' => true
+            ) + $attrib);
+
+        // form elements
+        $subject   = new html_inputfield(array('name' => 'vacation_subject', 'size' => 50));
+        $reason    = new html_textarea(array('name' => 'vacation_reason', 'cols' => 60, 'rows' => 8));
+        $interval  = new html_inputfield(array('name' => 'vacation_interval', 'size' => 5));
+        $addresses = '<textarea name="vacation_addresses" data-type="list" data-size="30" style="display: none">'
+            . rcube::Q(implode("\n", (array) $this->vacation['addresses']), 'strict', false) . '</textarea>';
+        $status    = new html_select(array('name' => 'vacation_status'));
+
+        $status->add($this->plugin->gettext('vacation.on'), 'on');
+        $status->add($this->plugin->gettext('vacation.off'), 'off');
+
+        if ($this->rc->config->get('managesieve_vacation') != 2 && count($this->vacation['list'])) {
+            $after = new html_select(array('name' => 'vacation_after'));
+
+            $after->add('', '');
+            foreach ($this->vacation['list'] as $idx => $rule) {
+                $after->add($rule, $idx);
+            }
+        }
+
+        $interval_txt = $interval->show(isset($this->vacation['seconds']) ? $this->vacation['seconds'] : $this->vacation['days']);
+        if ($seconds_extension) {
+            $interval_select = new html_select(array('name' => 'vacation_interval_type'));
+            $interval_select->add($this->plugin->gettext('days'), 'days');
+            $interval_select->add($this->plugin->gettext('seconds'), 'seconds');
+            $interval_txt .= '&nbsp;' . $interval_select->show(isset($this->vacation['seconds']) ? 'seconds' : 'days');
+        }
+        else {
+            $interval_txt .= '&nbsp;' . $this->plugin->gettext('days');
+        }
+
+        if ($date_extension) {
+            $date_from   = new html_inputfield(array('name' => 'vacation_datefrom', 'class' => 'datepicker', 'size' => 12));
+            $date_to     = new html_inputfield(array('name' => 'vacation_dateto', 'class' => 'datepicker', 'size' => 12));
+            $date_format = $this->rc->config->get('date_format', 'Y-m-d');
+
+            foreach ((array) $this->vacation['tests'] as $test) {
+                if ($test['test'] == 'currentdate' && $test['part'] == 'date') {
+                    $date = $this->rc->format_date($test['arg'], $date_format, false);
+                    $date_value[$test['type'] == 'value-ge' ? 'from' : 'to'] = $date;
+                }
+            }
+        }
+
+        // Message tab
+        $table = new html_table(array('cols' => 2));
+
+        $table->add('title', html::label('vacation_subject', $this->plugin->gettext('vacation.subject')));
+        $table->add(null, $subject->show($this->vacation['subject']));
+        $table->add('title', html::label('vacation_reason', $this->plugin->gettext('vacation.body')));
+        $table->add(null, $reason->show($this->vacation['reason']));
+
+        if ($date_extension) {
+            $table->add('title', html::label('vacation_datefrom', $this->plugin->gettext('vacation.dates')));
+            $table->add(null,
+                $this->plugin->gettext('vacation.from'). ' ' . $date_from->show($date_value['from'])
+                . ' ' . $this->plugin->gettext('vacation.to'). ' ' . $date_to->show($date_value['to'])
+            );
+        }
+
+        $table->add('title', html::label('vacation_status', $this->plugin->gettext('vacation.status')));
+        $table->add(null, $status->show($this->vacation['disabled'] ? 'off' : 'on'));
+
+        $out .= html::tag('fieldset', $class, html::tag('legend', null, $this->plugin->gettext('vacation.reply')) . $table->show($attrib));
+
+        // Advanced tab
+        $table = new html_table(array('cols' => 2));
+
+        $table->add('title', $this->plugin->gettext('vacation.addresses'));
+        $table->add(null, $addresses);
+        $table->add('title', $this->plugin->gettext('vacation.interval'));
+        $table->add(null, $interval_txt);
+        if ($after) {
+            $table->add('title', $this->plugin->gettext('vacation.after'));
+            $table->add(null, $after->show($this->vacation['idx'] - 1));
+        }
+
+        $out .= html::tag('fieldset', $class, html::tag('legend', null, $this->plugin->gettext('vacation.advanced')) . $table->show($attrib));
+
+        $out .= '</form>';
+
+        $this->rc->output->add_gui_object('sieveform', $form_id);
+
+        return $out;
+    }
+}
diff --git a/plugins/managesieve/localization/en_US.inc b/plugins/managesieve/localization/en_US.inc
index cbe69dc..e732b48 100644
--- a/plugins/managesieve/localization/en_US.inc
+++ b/plugins/managesieve/localization/en_US.inc
@@ -59,10 +59,10 @@
 $labels['vacationaddr'] = 'My additional e-mail address(es):';
 $labels['vacationdays'] = 'How often send messages (in days):';
 $labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
 $labels['vacationreason'] = 'Message body (vacation reason):';
 $labels['vacationsubject'] = 'Message subject:';
+$labels['days'] = 'days';
+$labels['seconds'] = 'seconds';
 $labels['rulestop'] = 'Stop evaluating rules';
 $labels['enable'] = 'Enable/Disable';
 $labels['filterset'] = 'Filters set';
@@ -159,6 +159,21 @@
 $labels['asciinumeric'] = 'numeric (ascii-numeric)';
 $labels['index'] = 'index:';
 $labels['indexlast'] = 'backwards';
+$labels['vacation'] = 'Vacation';
+$labels['vacation.reply'] = 'Reply message';
+$labels['vacation.advanced'] = 'Advanced settings';
+$labels['vacation.subject'] = 'Subject';
+$labels['vacation.body'] = 'Body';
+$labels['vacation.dates'] = 'Vacation time';
+$labels['vacation.from'] = 'From:';
+$labels['vacation.to'] = 'To:';
+$labels['vacation.status'] = 'Status';
+$labels['vacation.on'] = 'On';
+$labels['vacation.off'] = 'Off';
+$labels['vacation.addresses'] = 'My additional addresses';
+$labels['vacation.interval'] = 'Reply interval';
+$labels['vacation.after'] = 'Put vacation rule after';
+$labels['vacation.saving'] = 'Saving data...';
 
 $messages = array();
 $messages['filterunknownerror'] = 'Unknown server error.';
@@ -193,5 +208,7 @@
 $messages['setexist'] = 'Set already exists.';
 $messages['nodata'] = 'At least one position must be selected!';
 $messages['invaliddateformat'] = 'Invalid date or date part format';
+$messages['saveerror'] = 'Unable to save data. Server error occurred.';
+$messages['vacationsaved'] = 'Vacation data saved successfully.';
 
 ?>
diff --git a/plugins/managesieve/managesieve.js b/plugins/managesieve/managesieve.js
index 6b36127..7fcd9d9 100644
--- a/plugins/managesieve/managesieve.js
+++ b/plugins/managesieve/managesieve.js
@@ -50,6 +50,18 @@
         $('textarea[data-type="list"]', rcmail.gui_objects.sieveform).each(function() {
           smart_field_init(this);
         });
+
+        // enable date pickers on date fields
+        if ($.datepicker && rcmail.env.date_format) {
+          $.datepicker.setDefaults({
+            dateFormat: rcmail.env.date_format,
+            changeMonth: true,
+            showOtherMonths: true,
+            selectOtherMonths: true,
+            onSelect: function(dateText) { $(this).focus().val(dateText) }
+          });
+          $('input.datepicker').datepicker();
+        }
       }
       else {
         rcmail.enable_command('plugin.managesieve-add', 'plugin.managesieve-setadd', !rcmail.env.sieveconnerror);
@@ -443,6 +455,12 @@
 // Form submition
 rcube_webmail.prototype.managesieve_save = function()
 {
+  if (this.env.action == 'plugin.managesieve-vacation') {
+    var data = $(this.gui_objects.sieveform).serialize();
+    this.http_post('plugin.managesieve-vacation', data, this.display_message(this.get_label('managesieve.vacation.saving'), 'loading'));
+    return;
+  }
+
   if (parent.rcmail && parent.rcmail.filters_list && this.gui_objects.sieveform.name != 'filtersetform') {
     var id = parent.rcmail.filters_list.get_single_selection();
     if (id != null)
diff --git a/plugins/managesieve/managesieve.php b/plugins/managesieve/managesieve.php
index aa74c52..aba3425 100644
--- a/plugins/managesieve/managesieve.php
+++ b/plugins/managesieve/managesieve.php
@@ -42,6 +42,7 @@
         // register actions
         $this->register_action('plugin.managesieve', array($this, 'managesieve_actions'));
         $this->register_action('plugin.managesieve-action', array($this, 'managesieve_actions'));
+        $this->register_action('plugin.managesieve-vacation', array($this, 'managesieve_actions'));
         $this->register_action('plugin.managesieve-save', array($this, 'managesieve_save'));
 
         if ($this->rc->task == 'settings') {
@@ -69,8 +70,25 @@
         }
 
         // load localization
-        $this->add_texts('localization/', array('filters','managefilters'));
-        $this->include_script('managesieve.js');
+        $this->add_texts('localization/');
+
+        if (strpos($this->rc->action, 'plugin.managesieve') === 0) {
+            $this->include_script('managesieve.js');
+        }
+
+        // include styles
+        $skin_path = $this->local_skin_path();
+        if ($this->rc->task == 'settings') {
+            if (is_file($this->home . "/$skin_path/managesieve.css")) {
+                $this->include_stylesheet("$skin_path/managesieve.css");
+            }
+        }
+        else {
+            if (is_file($this->home . "/$skin_path/managesieve_mail.css")) {
+                $this->include_stylesheet("$skin_path/managesieve_mail.css");
+            }
+        }
+
 
         $this->ui_initialized = true;
     }
@@ -80,8 +98,30 @@
      */
     function settings_actions($args)
     {
-        // register as settings action
-        $args['actions'][] = array('action' => 'plugin.managesieve', 'class' => 'filter', 'label' => 'filters', 'domain' => 'managesieve');
+        $this->load_config();
+
+        $vacation_mode = (int) $this->rc->config->get('managesieve_vacation');
+
+        // register Filters action
+        if ($vacation_mode != 2) {
+            $args['actions'][] = array(
+                'action' => 'plugin.managesieve',
+                'class'  => 'filter',
+                'label'  => 'filters',
+                'domain' => 'managesieve',
+            );
+        }
+
+        // register Vacation action
+        if ($vacation_mode > 0) {
+            $args['actions'][] = array(
+                'action' => 'plugin.managesieve-vacation',
+                'class'  => 'vacation',
+                'label'  => 'vacation',
+                'domain' => 'managesieve',
+            );
+        }
+
         return $args;
     }
 
@@ -100,12 +140,6 @@
 
         // include js script and localization
         $this->init_ui();
-
-        // include styles
-        $skin_path = $this->local_skin_path();
-        if (is_file($this->home . "/$skin_path/managesieve_mail.css")) {
-            $this->include_stylesheet("$skin_path/managesieve_mail.css");
-        }
 
         // add 'Create filter' item to message menu
         $this->api->add_content(html::tag('li', null, 
@@ -163,9 +197,11 @@
             $this->rc->output->send();
         }
 
-        // handle other action
+        // handle other actions
+        $engine_type = $this->rc->action == 'plugin.managesieve-vacation' ? 'vacation' : '';
+        $engine      = $this->get_engine($engine_type);
+
         $this->init_ui();
-        $engine = $this->get_engine();
         $engine->actions();
     }
 
@@ -189,7 +225,7 @@
     /**
      * Initializes engine object
      */
-    private function get_engine()
+    private function get_engine($type = null)
     {
         if (!$this->engine) {
             $this->load_config();
@@ -199,7 +235,8 @@
             $include_path .= ini_get('include_path');
             set_include_path($include_path);
 
-            $this->engine = new rcube_sieve_engine($this);
+            $class_name = 'rcube_sieve_' . ($type ? $type : 'engine');
+            $this->engine = new $class_name($this);
         }
 
         return $this->engine;
diff --git a/plugins/managesieve/skins/classic/managesieve.css b/plugins/managesieve/skins/classic/managesieve.css
index 59d88cb..dea0a94 100644
--- a/plugins/managesieve/skins/classic/managesieve.css
+++ b/plugins/managesieve/skins/classic/managesieve.css
@@ -115,7 +115,7 @@
   padding: 20px 10px 10px 10px;
 }
 
-legend, label
+#filter-form legend, #filter-form label
 {
   color: #666666;
 }
@@ -410,3 +410,20 @@
 {
   padding: 10px 5px 5px 5px;
 }
+
+#vacationform .listarea {
+  max-height: 83px;
+}
+
+#vacationform .listelement,
+#vacationform .listelement .reset {
+  height: 20px;
+}
+
+#vacationform .listelement .reset {
+  background-position: -1px 2px;
+}
+
+#vacationform .listelement input {
+  vertical-align: top;
+}
diff --git a/plugins/managesieve/skins/classic/templates/filteredit.html b/plugins/managesieve/skins/classic/templates/filteredit.html
index 6ecb03c..8cef816 100644
--- a/plugins/managesieve/skins/classic/templates/filteredit.html
+++ b/plugins/managesieve/skins/classic/templates/filteredit.html
@@ -3,7 +3,6 @@
 <head>
 <title><roundcube:object name="pagetitle" /></title>
 <roundcube:include file="/includes/links.html" />
-<link rel="stylesheet" type="text/css" href="/this/managesieve.css" />
 </head>
 <body class="iframe<roundcube:exp expression="env:task != 'mail' ? '' : ' mail'" />">
 
diff --git a/plugins/managesieve/skins/classic/templates/managesieve.html b/plugins/managesieve/skins/classic/templates/managesieve.html
index 3d84466..5ed0994 100644
--- a/plugins/managesieve/skins/classic/templates/managesieve.html
+++ b/plugins/managesieve/skins/classic/templates/managesieve.html
@@ -3,7 +3,6 @@
 <head>
 <title><roundcube:object name="pagetitle" /></title>
 <roundcube:include file="/includes/links.html" />
-<link rel="stylesheet" type="text/css" href="/this/managesieve.css" />
 <script type="text/javascript" src="/functions.js"></script>
 <script type="text/javascript" src="/splitter.js"></script>
 
diff --git a/plugins/managesieve/skins/classic/templates/setedit.html b/plugins/managesieve/skins/classic/templates/setedit.html
index 26f7fec..c1010ca 100644
--- a/plugins/managesieve/skins/classic/templates/setedit.html
+++ b/plugins/managesieve/skins/classic/templates/setedit.html
@@ -3,7 +3,6 @@
 <head>
 <title><roundcube:object name="pagetitle" /></title>
 <roundcube:include file="/includes/links.html" />
-<link rel="stylesheet" type="text/css" href="/this/managesieve.css" />
 </head>
 <body class="iframe">
 
diff --git a/plugins/managesieve/skins/classic/templates/vacation.html b/plugins/managesieve/skins/classic/templates/vacation.html
new file mode 100644
index 0000000..bf94edb
--- /dev/null
+++ b/plugins/managesieve/skins/classic/templates/vacation.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+<script type="text/javascript" src="/functions.js"></script>
+</head>
+<body>
+
+<roundcube:include file="/includes/taskbar.html" />
+<roundcube:include file="/includes/header.html" />
+<roundcube:include file="/includes/settingstabs.html" />
+
+<div id="mainscreen">
+  <div class="box" style="height: 100%; overflow: auto">
+    <div id="prefs-title" class="boxtitle"><roundcube:label name="managesieve.vacation" /></div>
+    <roundcube:object name="vacationform" id="vacationform" style="margin: 10px 10px 0 10px" />
+    <div id="formfooter" style="padding: 0 10px">
+      <div class="footerleft">
+        <roundcube:button command="save" type="input" class="button mainaction" label="save" />
+      </div>
+    </div>
+  </div>
+</div>
+
+<script type="text/javascript">
+rcube_init_mail_ui();
+</script>
+
+</body>
+</html>
diff --git a/plugins/managesieve/skins/larry/images/vacation_icons.png b/plugins/managesieve/skins/larry/images/vacation_icons.png
new file mode 100644
index 0000000..f8933d4
--- /dev/null
+++ b/plugins/managesieve/skins/larry/images/vacation_icons.png
Binary files differ
diff --git a/plugins/managesieve/skins/larry/managesieve.css b/plugins/managesieve/skins/larry/managesieve.css
index 2144fe1..b36d97f 100644
--- a/plugins/managesieve/skins/larry/managesieve.css
+++ b/plugins/managesieve/skins/larry/managesieve.css
@@ -89,7 +89,7 @@
   padding: 20px 10px 10px 10px;
 }
 
-legend, label
+#filter-form legend, #filter-form label
 {
   color: #666666;
 }
@@ -124,7 +124,7 @@
   min-width: 600px;
 }
 
-td
+#filter-form td
 {
   vertical-align: top;
 }
@@ -414,3 +414,39 @@
 {
   padding: 10px 5px 5px 5px;
 }
+
+
+/* vacation form */
+#settings-sections span.vacation a {
+  background: url(images/vacation_icons.png) no-repeat 7px 1px;
+}
+
+#settings-sections span.vacation.selected a {
+  background-position: 7px -23px;
+}
+
+#managesieve-vacation {
+  position: absolute;
+  top: 0;
+  left: 212px;
+  right: 0;
+  bottom: 0;
+  overflow: auto;
+}
+
+#vacationform .listarea {
+  max-height: 83px;
+}
+
+#vacationform .listelement,
+#vacationform .listelement .reset {
+  height: 27px;
+}
+
+#vacationform .listelement .reset {
+  background-position: -1px 5px;
+}
+
+#vacationform .listelement input {
+  vertical-align: top;
+}
diff --git a/plugins/managesieve/skins/larry/templates/filteredit.html b/plugins/managesieve/skins/larry/templates/filteredit.html
index 602816a..1933b58 100644
--- a/plugins/managesieve/skins/larry/templates/filteredit.html
+++ b/plugins/managesieve/skins/larry/templates/filteredit.html
@@ -3,7 +3,6 @@
 <head>
 <title><roundcube:object name="pagetitle" /></title>
 <roundcube:include file="/includes/links.html" />
-<link rel="stylesheet" type="text/css" href="/this/managesieve.css" />
 </head>
 <body class="iframe<roundcube:exp expression="env:task != 'mail' ? ' floatingbuttons' : ' mail'" />">
 
diff --git a/plugins/managesieve/skins/larry/templates/managesieve.html b/plugins/managesieve/skins/larry/templates/managesieve.html
index 6ef3b2d..471bbf4 100644
--- a/plugins/managesieve/skins/larry/templates/managesieve.html
+++ b/plugins/managesieve/skins/larry/templates/managesieve.html
@@ -3,7 +3,6 @@
 <head>
 <title><roundcube:object name="pagetitle" /></title>
 <roundcube:include file="/includes/links.html" />
-<link rel="stylesheet" type="text/css" href="/this/managesieve.css" />
 </head>
 <body class="noscroll">
 
diff --git a/plugins/managesieve/skins/larry/templates/setedit.html b/plugins/managesieve/skins/larry/templates/setedit.html
index 9fc115d..3b8f98b 100644
--- a/plugins/managesieve/skins/larry/templates/setedit.html
+++ b/plugins/managesieve/skins/larry/templates/setedit.html
@@ -3,7 +3,6 @@
 <head>
 <title><roundcube:object name="pagetitle" /></title>
 <roundcube:include file="/includes/links.html" />
-<link rel="stylesheet" type="text/css" href="/this/managesieve.css" />
 </head>
 <body class="iframe floatingbuttons">
 
diff --git a/plugins/managesieve/skins/larry/templates/vacation.html b/plugins/managesieve/skins/larry/templates/vacation.html
new file mode 100644
index 0000000..c91eb87
--- /dev/null
+++ b/plugins/managesieve/skins/larry/templates/vacation.html
@@ -0,0 +1,30 @@
+<roundcube:object name="doctype" value="html5" />
+<html>
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+</head>
+<body class="noscroll">
+
+<roundcube:include file="/includes/header.html" />
+
+<div id="mainscreen" class="offset">
+
+<roundcube:include file="/includes/settingstabs.html" />
+
+<div id="managesieve-vacation" class="uibox contentbox">
+  <div>
+    <h2 class="boxtitle"><roundcube:label name="managesieve.vacation" /></h2>
+    <roundcube:object name="vacationform" id="vacationform" class="propform boxcontent tabbed" />
+  </div>
+  <div class="footerleft formbuttons">
+    <roundcube:button command="plugin.managesieve-save" type="input" class="button mainaction" label="save" />
+  </div>
+</div>
+
+</div>
+
+<roundcube:include file="/includes/footer.html" />
+
+</body>
+</html>

--
Gitblit v1.9.1