Mercurial > hg > rc1
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/filters/filters.php Thu Jan 04 15:50:29 2018 -0500 @@ -0,0 +1,471 @@ +<?php + +/** + * Filters + * + * Plugin that adds a new tab to the settings section to create client-side e-mail filtering. + * + * @version 2.1.6 + * @author Roberto Zarrelli <zarrelli@unimol.it> + * @developer Artur Petrov <admin@gtn18.ru> + */ + +class filters extends rcube_plugin{ + + public $task = 'login|mail|settings'; + + private $autoAddSpamFilterRule; + private $spam_subject; + private $caseInsensitiveSearch; + private $decodeBase64Msg; + private $searchstring = array(); + private $destfolder = array(); + private $msg_uids = array(); + private $open_mbox; + + + function init(){ + + /* Filters parameters initialization. See readme.txt */ + $this->load_config(); + /* ***************************************************** */ + + $rcmail = rcmail::get_instance(); + $this->rc = &$rcmail; + + $this->autoAddSpamFilterRule = $this->rc->config->get('autoAddSpamFilterRule',TRUE); + $this->spam_subject = $this->rc->config->get('spam_subject','[SPAM]'); + $this->caseInsensitiveSearch = $this->rc->config->get('caseInsensitiveSearch',TRUE); + $this->decodeBase64Msg = $this->rc->config->get('decodeBase64Msg',FALSE); + + if($this->rc->task == 'mail' && !isset($_GET["_q"])) + $this->add_hook('messages_list', array($this, 'filters_checkmsg')); + else if ($this->rc->task == 'settings'){ + $this->register_action('plugin.filters', array($this, 'filters_init')); + $this->register_action('plugin.filters-save', array($this, 'filters_save')); + $this->register_action('plugin.filters-delete', array($this, 'filters_delete')); + $this->add_texts('localization/', array('filters','nosearchstring')); + $this->rc->output->add_label('filters'); + $this->include_script('filters.js'); + } + else if ($this->rc->task == 'login'){ + if ($this->autoAddSpamFilterRule) + $this->add_hook('login_after', array($this, 'filters_addMoveSpamRule')); + } + + } + + function filters_checkmsg($mlist){ + $user = $this->rc->user; + if (method_exists($this->rc->imap,'get_mailbox_name')) { + $imap = $this->rc->imap; + $open_mbox = $imap->get_mailbox_name(); + } + else { + $imap = $this->rc->storage; + $open_mbox = $imap->get_folder(); + } + + $this->open_mbox=$open_mbox; + + // does not consider the messages already in the trash + if ($open_mbox == $this->rc->config->get('trash_mbox')) + return; + + //load filters + $arr_prefs = $this->rc->config->get('filters', array()); + + foreach ($arr_prefs as $key => $saved_filter){ + // if saved destination folder exists and current folder is INBOX + if (method_exists($imap,'mailbox_exists')){ + if ($imap->mailbox_exists($saved_filter['destfolder']) && 'INBOX'==$open_mbox){ + $saved_filter['searchstring'] = html_entity_decode($saved_filter['searchstring']); + // if (!isset($saved_filter['filterpriority'])) $saved_filter['filterpriority'] = ''; + // destfolder#messages#filterpriority#markread + $this->searchstring[ $saved_filter['whatfilter'] ][ $saved_filter['searchstring'] ] = + $saved_filter['destfolder']."#".$saved_filter['messages']."#".$saved_filter['filterpriority']."#".$saved_filter['markread']; + } + } + if (!method_exists($imap,'mailbox_exists')){ + if ($imap->folder_exists($saved_filter['destfolder']) && 'INBOX'==$open_mbox){ + $saved_filter['searchstring'] = html_entity_decode($saved_filter['searchstring']); + // if (!isset($saved_filter['filterpriority'])) $saved_filter['filterpriority'] = ''; + // destfolder#messages#filterpriority#markread + $this->searchstring[ $saved_filter['whatfilter'] ][ $saved_filter['searchstring'] ] = + $saved_filter['destfolder']."#".$saved_filter['messages']."#".$saved_filter['filterpriority']."#".$saved_filter['markread']; + } + } + } + // if there aren't filters return + if(!count($arr_prefs) || !count($this->searchstring) || !isset($mlist['messages']) || !is_array($mlist['messages'])) + return; + + // scan the messages + foreach($mlist["messages"] as $message){ + $this->filters_search($message); + } + + // move the filtered messages + if (count($this->destfolder) > 0){ + foreach ($this->destfolder as $dfolder){ + $uids = array(); + foreach ($this->msg_uids[$dfolder] as $muids){ + $uids[] = $muids; + } + if (count($uids)){ + $imap->move_message($uids, $dfolder, $open_mbox); + // refresh + $unseen = $this->rc->storage->count($dfolder, 'UNSEEN'); + $this->api->output->command('set_unread_count',$dfolder, $unseen); + $this->api->output->command('list_mailbox'); + $this->api->output->send(); + } + } + } + + } + + + function filters_init(){ + $this->add_texts('localization/'); + $this->register_handler('plugin.body', array($this, 'filters_form')); + $this->rc->output->set_pagetitle($this->gettext('filters')); + $this->rc->output->send('plugin'); + } + + function filters_save(){ + $user = $this->rc->user; + + $this->add_texts('localization/'); + $this->register_handler('plugin.body', array($this, 'filters_form')); + $this->rc->output->set_pagetitle($this->gettext('filters')); + + $searchstring = trim(rcube_utils::get_input_value('_searchstring', RCUBE_INPUT_POST, true)); + $destfolder = trim(rcube_utils::get_input_value('_folders', RCUBE_INPUT_POST, true)); + $whatfilter = trim(rcube_utils::get_input_value('_whatfilter', RCUBE_INPUT_POST, true)); + $messages = trim(rcube_utils::get_input_value('_messages', RCUBE_INPUT_POST, true)); + $filterpriority = trim(rcube_utils::get_input_value('_checkbox', RCUBE_INPUT_POST, true)); + $markread = trim(rcube_utils::get_input_value('_markread', RCUBE_INPUT_POST, true)); + + if ($searchstring == "") + $this->rc->output->command('display_message', $this->gettext('nosearchstring'), 'error'); + else{ + $new_arr['whatfilter'] = $whatfilter; + $new_arr['searchstring'] = htmlspecialchars(addslashes($searchstring)); + $new_arr['destfolder'] = addslashes($destfolder); + $new_arr['messages'] = $messages; + $new_arr['filterpriority'] = $filterpriority; + $new_arr['markread'] = $markread; + $arr_prefs = $user->get_prefs(); + $arr_prefs['filters'][] = $new_arr; + if ($user->save_prefs($arr_prefs)) + $this->rc->output->command('display_message', $this->gettext('successfullysaved'), 'confirmation'); + else + $this->rc->output->command('display_message', $this->gettext('unsuccessfullysaved'), 'error'); + } + $this->rc->overwrite_action('plugin.filters'); + $this->rc->output->send('plugin'); + } + + function filters_delete(){ + $user = $this->rc->user; + + $this->add_texts('localization/'); + $this->register_handler('plugin.body', array($this, 'filters_form')); + $this->rc->output->set_pagetitle($this->gettext('filters')); + + if (isset($_GET[filterid])){ + $filter_id = $_GET[filterid]; + $arr_prefs = $user->get_prefs(); + $arr_prefs['filters'][$filter_id] = ''; + $arr_prefs['filters'] = array_diff($arr_prefs['filters'], array('')); + if ($user->save_prefs($arr_prefs)) + $this->rc->output->command('display_message', $this->gettext('successfullydeleted'), 'confirmation'); + else + $this->rc->output->command('display_message', $this->gettext('unsuccessfullydeleted'), 'error'); + } + + if (function_exists('rcmail::get_instance()->overwrite_action')) + rcmail::get_instance()->overwrite_action('plugin.filters'); + else $this->rc->overwrite_action('plugin.filters'); + + $this->rc->output->send('plugin'); + } + + function filters_form(){ + + if (method_exists($this->rc,'imap_connect')) $this->rc->imap_connect(); + else $this->rc->storage_connect(); + + $table = new html_table(array('cols' => 2)); + $table->add('title', rcube_utils::rep_specialchars_output($this->gettext('whatfilter').":", 'html')); + + $select = new html_select(array('name' => '_whatfilter', 'id' => 'whatfilter')); + $select->add($this->gettext('from'), 'from'); + $select->add($this->gettext('to'), 'to'); + $select->add($this->gettext('cc'), 'cc'); + $select->add($this->gettext('subject'), 'subject'); + $table->add('', $select->show($this->gettext('from'))); + + $table->add('title', rcube_utils::rep_specialchars_output($this->gettext('searchstring').":"), 'html'); + $inputfield = new html_inputfield(array('name' => '_searchstring', 'id' => 'searchstring')); + $table->add('', $inputfield->show("")); + + $table->add('title', rcube_utils::rep_specialchars_output($this->gettext('moveto').":")); + if (function_exists('rcmail::get_instance()->folder_selector')) + $select = rcmail::get_instance()->folder_selector(array('name' => '_folders', 'id' => 'folders')); + else $select = $this->rc->folder_selector(array('name' => '_folders', 'id' => 'folders')); + $table->add('title', $select->show()); + + # new option: all, read and unread messages + $table->add('title', rcube_utils::rep_specialchars_output($this->gettext('messagecount').":"), 'html'); + $select = new html_select(array('name' => '_messages', 'id' => 'messages')); + $select->add($this->gettext('all'), 'all'); + $select->add($this->gettext('unread'), 'unread'); + $select->add($this->gettext('isread'), 'isread'); + $table->add('', $select->show($this->gettext('all'))); + + # new option: markread or markunread messages + $table->add('title', rcube_utils::rep_specialchars_output($this->gettext('markmessages').":"), 'html'); + $select = new html_select(array('name' => '_markread', 'id' => 'markread')); + $select->add($this->gettext('none'), 'none'); + $select->add($this->gettext('markunread'), 'markunread'); + $select->add($this->gettext('markread'), 'markread'); + $table->add('', $select->show($this->gettext('none'))); + + # new option: filter priority, "on" as enable and "" as disable + $table->add('title', rcube_utils::rep_specialchars_output($this->gettext('filterpriority').":"), 'html'); + $checkbox = new html_checkbox(array('name' => '_checkbox', 'id' => 'checkbox')); + $table->add('', $checkbox->show("0")); + + // load saved filters + $user = $this->rc->user; + $arr_prefs = $user->get_prefs(); + $i = 1; + $flag=false; + $table2 = new html_table(array('cols' => 2)); + foreach ($arr_prefs['filters'] as $key => $saved_filter){ + $flag=true; + if (empty($saved_filter['markread'])) $saved_filter['markread'] = 'none'; + $folder_id = $saved_filter['destfolder']; + if (function_exists('rcmail::get_instance()->localize_folderpath')) + $folder_name = rcmail::get_instance()->localize_folderpath($folder_id); + else $folder_name = $this->rc->localize_folderpath($folder_id); + + $messages = $saved_filter['messages']; + + $msg = $i." - ".$this->gettext('msg_if_field')." <b>".$this->gettext($saved_filter['whatfilter'])."</b> ".$this->gettext('msg_contains'). + " <b>".stripslashes($saved_filter['searchstring'])."</b> ". + $this->gettext('msg_move_msg_in')." <b>".$folder_name."</b> ". + "(".$this->gettext('messagecount').": ".$this->gettext($saved_filter['messages']). + ", ".$this->gettext('mark').": ".$this->gettext($saved_filter['markread']).")"; + if ( !empty($saved_filter['filterpriority'])) + $msg = "<font color='green'>".$msg."</font>"; + + $table2->add('title',$msg); + $dlink = "<a href='./?_task=settings&_action=plugin.filters-delete&filterid=".$key."'>".$this->gettext('delete')."</a>"; + $table2->add('title',$dlink); + $i++; + } + + if (!$flag){ + $table2->add('title',rcube_utils::rep_specialchars_output($this->gettext('msg_no_stored_filters'), 'html')); + } + + $out = html::div(array('class' => 'box'), + html::div(array('id' => 'prefs-title', 'class' => 'boxtitle'), $this->gettext('filters')) . + html::div(array('class' => 'boxcontent'), $table->show() . + html::p(null, + $this->rc->output->button(array( + 'command' => 'plugin.filters-save', + 'type' => 'input', + 'class' => 'button mainaction', + 'label' => 'save' + ))))); + $out.= html::div(array('id' => 'prefs-title','class' => 'boxtitle'), $this->gettext('storedfilters')). html::div(array('class' => 'uibox listbox scroller','style'=>'margin-top:250px;'), + html::div(array('class' => 'boxcontent'), $table2->show() )); + + $this->rc->output->add_gui_object('filtersform', 'filters-form'); + + return $this->rc->output->form_tag(array( + 'id' => 'filters-form', + 'name' => 'filters-form', + 'method' => 'post', + 'class' => 'propform', + 'action' => './?_task=settings&_action=plugin.filters-save', + ), $out); + + } + + function filters_search($message){ + // check if a message has been read + if (isset($message->flags['SEEN']) && $message->flags['SEEN']) + $msg_read = 1; + $headers = array('from','to','cc','subject'); + $destination_folder = ''; + $filter_flag = ''; + $mark_flag = ''; + foreach($headers as $whatfilter){ + if (isset($this->searchstring[$whatfilter])){ + foreach ($this->searchstring[$whatfilter] as $from => $dest){ + $arr = explode("#",$dest); + $destination = $arr[0]; + $msg_filter = $arr[1]; + $filterpriority = $arr[2]; + $markread = $arr[3]; + + switch ($whatfilter){ + case 'from': + $field = $message->from; + break; + case 'to': + $field = $message->to; + break; + case 'cc': + $field = $message->cc; + break; + case 'subject': + $field = $message->subject; + break; + default: + $field = ""; + } + + if ($this->filters_searchString($field, $from) != false && $destination!=$this->open_mbox){ + if (!empty($filterpriority)){ + $destination_folder = $destination; + $filter_flag = $msg_filter; + $mark_flag = $markread; + break 2; + } + if (empty($destination_folder)){ + $destination_folder = $destination; + $filter_flag = $msg_filter; + $mark_flag = $markread; + } + } + } + } + } + if (!empty($destination_folder)){ + // if message as read and need unread message, then exit from function + // Если сообщение как прочитанное и нужно непрочитанное сообщение, то выход из функции + if (!empty($msg_read) && $filter_flag == "unread") return; + // if message as unread and need read message, then exit from function + // Если сообщение как непрочитанное и нужно прочитанное сообщение, то выход из функции + if (empty($msg_read) && $filter_flag == "isread") return; + $this->msg_uids[$destination_folder][] = $message->uid; + if (!in_array($destination_folder, $this->destfolder)) $this->destfolder[] = $destination_folder; + // Mark message as read if need mark message as read + // Отметить сообщение как прочитанное + if ($mark_flag == "markread") $this->filters_markread($message); + // Mark message as unread if need mark message as unread + // Отметить сообщение как непрочитанное + if ($mark_flag == "markunread") $this->filters_markread($message,'UNSEEN'); + } +} + // Mark message as read (SEEN) or as unread (UNSEEN) + function filters_markread($message,$markread='SEEN'){ + $storage = $this->rc->storage; + $storage->set_flag($message->uid, $markread, NULL); + } + + function filters_searchString($msg,$stringToSearch){ + $ret = FALSE; + + $ciSearch = $this->caseInsensitiveSearch; + $decode_msg = rcube_mime::decode_header((string)$msg); + + $stringToSearch=stripslashes($stringToSearch); + + $decode_msg = addslashes($decode_msg); + $stringToSearch = addslashes($stringToSearch); + + if ($ciSearch){ + if (function_exists('mb_stripos')){ + $tmp = mb_stripos($decode_msg, $stringToSearch); + } + else{ + $tmp = stripos($decode_msg, $stringToSearch); + } + } + else{ + if (function_exists('mb_strpos')){ + $tmp = mb_strpos($decode_msg, $stringToSearch); + } + else{ + $tmp = strpos($decode_msg, $stringToSearch); + } + } + + if ($tmp !== FALSE){ + $ret = TRUE; + } + + else{ + if ($this->decodeBase64Msg === TRUE){ + // decode and search BASE64 msg + $decode_msg = rcube_mime::decode_header(base64_decode($msg)); + + if ($decode_msg !== FALSE){ + + if ($ciSearch){ + if (function_exists('mb_stripos')){ + $tmp = mb_stripos($decode_msg, $stringToSearch); + } + else{ + $tmp = stripos($decode_msg, $stringToSearch); + } + } + else{ + if (function_exists('mb_strpos')){ + $tmp = mb_strpos($decode_msg, $stringToSearch); + } + else{ + $tmp = strpos($decode_msg, $stringToSearch); + } + } + if ($tmp !== FALSE){ + $ret = TRUE; + } + } + } + } + + return $ret; + } + + + function filters_addMoveSpamRule(){ + + $user = $this->rc->user; + + $searchstring = $this->spam_subject; + $destfolder = $this->rc->config->get('junk_mbox', null); + $whatfilter = "subject"; + $messages = "all"; + + //load filters + $arr_prefs = $this->rc->config->get('filters', array()); + + // check if the rule is already enabled + $found = false; + foreach ($arr_prefs as $key => $saved_filter){ + if ($saved_filter['searchstring'] == $searchstring && $saved_filter['whatfilter'] == $whatfilter){ + $found = true; + } + } + + if (!$found && $destfolder !== null && $destfolder !== ""){ + $new_arr['whatfilter'] = $whatfilter; + $new_arr['searchstring'] = $searchstring; + $new_arr['destfolder'] = $destfolder; + $new_arr['messages'] = $messages; + $arr_prefs = $user->get_prefs(); + $arr_prefs['filters'][] = $new_arr; + $user->save_prefs($arr_prefs); + } + } + +} +?>