Aleksander Machniak
2014-03-14 50a57e9b755e80885c7a608924e6e860b28be541
Added optional separate interface for out-of-office management (#1488266)
4 files added
14 files modified
612 ■■■■■ changed files
plugins/managesieve/Changelog 2 ●●●●● patch | view | raw | blame | history
plugins/managesieve/config.inc.php.dist 6 ●●●●● patch | view | raw | blame | history
plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php 71 ●●●● patch | view | raw | blame | history
plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php 303 ●●●●● patch | view | raw | blame | history
plugins/managesieve/localization/en_US.inc 21 ●●●●● patch | view | raw | blame | history
plugins/managesieve/managesieve.js 18 ●●●●● patch | view | raw | blame | history
plugins/managesieve/managesieve.php 65 ●●●● patch | view | raw | blame | history
plugins/managesieve/skins/classic/managesieve.css 19 ●●●●● patch | view | raw | blame | history
plugins/managesieve/skins/classic/templates/filteredit.html 1 ●●●● patch | view | raw | blame | history
plugins/managesieve/skins/classic/templates/managesieve.html 1 ●●●● patch | view | raw | blame | history
plugins/managesieve/skins/classic/templates/setedit.html 1 ●●●● patch | view | raw | blame | history
plugins/managesieve/skins/classic/templates/vacation.html 31 ●●●●● patch | view | raw | blame | history
plugins/managesieve/skins/larry/images/vacation_icons.png patch | view | raw | blame | history
plugins/managesieve/skins/larry/managesieve.css 40 ●●●●● patch | view | raw | blame | history
plugins/managesieve/skins/larry/templates/filteredit.html 1 ●●●● patch | view | raw | blame | history
plugins/managesieve/skins/larry/templates/managesieve.html 1 ●●●● patch | view | raw | blame | history
plugins/managesieve/skins/larry/templates/setedit.html 1 ●●●● patch | view | raw | blame | history
plugins/managesieve/skins/larry/templates/vacation.html 30 ●●●●● patch | view | raw | blame | history
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)
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;
?>
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();
plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php
New file
@@ -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;
    }
}
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.';
?>
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)
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;
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;
}
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'" />">
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>
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">
plugins/managesieve/skins/classic/templates/vacation.html
New file
@@ -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>
plugins/managesieve/skins/larry/images/vacation_icons.png
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;
}
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'" />">
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">
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">
plugins/managesieve/skins/larry/templates/vacation.html
New file
@@ -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>