Aleksander Machniak
2015-11-22 9f1f754daf4b57a0d0d3aea95d2321716d218cf5
commit | author | age
48e9c1 1 <?php
T 2
3 /**
4  * Managesieve (Sieve Filters)
5  *
6  * Plugin that adds a possibility to manage Sieve filters in Thunderbird's style.
7  * It's clickable interface which operates on text scripts and communicates
8  * with server using managesieve protocol. Adds Filters tab in Settings.
9  *
e69516 10  * @version @package_version@
48e9c1 11  * @author Aleksander Machniak <alec@alec.pl>
T 12  *
13  * Configuration (see config.inc.php.dist)
14  *
0185a2 15  * Copyright (C) 2008-2013, The Roundcube Dev Team
AM 16  * Copyright (C) 2011-2013, Kolab Systems AG
48e9c1 17  *
07c6c6 18  * This program is free software: you can redistribute it and/or modify
TB 19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation, either version 3 of the License, or
21  * (at your option) any later version.
48e9c1 22  *
T 23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26  * GNU General Public License for more details.
27  *
07c6c6 28  * You should have received a copy of the GNU General Public License
TB 29  * along with this program. If not, see http://www.gnu.org/licenses/.
48e9c1 30  */
T 31
32 class managesieve extends rcube_plugin
33 {
34     public $task = 'mail|settings';
35     private $rc;
8ea08a 36     private $engine;
48e9c1 37
T 38     function init()
39     {
613f96 40         $this->rc = rcube::get_instance();
48e9c1 41
T 42         // register actions
43         $this->register_action('plugin.managesieve', array($this, 'managesieve_actions'));
27f0c2 44         $this->register_action('plugin.managesieve-action', array($this, 'managesieve_actions'));
50a57e 45         $this->register_action('plugin.managesieve-vacation', array($this, 'managesieve_actions'));
48e9c1 46         $this->register_action('plugin.managesieve-save', array($this, 'managesieve_save'));
T 47
48         if ($this->rc->task == 'settings') {
4e040e 49             $this->add_hook('settings_actions', array($this, 'settings_actions'));
48e9c1 50             $this->init_ui();
T 51         }
52         else if ($this->rc->task == 'mail') {
53             // register message hook
6e6f9c 54             if ($this->rc->action == 'show') {
AM 55                 $this->add_hook('message_headers_output', array($this, 'mail_headers'));
56             }
48e9c1 57
T 58             // inject Create Filter popup stuff
4d52ee 59             if (empty($this->rc->action) || $this->rc->action == 'show'
AM 60                 || strpos($this->rc->action, 'plugin.managesieve') === 0
61             ) {
48e9c1 62                 $this->mail_task_handler();
T 63             }
64         }
65     }
66
67     /**
68      * Initializes plugin's UI (localization, js script)
69      */
8ea08a 70     function init_ui()
48e9c1 71     {
8ea08a 72         if ($this->ui_initialized) {
48e9c1 73             return;
8ea08a 74         }
48e9c1 75
T 76         // load localization
50a57e 77         $this->add_texts('localization/');
AM 78
4d52ee 79         $sieve_action = strpos($this->rc->action, 'plugin.managesieve') === 0;
AM 80
81         if ($this->rc->task == 'mail' || $sieve_action) {
50a57e 82             $this->include_script('managesieve.js');
AM 83         }
84
85         // include styles
86         $skin_path = $this->local_skin_path();
570f43 87         if ($sieve_action || ($this->rc->task == 'settings' && empty($_REQUEST['_framed']))) {
e97951 88             $this->include_stylesheet("$skin_path/managesieve.css");
50a57e 89         }
570f43 90         else if ($this->rc->task == 'mail') {
e97951 91             $this->include_stylesheet("$skin_path/managesieve_mail.css");
50a57e 92         }
48e9c1 93
T 94         $this->ui_initialized = true;
95     }
96
97     /**
4e040e 98      * Adds Filters section in Settings
AM 99      */
100     function settings_actions($args)
101     {
50a57e 102         $this->load_config();
AM 103
104         $vacation_mode = (int) $this->rc->config->get('managesieve_vacation');
105
106         // register Filters action
107         if ($vacation_mode != 2) {
108             $args['actions'][] = array(
109                 'action' => 'plugin.managesieve',
110                 'class'  => 'filter',
111                 'label'  => 'filters',
112                 'domain' => 'managesieve',
ebc987 113                 'title'  => 'filterstitle',
50a57e 114             );
AM 115         }
116
117         // register Vacation action
118         if ($vacation_mode > 0) {
119             $args['actions'][] = array(
120                 'action' => 'plugin.managesieve-vacation',
121                 'class'  => 'vacation',
122                 'label'  => 'vacation',
123                 'domain' => 'managesieve',
ebc987 124                 'title'  => 'vacationtitle',
50a57e 125             );
AM 126         }
127
4e040e 128         return $args;
AM 129     }
130
131     /**
48e9c1 132      * Add UI elements to the 'mailbox view' and 'show message' UI.
T 133      */
134     function mail_task_handler()
135     {
2a3e77 136         // make sure we're not in ajax request
AM 137         if ($this->rc->output->type != 'html') {
138             return;
139         }
140
48e9c1 141         // use jQuery for popup window
bc92ca 142         $this->require_plugin('jqueryui');
48e9c1 143
T 144         // include js script and localization
145         $this->init_ui();
146
147         // add 'Create filter' item to message menu
148         $this->api->add_content(html::tag('li', null, 
149             $this->api->output->button(array(
150                 'command'  => 'managesieve-create',
151                 'label'    => 'managesieve.filtercreate',
152                 'type'     => 'link',
8d8f7a 153                 'classact' => 'icon filterlink active',
A 154                 'class'    => 'icon filterlink',
155                 'innerclass' => 'icon filterlink',
48e9c1 156             ))), 'messagemenu');
T 157
158         // register some labels/messages
159         $this->rc->output->add_label('managesieve.newfilter', 'managesieve.usedata',
160             'managesieve.nodata', 'managesieve.nextstep', 'save');
161
162         $this->rc->session->remove('managesieve_current');
163     }
164
165     /**
166      * Get message headers for popup window
167      */
168     function mail_headers($args)
169     {
23856c 170         // this hook can be executed many times
AM 171         if ($this->mail_headers_done) {
172             return $args;
173         }
174
175         $this->mail_headers_done = true;
176
fb5255 177         $headers = $this->parse_headers($args['headers']);
48e9c1 178
T 179         if ($this->rc->action == 'preview')
fb5255 180             $this->rc->output->command('parent.set_env', array('sieve_headers' => $headers));
48e9c1 181         else
fb5255 182             $this->rc->output->set_env('sieve_headers', $headers);
48e9c1 183
T 184         return $args;
185     }
186
187     /**
8ea08a 188      * Plugin action handler
48e9c1 189      */
T 190     function managesieve_actions()
191     {
fb5255 192         // handle fetching email headers for the new filter form
6e6f9c 193         if ($uid = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_POST)) {
AM 194             $uids    = rcmail::get_uids();
195             $mailbox = key($uids);
196             $message = new rcube_message($uids[$mailbox][0], $mailbox);
fb5255 197             $headers = $this->parse_headers($message->headers);
AM 198
199             $this->rc->output->set_env('sieve_headers', $headers);
200             $this->rc->output->command('managesieve_create', true);
201             $this->rc->output->send();
202         }
203
50a57e 204         // handle other actions
AM 205         $engine_type = $this->rc->action == 'plugin.managesieve-vacation' ? 'vacation' : '';
206         $engine      = $this->get_engine($engine_type);
207
48e9c1 208         $this->init_ui();
8ea08a 209         $engine->actions();
48e9c1 210     }
T 211
8ea08a 212     /**
AM 213      * Forms save action handler
214      */
48e9c1 215     function managesieve_save()
T 216     {
217         // load localization
218         $this->add_texts('localization/', array('filters','managefilters'));
219
220         // include main js script
221         if ($this->api->output->type == 'html') {
222             $this->include_script('managesieve.js');
223         }
224
8ea08a 225         $engine = $this->get_engine();
AM 226         $engine->save();
c6f075 227     }
AM 228
48e9c1 229     /**
8ea08a 230      * Initializes engine object
0185a2 231      */
613f96 232     public function get_engine($type = null)
0185a2 233     {
8ea08a 234         if (!$this->engine) {
AM 235             $this->load_config();
0185a2 236
8ea08a 237             // Add include path for internal classes
AM 238             $include_path = $this->home . '/lib' . PATH_SEPARATOR;
239             $include_path .= ini_get('include_path');
240             set_include_path($include_path);
48e9c1 241
9f1f75 242             $class_name = 'rcube_sieve_' . ($type ?: 'engine');
50a57e 243             $this->engine = new $class_name($this);
48e9c1 244         }
T 245
8ea08a 246         return $this->engine;
48e9c1 247     }
fb5255 248
AM 249     /**
250      * Extract mail headers for new filter form
251      */
252     private function parse_headers($headers)
253     {
254         $result = array();
255
256         if ($headers->subject)
257             $result[] = array('Subject', rcube_mime::decode_header($headers->subject));
258
259         // @TODO: List-Id, others?
260         foreach (array('From', 'To') as $h) {
261             $hl = strtolower($h);
262             if ($headers->$hl) {
263                 $list = rcube_mime::decode_address_list($headers->$hl);
264                 foreach ($list as $item) {
265                     if ($item['mailto']) {
266                         $result[] = array($h, $item['mailto']);
267                     }
268                 }
269             }
270         }
271
272         return $result;
273     }
48e9c1 274 }