Mercurial > hg > rc1
comparison plugins/filters/filters.php @ 0:1e000243b222
vanilla 1.3.3 distro, I hope
author | Charlie Root |
---|---|
date | Thu, 04 Jan 2018 15:50:29 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1e000243b222 |
---|---|
1 <?php | |
2 | |
3 /** | |
4 * Filters | |
5 * | |
6 * Plugin that adds a new tab to the settings section to create client-side e-mail filtering. | |
7 * | |
8 * @version 2.1.6 | |
9 * @author Roberto Zarrelli <zarrelli@unimol.it> | |
10 * @developer Artur Petrov <admin@gtn18.ru> | |
11 */ | |
12 | |
13 class filters extends rcube_plugin{ | |
14 | |
15 public $task = 'login|mail|settings'; | |
16 | |
17 private $autoAddSpamFilterRule; | |
18 private $spam_subject; | |
19 private $caseInsensitiveSearch; | |
20 private $decodeBase64Msg; | |
21 private $searchstring = array(); | |
22 private $destfolder = array(); | |
23 private $msg_uids = array(); | |
24 private $open_mbox; | |
25 | |
26 | |
27 function init(){ | |
28 | |
29 /* Filters parameters initialization. See readme.txt */ | |
30 $this->load_config(); | |
31 /* ***************************************************** */ | |
32 | |
33 $rcmail = rcmail::get_instance(); | |
34 $this->rc = &$rcmail; | |
35 | |
36 $this->autoAddSpamFilterRule = $this->rc->config->get('autoAddSpamFilterRule',TRUE); | |
37 $this->spam_subject = $this->rc->config->get('spam_subject','[SPAM]'); | |
38 $this->caseInsensitiveSearch = $this->rc->config->get('caseInsensitiveSearch',TRUE); | |
39 $this->decodeBase64Msg = $this->rc->config->get('decodeBase64Msg',FALSE); | |
40 | |
41 if($this->rc->task == 'mail' && !isset($_GET["_q"])) | |
42 $this->add_hook('messages_list', array($this, 'filters_checkmsg')); | |
43 else if ($this->rc->task == 'settings'){ | |
44 $this->register_action('plugin.filters', array($this, 'filters_init')); | |
45 $this->register_action('plugin.filters-save', array($this, 'filters_save')); | |
46 $this->register_action('plugin.filters-delete', array($this, 'filters_delete')); | |
47 $this->add_texts('localization/', array('filters','nosearchstring')); | |
48 $this->rc->output->add_label('filters'); | |
49 $this->include_script('filters.js'); | |
50 } | |
51 else if ($this->rc->task == 'login'){ | |
52 if ($this->autoAddSpamFilterRule) | |
53 $this->add_hook('login_after', array($this, 'filters_addMoveSpamRule')); | |
54 } | |
55 | |
56 } | |
57 | |
58 function filters_checkmsg($mlist){ | |
59 $user = $this->rc->user; | |
60 if (method_exists($this->rc->imap,'get_mailbox_name')) { | |
61 $imap = $this->rc->imap; | |
62 $open_mbox = $imap->get_mailbox_name(); | |
63 } | |
64 else { | |
65 $imap = $this->rc->storage; | |
66 $open_mbox = $imap->get_folder(); | |
67 } | |
68 | |
69 $this->open_mbox=$open_mbox; | |
70 | |
71 // does not consider the messages already in the trash | |
72 if ($open_mbox == $this->rc->config->get('trash_mbox')) | |
73 return; | |
74 | |
75 //load filters | |
76 $arr_prefs = $this->rc->config->get('filters', array()); | |
77 | |
78 foreach ($arr_prefs as $key => $saved_filter){ | |
79 // if saved destination folder exists and current folder is INBOX | |
80 if (method_exists($imap,'mailbox_exists')){ | |
81 if ($imap->mailbox_exists($saved_filter['destfolder']) && 'INBOX'==$open_mbox){ | |
82 $saved_filter['searchstring'] = html_entity_decode($saved_filter['searchstring']); | |
83 // if (!isset($saved_filter['filterpriority'])) $saved_filter['filterpriority'] = ''; | |
84 // destfolder#messages#filterpriority#markread | |
85 $this->searchstring[ $saved_filter['whatfilter'] ][ $saved_filter['searchstring'] ] = | |
86 $saved_filter['destfolder']."#".$saved_filter['messages']."#".$saved_filter['filterpriority']."#".$saved_filter['markread']; | |
87 } | |
88 } | |
89 if (!method_exists($imap,'mailbox_exists')){ | |
90 if ($imap->folder_exists($saved_filter['destfolder']) && 'INBOX'==$open_mbox){ | |
91 $saved_filter['searchstring'] = html_entity_decode($saved_filter['searchstring']); | |
92 // if (!isset($saved_filter['filterpriority'])) $saved_filter['filterpriority'] = ''; | |
93 // destfolder#messages#filterpriority#markread | |
94 $this->searchstring[ $saved_filter['whatfilter'] ][ $saved_filter['searchstring'] ] = | |
95 $saved_filter['destfolder']."#".$saved_filter['messages']."#".$saved_filter['filterpriority']."#".$saved_filter['markread']; | |
96 } | |
97 } | |
98 } | |
99 // if there aren't filters return | |
100 if(!count($arr_prefs) || !count($this->searchstring) || !isset($mlist['messages']) || !is_array($mlist['messages'])) | |
101 return; | |
102 | |
103 // scan the messages | |
104 foreach($mlist["messages"] as $message){ | |
105 $this->filters_search($message); | |
106 } | |
107 | |
108 // move the filtered messages | |
109 if (count($this->destfolder) > 0){ | |
110 foreach ($this->destfolder as $dfolder){ | |
111 $uids = array(); | |
112 foreach ($this->msg_uids[$dfolder] as $muids){ | |
113 $uids[] = $muids; | |
114 } | |
115 if (count($uids)){ | |
116 $imap->move_message($uids, $dfolder, $open_mbox); | |
117 // refresh | |
118 $unseen = $this->rc->storage->count($dfolder, 'UNSEEN'); | |
119 $this->api->output->command('set_unread_count',$dfolder, $unseen); | |
120 $this->api->output->command('list_mailbox'); | |
121 $this->api->output->send(); | |
122 } | |
123 } | |
124 } | |
125 | |
126 } | |
127 | |
128 | |
129 function filters_init(){ | |
130 $this->add_texts('localization/'); | |
131 $this->register_handler('plugin.body', array($this, 'filters_form')); | |
132 $this->rc->output->set_pagetitle($this->gettext('filters')); | |
133 $this->rc->output->send('plugin'); | |
134 } | |
135 | |
136 function filters_save(){ | |
137 $user = $this->rc->user; | |
138 | |
139 $this->add_texts('localization/'); | |
140 $this->register_handler('plugin.body', array($this, 'filters_form')); | |
141 $this->rc->output->set_pagetitle($this->gettext('filters')); | |
142 | |
143 $searchstring = trim(rcube_utils::get_input_value('_searchstring', RCUBE_INPUT_POST, true)); | |
144 $destfolder = trim(rcube_utils::get_input_value('_folders', RCUBE_INPUT_POST, true)); | |
145 $whatfilter = trim(rcube_utils::get_input_value('_whatfilter', RCUBE_INPUT_POST, true)); | |
146 $messages = trim(rcube_utils::get_input_value('_messages', RCUBE_INPUT_POST, true)); | |
147 $filterpriority = trim(rcube_utils::get_input_value('_checkbox', RCUBE_INPUT_POST, true)); | |
148 $markread = trim(rcube_utils::get_input_value('_markread', RCUBE_INPUT_POST, true)); | |
149 | |
150 if ($searchstring == "") | |
151 $this->rc->output->command('display_message', $this->gettext('nosearchstring'), 'error'); | |
152 else{ | |
153 $new_arr['whatfilter'] = $whatfilter; | |
154 $new_arr['searchstring'] = htmlspecialchars(addslashes($searchstring)); | |
155 $new_arr['destfolder'] = addslashes($destfolder); | |
156 $new_arr['messages'] = $messages; | |
157 $new_arr['filterpriority'] = $filterpriority; | |
158 $new_arr['markread'] = $markread; | |
159 $arr_prefs = $user->get_prefs(); | |
160 $arr_prefs['filters'][] = $new_arr; | |
161 if ($user->save_prefs($arr_prefs)) | |
162 $this->rc->output->command('display_message', $this->gettext('successfullysaved'), 'confirmation'); | |
163 else | |
164 $this->rc->output->command('display_message', $this->gettext('unsuccessfullysaved'), 'error'); | |
165 } | |
166 $this->rc->overwrite_action('plugin.filters'); | |
167 $this->rc->output->send('plugin'); | |
168 } | |
169 | |
170 function filters_delete(){ | |
171 $user = $this->rc->user; | |
172 | |
173 $this->add_texts('localization/'); | |
174 $this->register_handler('plugin.body', array($this, 'filters_form')); | |
175 $this->rc->output->set_pagetitle($this->gettext('filters')); | |
176 | |
177 if (isset($_GET[filterid])){ | |
178 $filter_id = $_GET[filterid]; | |
179 $arr_prefs = $user->get_prefs(); | |
180 $arr_prefs['filters'][$filter_id] = ''; | |
181 $arr_prefs['filters'] = array_diff($arr_prefs['filters'], array('')); | |
182 if ($user->save_prefs($arr_prefs)) | |
183 $this->rc->output->command('display_message', $this->gettext('successfullydeleted'), 'confirmation'); | |
184 else | |
185 $this->rc->output->command('display_message', $this->gettext('unsuccessfullydeleted'), 'error'); | |
186 } | |
187 | |
188 if (function_exists('rcmail::get_instance()->overwrite_action')) | |
189 rcmail::get_instance()->overwrite_action('plugin.filters'); | |
190 else $this->rc->overwrite_action('plugin.filters'); | |
191 | |
192 $this->rc->output->send('plugin'); | |
193 } | |
194 | |
195 function filters_form(){ | |
196 | |
197 if (method_exists($this->rc,'imap_connect')) $this->rc->imap_connect(); | |
198 else $this->rc->storage_connect(); | |
199 | |
200 $table = new html_table(array('cols' => 2)); | |
201 $table->add('title', rcube_utils::rep_specialchars_output($this->gettext('whatfilter').":", 'html')); | |
202 | |
203 $select = new html_select(array('name' => '_whatfilter', 'id' => 'whatfilter')); | |
204 $select->add($this->gettext('from'), 'from'); | |
205 $select->add($this->gettext('to'), 'to'); | |
206 $select->add($this->gettext('cc'), 'cc'); | |
207 $select->add($this->gettext('subject'), 'subject'); | |
208 $table->add('', $select->show($this->gettext('from'))); | |
209 | |
210 $table->add('title', rcube_utils::rep_specialchars_output($this->gettext('searchstring').":"), 'html'); | |
211 $inputfield = new html_inputfield(array('name' => '_searchstring', 'id' => 'searchstring')); | |
212 $table->add('', $inputfield->show("")); | |
213 | |
214 $table->add('title', rcube_utils::rep_specialchars_output($this->gettext('moveto').":")); | |
215 if (function_exists('rcmail::get_instance()->folder_selector')) | |
216 $select = rcmail::get_instance()->folder_selector(array('name' => '_folders', 'id' => 'folders')); | |
217 else $select = $this->rc->folder_selector(array('name' => '_folders', 'id' => 'folders')); | |
218 $table->add('title', $select->show()); | |
219 | |
220 # new option: all, read and unread messages | |
221 $table->add('title', rcube_utils::rep_specialchars_output($this->gettext('messagecount').":"), 'html'); | |
222 $select = new html_select(array('name' => '_messages', 'id' => 'messages')); | |
223 $select->add($this->gettext('all'), 'all'); | |
224 $select->add($this->gettext('unread'), 'unread'); | |
225 $select->add($this->gettext('isread'), 'isread'); | |
226 $table->add('', $select->show($this->gettext('all'))); | |
227 | |
228 # new option: markread or markunread messages | |
229 $table->add('title', rcube_utils::rep_specialchars_output($this->gettext('markmessages').":"), 'html'); | |
230 $select = new html_select(array('name' => '_markread', 'id' => 'markread')); | |
231 $select->add($this->gettext('none'), 'none'); | |
232 $select->add($this->gettext('markunread'), 'markunread'); | |
233 $select->add($this->gettext('markread'), 'markread'); | |
234 $table->add('', $select->show($this->gettext('none'))); | |
235 | |
236 # new option: filter priority, "on" as enable and "" as disable | |
237 $table->add('title', rcube_utils::rep_specialchars_output($this->gettext('filterpriority').":"), 'html'); | |
238 $checkbox = new html_checkbox(array('name' => '_checkbox', 'id' => 'checkbox')); | |
239 $table->add('', $checkbox->show("0")); | |
240 | |
241 // load saved filters | |
242 $user = $this->rc->user; | |
243 $arr_prefs = $user->get_prefs(); | |
244 $i = 1; | |
245 $flag=false; | |
246 $table2 = new html_table(array('cols' => 2)); | |
247 foreach ($arr_prefs['filters'] as $key => $saved_filter){ | |
248 $flag=true; | |
249 if (empty($saved_filter['markread'])) $saved_filter['markread'] = 'none'; | |
250 $folder_id = $saved_filter['destfolder']; | |
251 if (function_exists('rcmail::get_instance()->localize_folderpath')) | |
252 $folder_name = rcmail::get_instance()->localize_folderpath($folder_id); | |
253 else $folder_name = $this->rc->localize_folderpath($folder_id); | |
254 | |
255 $messages = $saved_filter['messages']; | |
256 | |
257 $msg = $i." - ".$this->gettext('msg_if_field')." <b>".$this->gettext($saved_filter['whatfilter'])."</b> ".$this->gettext('msg_contains'). | |
258 " <b>".stripslashes($saved_filter['searchstring'])."</b> ". | |
259 $this->gettext('msg_move_msg_in')." <b>".$folder_name."</b> ". | |
260 "(".$this->gettext('messagecount').": ".$this->gettext($saved_filter['messages']). | |
261 ", ".$this->gettext('mark').": ".$this->gettext($saved_filter['markread']).")"; | |
262 if ( !empty($saved_filter['filterpriority'])) | |
263 $msg = "<font color='green'>".$msg."</font>"; | |
264 | |
265 $table2->add('title',$msg); | |
266 $dlink = "<a href='./?_task=settings&_action=plugin.filters-delete&filterid=".$key."'>".$this->gettext('delete')."</a>"; | |
267 $table2->add('title',$dlink); | |
268 $i++; | |
269 } | |
270 | |
271 if (!$flag){ | |
272 $table2->add('title',rcube_utils::rep_specialchars_output($this->gettext('msg_no_stored_filters'), 'html')); | |
273 } | |
274 | |
275 $out = html::div(array('class' => 'box'), | |
276 html::div(array('id' => 'prefs-title', 'class' => 'boxtitle'), $this->gettext('filters')) . | |
277 html::div(array('class' => 'boxcontent'), $table->show() . | |
278 html::p(null, | |
279 $this->rc->output->button(array( | |
280 'command' => 'plugin.filters-save', | |
281 'type' => 'input', | |
282 'class' => 'button mainaction', | |
283 'label' => 'save' | |
284 ))))); | |
285 $out.= html::div(array('id' => 'prefs-title','class' => 'boxtitle'), $this->gettext('storedfilters')). html::div(array('class' => 'uibox listbox scroller','style'=>'margin-top:250px;'), | |
286 html::div(array('class' => 'boxcontent'), $table2->show() )); | |
287 | |
288 $this->rc->output->add_gui_object('filtersform', 'filters-form'); | |
289 | |
290 return $this->rc->output->form_tag(array( | |
291 'id' => 'filters-form', | |
292 'name' => 'filters-form', | |
293 'method' => 'post', | |
294 'class' => 'propform', | |
295 'action' => './?_task=settings&_action=plugin.filters-save', | |
296 ), $out); | |
297 | |
298 } | |
299 | |
300 function filters_search($message){ | |
301 // check if a message has been read | |
302 if (isset($message->flags['SEEN']) && $message->flags['SEEN']) | |
303 $msg_read = 1; | |
304 $headers = array('from','to','cc','subject'); | |
305 $destination_folder = ''; | |
306 $filter_flag = ''; | |
307 $mark_flag = ''; | |
308 foreach($headers as $whatfilter){ | |
309 if (isset($this->searchstring[$whatfilter])){ | |
310 foreach ($this->searchstring[$whatfilter] as $from => $dest){ | |
311 $arr = explode("#",$dest); | |
312 $destination = $arr[0]; | |
313 $msg_filter = $arr[1]; | |
314 $filterpriority = $arr[2]; | |
315 $markread = $arr[3]; | |
316 | |
317 switch ($whatfilter){ | |
318 case 'from': | |
319 $field = $message->from; | |
320 break; | |
321 case 'to': | |
322 $field = $message->to; | |
323 break; | |
324 case 'cc': | |
325 $field = $message->cc; | |
326 break; | |
327 case 'subject': | |
328 $field = $message->subject; | |
329 break; | |
330 default: | |
331 $field = ""; | |
332 } | |
333 | |
334 if ($this->filters_searchString($field, $from) != false && $destination!=$this->open_mbox){ | |
335 if (!empty($filterpriority)){ | |
336 $destination_folder = $destination; | |
337 $filter_flag = $msg_filter; | |
338 $mark_flag = $markread; | |
339 break 2; | |
340 } | |
341 if (empty($destination_folder)){ | |
342 $destination_folder = $destination; | |
343 $filter_flag = $msg_filter; | |
344 $mark_flag = $markread; | |
345 } | |
346 } | |
347 } | |
348 } | |
349 } | |
350 if (!empty($destination_folder)){ | |
351 // if message as read and need unread message, then exit from function | |
352 // Если сообщение как прочитанное и нужно непрочитанное сообщение, то выход из функции | |
353 if (!empty($msg_read) && $filter_flag == "unread") return; | |
354 // if message as unread and need read message, then exit from function | |
355 // Если сообщение как непрочитанное и нужно прочитанное сообщение, то выход из функции | |
356 if (empty($msg_read) && $filter_flag == "isread") return; | |
357 $this->msg_uids[$destination_folder][] = $message->uid; | |
358 if (!in_array($destination_folder, $this->destfolder)) $this->destfolder[] = $destination_folder; | |
359 // Mark message as read if need mark message as read | |
360 // Отметить сообщение как прочитанное | |
361 if ($mark_flag == "markread") $this->filters_markread($message); | |
362 // Mark message as unread if need mark message as unread | |
363 // Отметить сообщение как непрочитанное | |
364 if ($mark_flag == "markunread") $this->filters_markread($message,'UNSEEN'); | |
365 } | |
366 } | |
367 // Mark message as read (SEEN) or as unread (UNSEEN) | |
368 function filters_markread($message,$markread='SEEN'){ | |
369 $storage = $this->rc->storage; | |
370 $storage->set_flag($message->uid, $markread, NULL); | |
371 } | |
372 | |
373 function filters_searchString($msg,$stringToSearch){ | |
374 $ret = FALSE; | |
375 | |
376 $ciSearch = $this->caseInsensitiveSearch; | |
377 $decode_msg = rcube_mime::decode_header((string)$msg); | |
378 | |
379 $stringToSearch=stripslashes($stringToSearch); | |
380 | |
381 $decode_msg = addslashes($decode_msg); | |
382 $stringToSearch = addslashes($stringToSearch); | |
383 | |
384 if ($ciSearch){ | |
385 if (function_exists('mb_stripos')){ | |
386 $tmp = mb_stripos($decode_msg, $stringToSearch); | |
387 } | |
388 else{ | |
389 $tmp = stripos($decode_msg, $stringToSearch); | |
390 } | |
391 } | |
392 else{ | |
393 if (function_exists('mb_strpos')){ | |
394 $tmp = mb_strpos($decode_msg, $stringToSearch); | |
395 } | |
396 else{ | |
397 $tmp = strpos($decode_msg, $stringToSearch); | |
398 } | |
399 } | |
400 | |
401 if ($tmp !== FALSE){ | |
402 $ret = TRUE; | |
403 } | |
404 | |
405 else{ | |
406 if ($this->decodeBase64Msg === TRUE){ | |
407 // decode and search BASE64 msg | |
408 $decode_msg = rcube_mime::decode_header(base64_decode($msg)); | |
409 | |
410 if ($decode_msg !== FALSE){ | |
411 | |
412 if ($ciSearch){ | |
413 if (function_exists('mb_stripos')){ | |
414 $tmp = mb_stripos($decode_msg, $stringToSearch); | |
415 } | |
416 else{ | |
417 $tmp = stripos($decode_msg, $stringToSearch); | |
418 } | |
419 } | |
420 else{ | |
421 if (function_exists('mb_strpos')){ | |
422 $tmp = mb_strpos($decode_msg, $stringToSearch); | |
423 } | |
424 else{ | |
425 $tmp = strpos($decode_msg, $stringToSearch); | |
426 } | |
427 } | |
428 if ($tmp !== FALSE){ | |
429 $ret = TRUE; | |
430 } | |
431 } | |
432 } | |
433 } | |
434 | |
435 return $ret; | |
436 } | |
437 | |
438 | |
439 function filters_addMoveSpamRule(){ | |
440 | |
441 $user = $this->rc->user; | |
442 | |
443 $searchstring = $this->spam_subject; | |
444 $destfolder = $this->rc->config->get('junk_mbox', null); | |
445 $whatfilter = "subject"; | |
446 $messages = "all"; | |
447 | |
448 //load filters | |
449 $arr_prefs = $this->rc->config->get('filters', array()); | |
450 | |
451 // check if the rule is already enabled | |
452 $found = false; | |
453 foreach ($arr_prefs as $key => $saved_filter){ | |
454 if ($saved_filter['searchstring'] == $searchstring && $saved_filter['whatfilter'] == $whatfilter){ | |
455 $found = true; | |
456 } | |
457 } | |
458 | |
459 if (!$found && $destfolder !== null && $destfolder !== ""){ | |
460 $new_arr['whatfilter'] = $whatfilter; | |
461 $new_arr['searchstring'] = $searchstring; | |
462 $new_arr['destfolder'] = $destfolder; | |
463 $new_arr['messages'] = $messages; | |
464 $arr_prefs = $user->get_prefs(); | |
465 $arr_prefs['filters'][] = $new_arr; | |
466 $user->save_prefs($arr_prefs); | |
467 } | |
468 } | |
469 | |
470 } | |
471 ?> |