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 ?> |
