diff --git a/include/class.banlist.php b/include/class.banlist.php index 27729b44a42f45cb0d187f1e8f2a8b731991784e..c620b105033fbc1275b6f0cb82ee69bb2c5306d3 100644 --- a/include/class.banlist.php +++ b/include/class.banlist.php @@ -27,7 +27,7 @@ class Banlist { } function isbanned($email) { - return EmailFilter::isBanned($email); + return TicketFilter::isBanned($email); } function includes($email) { @@ -50,7 +50,7 @@ class Banlist { 'name' => 'SYSTEM BAN LIST', 'isactive' => 1, 'match_all_rules' => false, - 'reject_email' => true, + 'reject_ticket' => true, 'rules' => array(), 'notes' => 'Internal list for email banning. Do not remove' ), $errors); diff --git a/include/class.canned.php b/include/class.canned.php index b9ff6de802da17026ce4bc8206af1607e2f1593e..c84950e7d6d19b062dbb3a53c0ccfe95eab96c48 100644 --- a/include/class.canned.php +++ b/include/class.canned.php @@ -35,7 +35,7 @@ class Canned { .' count(filter.id) as filters ' .' FROM '.CANNED_TABLE.' canned ' .' LEFT JOIN '.CANNED_ATTACHMENT_TABLE.' attach ON (attach.canned_id=canned.canned_id) ' - .' LEFT JOIN '.EMAIL_FILTER_TABLE.' filter ON (canned.canned_id = filter.canned_response_id) ' + .' LEFT JOIN '.FILTER_TABLE.' filter ON (canned.canned_id = filter.canned_response_id) ' .' WHERE canned.canned_id='.db_input($id) .' GROUP BY canned.canned_id'; @@ -102,7 +102,7 @@ class Canned { if (!$this->_filters) { $this->_filters = array(); $res = db_query( - 'SELECT name FROM '.EMAIL_FILTER_TABLE + 'SELECT name FROM '.FILTER_TABLE .' WHERE canned_response_id = '.db_input($this->getId()) .' ORDER BY name'); while ($row = db_fetch_row($res)) diff --git a/include/class.filter.php b/include/class.filter.php index b6c81b42b60d0d4b8c67d3f7b33b1138695fa1e7..ce7d7d92cb273705bc458e32e6c7dd93cf8668e7 100644 --- a/include/class.filter.php +++ b/include/class.filter.php @@ -2,7 +2,7 @@ /********************************************************************* class.filter.php - Email Filter Class + Ticket Filter Peter Rotich <peter@osticket.com> Copyright (c) 2006-2012 osTicket @@ -18,7 +18,7 @@ class Filter { var $id; var $ht; - function Filter($id){ + function Filter($id) { $this->id=0; $this->load($id); } @@ -29,8 +29,8 @@ class Filter { return false; $sql='SELECT filter.*,count(rule.id) as rule_count ' - .' FROM '.EMAIL_FILTER_TABLE.' filter ' - .' LEFT JOIN '.EMAIL_FILTER_RULE_TABLE.' rule ON(rule.filter_id=filter.id) ' + .' FROM '.FILTER_TABLE.' filter ' + .' LEFT JOIN '.FILTER_RULE_TABLE.' rule ON(rule.filter_id=filter.id) ' .' WHERE filter.id='.db_input($id) .' GROUP BY filter.id'; @@ -47,27 +47,31 @@ class Filter { return $this->load($this->getId()); } - function getId(){ + function getId() { return $this->id; } - function getName(){ + function getTarget() { + return $this->ht['target']; + } + + function getName() { return $this->ht['name']; } - function getNotes(){ + function getNotes() { return $this->ht['notes']; } - function getInfo(){ + function getInfo() { return $this->ht; } - function getNumRules(){ + function getNumRules() { return $this->ht['rule_count']; } - function getExecOrder(){ + function getExecOrder() { return $this->ht['execorder']; } @@ -75,7 +79,7 @@ class Filter { return $this->ht['email_id']; } - function isActive(){ + function isActive() { return ($this->ht['isactive']); } @@ -83,23 +87,23 @@ class Filter { return !strcasecmp($this->getName(),'SYSTEM BAN LIST'); } - function getDeptId(){ + function getDeptId() { return $this->ht['dept_id']; } - function getPriorityId(){ + function getPriorityId() { return $this->ht['priority_id']; } - function getSLAId(){ + function getSLAId() { return $this->ht['sla_id']; } - function getStaffId(){ + function getStaffId() { return $this->ht['staff_id']; } - function getTeamId(){ + function getTeamId() { return $this->ht['team_id']; } @@ -107,36 +111,36 @@ class Filter { return $this->ht['canned_response_id']; } - function stopOnMatch(){ + function stopOnMatch() { return ($this->ht['stop_on_match']); } - function matchAllRules(){ + function matchAllRules() { return ($this->ht['match_all_rules']); } - function rejectEmail(){ - return ($this->ht['reject_email']); + function rejectOnMatch() { + return ($this->ht['reject_ticket']); } - function useReplyToEmail(){ + function useReplyToEmail() { return ($this->ht['use_replyto_email']); } - function disableAlerts(){ + function disableAlerts() { return ($this->ht['disable_autoresponder']); } - function sendAlerts(){ + function sendAlerts() { return (!$this->disableAlerts()); } - function getRules(){ + function getRules() { if (!$this->ht['rules']) { $rules=array(); //We're getting the rules...live because it gets cleared on update. - $sql='SELECT * FROM '.EMAIL_FILTER_RULE_TABLE.' WHERE filter_id='.db_input($this->getId()); - if(($res=db_query($sql)) && db_num_rows($res)){ + $sql='SELECT * FROM '.FILTER_RULE_TABLE.' WHERE filter_id='.db_input($this->getId()); + if(($res=db_query($sql)) && db_num_rows($res)) { while($row=db_fetch_array($res)) $rules[]=array('w'=>$row['what'],'h'=>$row['how'],'v'=>$row['val']); } @@ -145,11 +149,11 @@ class Filter { return $this->ht['rules']; } - function getFlatRules(){ //Format used on html... I'm ashamed + function getFlatRules() { //Format used on html... I'm ashamed $info=array(); - if(($rules=$this->getRules())){ - foreach($rules as $k=>$rule){ + if(($rules=$this->getRules())) { + foreach($rules as $k=>$rule) { $i=$k+1; $info["rule_w$i"]=$rule['w']; $info["rule_h$i"]=$rule['h']; @@ -169,7 +173,7 @@ class Filter { function removeRule($what, $how, $val) { - $sql='DELETE FROM '.EMAIL_FILTER_RULE_TABLE + $sql='DELETE FROM '.FILTER_RULE_TABLE .' WHERE filter_id='.db_input($this->getId()) .' AND what='.db_input($what) .' AND how='.db_input($how) @@ -187,17 +191,19 @@ class Filter { } function containsRule($what, $how, $val) { + $val = trim($val); if (isset($this->ht['rules'])) { + $match = array("w"=>$what, "h"=>$how, "v"=>$val); foreach ($this->ht['rules'] as $rule) { - if (array("w"=>$what, "h"=>$how, "v"=>$val) == $rule) { - return True; - } + if ($match == $rule) + return true; } - return False; + return false; + } else { # Fetch from database return 0 != db_count( - "SELECT COUNT(*) FROM ".EMAIL_FILTER_RULE_TABLE + "SELECT COUNT(*) FROM ".FILTER_RULE_TABLE ." WHERE filter_id=".db_input($this->id) ." AND what=".db_input($what)." AND how=".db_input($how) ." AND val=".db_input($val) @@ -208,35 +214,41 @@ class Filter { * Simple true/false if the rules defined for this filter match the * incoming email * - * $email is an ARRAY, which has valid keys - * *from - email address of sender - * name - name of sender - * subject - subject line of the email - * body - body content of the email (no attachments, please) + * $info is an ARRAY, which has valid keys + * email - FROM email address of the ticket owner + * name - name of ticket owner + * subject - subject line of the ticket + * body - body content of the message (no attachments, please) * reply-to - reply-to email address * reply-to-name - name of sender to reply-to * headers - array of email headers - * emailid - osTicket email id of recipient + * emailId - osTicket system email id */ - function matches($email) { + function matches($info) { + + if(!$info || !is_array($info)) return false; + $what = array( - "email" => $email['email'], - "subject" => $email['subject'], + 'email' => $info['email'], + 'subject' => $info['subject'], # XXX: Support reply-to too ? - "name" => $email['name'], - "body" => $email['message'] + 'name' => $info['name'], + 'body' => $info['message'] # XXX: Support headers ); $how = array( # how => array(function, null or === this, null or !== this) - "equal" => array("strcmp", 0), - "not_equal" => array("strcmp", null, 0), - "contains" => array("strpos", null, false), - "dn_contain"=> array("strpos", false) + 'equal' => array('strcmp', 0), + 'not_equal' => array('strcmp', null, 0), + 'contains' => array('strpos', null, false), + 'dn_contain'=> array('strpos', false) ); + $match = false; # Respect configured filter email-id - if ($this->getEmailId() && $this->getEmailId() != $email['emailId']) + if ($this->getEmailId() + && !strcasecmp($this->getTarget(), 'Email') + && $this->getEmailId() != $info['emailId']) return false; foreach ($this->getRules() as $rule) { @@ -265,7 +277,7 @@ class Filter { * If the matches() method returns TRUE, send the initial ticket to this * method to apply the filter actions defined */ - function apply(&$ticket, $email=null) { + function apply(&$ticket, $info=null) { # TODO: Disable alerting # XXX: Does this imply turning it on as well? (via ->sendAlerts()) if ($this->disableAlerts()) $ticket['autorespond']=false; @@ -279,22 +291,24 @@ class Filter { # XXX: Unset the other (of staffId or teamId) (?) if ($this->getStaffId()) $ticket['staffId']=$this->getStaffId(); elseif ($this->getTeamId()) $ticket['teamId']=$this->getTeamId(); - # Override name with reply-to information from the EmailFilter + # Override name with reply-to information from the TicketFilter # match - if ($this->useReplyToEmail() && $email['reply-to']) { - $ticket['email'] = $email['reply-to']; - if ($email['reply-to-name']) - $ticket['name'] = $email['reply-to-name']; + if ($this->useReplyToEmail() && $info['reply-to']) { + $ticket['email'] = $info['reply-to']; + if ($info['reply-to-name']) + $ticket['name'] = $info['reply-to-name']; } + + # Use canned response. if ($this->getCannedResponse()) $ticket['cannedResponseId'] = $this->getCannedResponse(); } /* static */ function getSupportedMatches() { return array( - 'name'=> "Sender's Name", - 'email'=> "Sender's Email", - 'subject'=> 'Email Subject', - 'body'=> 'Email Body/Text' + 'name'=> 'Name', + 'email'=> 'Email', + 'subject'=> 'Subject', + 'body'=> 'Body/Text' ); } /* static */ function getSupportedMatchTypes() { @@ -306,7 +320,7 @@ class Filter { ); } - function update($vars,&$errors){ + function update($vars,&$errors) { if(!Filter::save($this->getId(),$vars,$errors)) return false; @@ -316,47 +330,55 @@ class Filter { return true; } - function delete(){ + function delete() { $id=$this->getId(); - $sql='DELETE FROM '.EMAIL_FILTER_TABLE.' WHERE id='.db_input($id).' LIMIT 1'; - if(db_query($sql) && ($num=db_affected_rows())){ - db_query('DELETE FROM '.EMAIL_FILTER_RULE_TABLE.' WHERE filter_id='.db_input($id)); + $sql='DELETE FROM '.FILTER_TABLE.' WHERE id='.db_input($id).' LIMIT 1'; + if(db_query($sql) && ($num=db_affected_rows())) { + db_query('DELETE FROM '.FILTER_RULE_TABLE.' WHERE filter_id='.db_input($id)); } return $num; } /** static functions **/ - function create($vars,&$errors){ + function getTargets() { + return array( + 'Any' => 'Any', + 'Web' => 'Web Forms', + 'API' => 'API Calls', + 'Email' => 'Emails'); + } + + function create($vars,&$errors) { return Filter::save(0,$vars,$errors); } - function getIdByName($name){ + function getIdByName($name) { - $sql='SELECT id FROM '.EMAIL_FILTER_TABLE.' WHERE name='.db_input($name); + $sql='SELECT id FROM '.FILTER_TABLE.' WHERE name='.db_input($name); if(($res=db_query($sql)) && db_num_rows($res)) list($id)=db_fetch_row($res); return $id; } - function lookup($id){ + function lookup($id) { return ($id && is_numeric($id) && ($f= new Filter($id)) && $f->getId()==$id)?$f:null; } - function validate_rules($vars,&$errors){ + function validate_rules($vars,&$errors) { return self::save_rules(0,$vars,$errors); } - function save_rules($id,$vars,&$errors){ + function save_rules($id,$vars,&$errors) { $matches=array('name','email','subject','body','header'); $types=array('equal','not_equal','contains','dn_contain'); $rules=array(); for($i=1; $i<=25; $i++) { //Expecting no more than 25 rules... - if($vars["rule_w$i"] || $vars["rule_h$i"]){ + if($vars["rule_w$i"] || $vars["rule_h$i"]) { if(!$vars["rule_w$i"] || !in_array($vars["rule_w$i"],$matches)) $errors["rule_$i"]='Invalid match selection'; elseif(!$vars["rule_h$i"] || !in_array($vars["rule_h$i"],$types)) @@ -367,7 +389,7 @@ class Filter { $errors["rule_$i"]='Valid email required for the match type'; else //for everything-else...we assume it's valid. $rules[]=array('w'=>$vars["rule_w$i"],'h'=>$vars["rule_h$i"],'v'=>$vars["rule_v$i"]); - }elseif($vars["rule_v$i"]){ + }elseif($vars["rule_v$i"]) { $errors["rule_$i"]='Incomplete selection'; } } @@ -383,7 +405,7 @@ class Filter { if(!$id) return true; //When ID is 0 then assume it was just validation... //Clear existing rules...we're doing mass replace on each save!! - db_query('DELETE FROM '.EMAIL_FILTER_RULE_TABLE.' WHERE filter_id='.db_input($id)); + db_query('DELETE FROM '.FILTER_RULE_TABLE.' WHERE filter_id='.db_input($id)); $num=0; foreach($rules as $rule) { $rule['filter_id']=$id; @@ -394,39 +416,52 @@ class Filter { return $num; } - function save($id,$vars,&$errors){ + function save($id,$vars,&$errors) { if(!$vars['execorder']) - $errors['execorder']='Order required'; + $errors['execorder'] = 'Order required'; elseif(!is_numeric($vars['execorder'])) - $errors['execorder']='Must be numeric value'; + $errors['execorder'] = 'Must be numeric value'; if(!$vars['name']) - $errors['name']='Name required'; + $errors['name'] = 'Name required'; elseif(($sid=self::getIdByName($vars['name'])) && $sid!=$id) - $errors['name']='Name already in-use'; + $errors['name'] = 'Name already in-use'; if(!$errors && !self::validate_rules($vars,$errors) && !$errors['rules']) - $errors['rules']='Unable to validate rules as entered'; + $errors['rules'] = 'Unable to validate rules as entered'; + + $targets = self::getTargets(); + if(!$vars['target']) + $errors['target'] = 'Target required'; + else if(!is_numeric($vars['target']) && !$targets[$vars['target']]) + $errors['target'] = 'Unknown or invalid target'; if($errors) return false; - $sql=' updated=NOW() '. - ',isactive='.db_input($vars['isactive']). - ',name='.db_input($vars['name']). - ',execorder='.db_input($vars['execorder']). - ',email_id='.db_input($vars['email_id']). - ',dept_id='.db_input($vars['dept_id']). - ',priority_id='.db_input($vars['priority_id']). - ',sla_id='.db_input($vars['sla_id']). - ',match_all_rules='.db_input($vars['match_all_rules']). - ',stop_onmatch='.db_input(isset($vars['stop_onmatch'])?1:0). - ',reject_email='.db_input(isset($vars['reject_email'])?1:0). - ',use_replyto_email='.db_input(isset($vars['use_replyto_email'])?1:0). - ',disable_autoresponder='.db_input(isset($vars['disable_autoresponder'])?1:0). - ',canned_response_id='.db_input($vars['canned_response_id']). - ',notes='.db_input($vars['notes']); + $emailId = 0; + if(is_numeric($vars['target'])) { + $emailId = $vars['target']; + $vars['target'] = 'Email'; + } + + $sql=' updated=NOW() ' + .',isactive='.db_input($vars['isactive']) + .',target='.db_input($vars['target']) + .',name='.db_input($vars['name']) + .',execorder='.db_input($vars['execorder']) + .',email_id='.db_input($emailId) + .',dept_id='.db_input($vars['dept_id']) + .',priority_id='.db_input($vars['priority_id']) + .',sla_id='.db_input($vars['sla_id']) + .',match_all_rules='.db_input($vars['match_all_rules']) + .',stop_onmatch='.db_input(isset($vars['stop_onmatch'])?1:0) + .',reject_ticket='.db_input(isset($vars['reject_ticket'])?1:0) + .',use_replyto_email='.db_input(isset($vars['use_replyto_email'])?1:0) + .',disable_autoresponder='.db_input(isset($vars['disable_autoresponder'])?1:0) + .',canned_response_id='.db_input($vars['canned_response_id']) + .',notes='.db_input($vars['notes']); //Auto assign ID is overloaded... @@ -438,11 +473,11 @@ class Filter { $sql.=',staff_id=0,team_id=0 '; //no auto-assignment! if($id) { - $sql='UPDATE '.EMAIL_FILTER_TABLE.' SET '.$sql.' WHERE id='.db_input($id); + $sql='UPDATE '.FILTER_TABLE.' SET '.$sql.' WHERE id='.db_input($id); if(!db_query($sql)) $errors['err']='Unable to update the filter. Internal error occurred'; }else{ - $sql='INSERT INTO '.EMAIL_FILTER_TABLE.' SET '.$sql.',created=NOW() '; + $sql='INSERT INTO '.FILTER_TABLE.' SET '.$sql.',created=NOW() '; if(!db_query($sql) || !($id=db_insert_id())) $errors['err']='Unable to add filter. Internal error'; } @@ -464,14 +499,14 @@ class FilterRule { var $filter; - function FilterRule($id,$filterId=0){ + function FilterRule($id,$filterId=0) { $this->id=0; $this->load($id,$filterId); } function load($id,$filterId=0) { - $sql='SELECT rule.* FROM '.EMAIL_FILTER_RULE_TABLE.' rule ' + $sql='SELECT rule.* FROM '.FILTER_RULE_TABLE.' rule ' .' WHERE rule.id='.db_input($id); if($filterId) $sql.=' AND rule.filter_id='.db_input($filterId); @@ -529,9 +564,9 @@ class FilterRule { return true; } - function delete(){ + function delete() { - $sql='DELETE FROM '.EMAIL_FILTER_RULE_TABLE.' WHERE id='.db_input($this->getId()).' AND filter_id='.db_input($this->getFilterId()); + $sql='DELETE FROM '.FILTER_RULE_TABLE.' WHERE id='.db_input($this->getId()).' AND filter_id='.db_input($this->getFilterId()); return (db_query($sql) && db_affected_rows()); } @@ -559,12 +594,12 @@ class FilterRule { $sql.=',notes='.db_input($vars['notes']); if($id) { - $sql='UPDATE '.EMAIL_FILTER_RULE_TABLE.' SET '.$sql.' WHERE id='.db_input($id).' AND filter_id='.db_input($vars['filter_id']); + $sql='UPDATE '.FILTER_RULE_TABLE.' SET '.$sql.' WHERE id='.db_input($id).' AND filter_id='.db_input($vars['filter_id']); if(db_query($sql)) return true; } else { - $sql='INSERT INTO '.EMAIL_FILTER_RULE_TABLE.' SET created=NOW(), filter_id='.db_input($vars['filter_id']).', '.$sql; + $sql='INSERT INTO '.FILTER_RULE_TABLE.' SET created=NOW(), filter_id='.db_input($vars['filter_id']).', '.$sql; if(db_query($sql) && ($id=db_insert_id())) return $id; } @@ -579,50 +614,65 @@ class FilterRule { } /** - * Applies rules defined in the staff control panel "Email Filters". Each + * Applies rules defined in the admin control panel > Settings tab > "Ticket Filters". Each * filter can have up to 25 rules (*currently). This will attempt to match - * the incoming email against the defined rules, and, if the email matches, - * the ticket will be modified as described in the filter + * the incoming tickets against the defined rules, and, if the email matches, + * the ticket will be modified as described in the filter actions. */ -class EmailFilter { +class TicketFilter { + + var $target; + var $vars; + /** - * Construct a list of filters to handle a new ticket generated from an - * email or something with information common to email (such as API - * calls, etc). + * Construct a list of filters to handle a new ticket + * taking into account the source/origin of the ticket. * - * $email is an ARRAY, which has valid keys - * *email - email address of sender - * name - name of sender - * subject - subject line of the email - * email-id - id of osTicket email recipient address + * $vars is an ARRAY, which has valid keys + * *email - email address of user + * name - name of user + * subject - subject of the ticket + * emailId - id of osTicket's system email (for emailed tickets) * --------------- * @see Filter::matches() for a complete list of supported keys * - * $slow - if TRUE, every (active) filter will be fetched from the - * database and matched against the email. Otherwise, a subset - * of filters from the database that appear to have rules that - * deal with the data in the email will be considered. @see - * ::quickList() for more information. + * IF $vars is not provided, every (active) filter will be fetched from the + * database and matched against the incoming ticket. Otherwise, a subset + * of filters from the database that appear to have rules that + * deal with the data in the incoming ticket (based on $vars) will be considered. + * @see ::quickList() for more information. */ - function EmailFilter($email, $slow=false) { - $this->email = $email; - if ($slow) { - $this->build($this->getAllActive()); - } else { - $this->build( - $this->quickList($email['email'], $email['name'], - $email['subject'], $email['emailId'])); - } + function TicketFilter($origin, $vars=null) { + + $this->target = self::origin2target($origin); + $this->vars = ($vars && is_array($vars))?array_filter(array_map('trim', $vars)):null; + + //Init filters. + $this->build(); } - - function build($res) { + + function build() { + + //Clear any memoized filters $this->filters = array(); - while (list($id) = db_fetch_row($res)) - array_push($this->filters, new Filter($id)); + $this->short_list = array(); + + //Query DB for "possibly" matching filters. + $res = $this->vars?$this->quickList():$this->getAllActive(); + if($res) { + while (list($id) = db_fetch_row($res)) + array_push($this->filters, new Filter($id)); + } + return $this->filters; } + + function getTarget() { + return $this->target; + } + /** - * Fetches the short list of filters that match the email received in the + * Fetches the short list of filters that match the ticket vars received in the * constructor. This function is memoized so subsequent calls will * return immediately. */ @@ -630,17 +680,18 @@ class EmailFilter { if (!isset($this->short_list)) { $this->short_list = array(); foreach ($this->filters as $filter) - if ($filter->matches($this->email)) + if ($filter->matches($this->vars)) $this->short_list[] = $filter; } + return $this->short_list; } /** - * Determine if the filters that match the received email indicate that + * Determine if the filters that match the received vars indicate that * the email should be rejected * * Returns FALSE if the email should be acceptable. If the email should - * be rejected, the first filter that matches and has rejectEmail set is + * be rejected, the first filter that matches and has reject ticket set is * returned. */ function shouldReject() { @@ -649,7 +700,7 @@ class EmailFilter { # be blocked; however, don't unset $reject, because if it # was set by another rule that did not set stopOnMatch(), we # should still honor its configuration - if ($filter->rejectEmail()) return $filter; + if ($filter->rejectOnMatch()) return $filter; } return false; } @@ -659,17 +710,21 @@ class EmailFilter { */ function apply(&$ticket) { foreach ($this->getMatchingFilterList() as $filter) { - $filter->apply($ticket, $this->email); + $filter->apply($ticket, $this->vars); if ($filter->stopOnMatch()) break; } } /* static */ function getAllActive() { - $sql="SELECT id FROM ".EMAIL_FILTER_TABLE." WHERE isactive" - ." ORDER BY execorder"; + + $sql='SELECT id FROM '.FILTER_TABLE + .' WHERE isactive=1 ' + .' AND target IN ("Any", '.db_input($this->getTarget()).') ' + .' ORDER BY execorder'; return db_query($sql); } + /** * Fast lookup function to all filters that have at least one rule that * matches the received address or name or is not defined to match based @@ -693,45 +748,55 @@ class EmailFilter { * information from the database. Whether the filter will completely * match or not is determined in the Filter::matches() method. */ - /* static */ function quickList($addr, $name=false, $subj=false, - $emailid=0) { - $sql="SELECT DISTINCT filter_id FROM ".EMAIL_FILTER_RULE_TABLE." rule" - ." INNER JOIN ".EMAIL_FILTER_TABLE." filter" - ." ON (filter.id=rule.filter_id)" - ." WHERE filter.isactive"; - # Filter by recipient email-id if specified - if ($emailid) #TODO: Fix the logic here... - $sql.=" AND filter.email_id=".db_input($emailid); + function quickList() { + + if(!$this->vars || !$this->vars['email']) + return $this->getAllActive(); + + $sql='SELECT DISTINCT filter_id FROM '.FILTER_RULE_TABLE.' rule ' + .' INNER JOIN '.FILTER_TABLE.' filter ' + .' ON (filter.id=rule.filter_id) ' + .' WHERE filter.isactive ' + ." AND filter.target IN ('Any', ".db_input($this->getTarget()).') '; + + # Filter by system's email-id if specified + if($this->vars['emailId']) + $sql.=' AND (filter.email_id=0 OR filter.email_id='.db_input($this->vars['emailId']).')'; + # Include rules for sender-email, sender-name and subject as # requested - $sql.=" AND ((what='email' AND LOCATE(val,".db_input($addr)."))"; - if ($name) - $sql.=" OR (what='name' AND LOCATE(val,".db_input($name)."))"; - if ($subj) - $sql.=" OR (what='subject' AND LOCATE(val,".db_input($subj)."))"; + $sql.=" AND ((what='email' AND LOCATE(val, ".db_input($this->vars['email']).'))'; + if($this->vars['name']) + $sql.=" OR (what='name' AND LOCATE(val, ".db_input($this->vars['name']).'))'; + if($this->vars['subject']) + $sql.=" OR (what='subject' AND LOCATE(val, ".db_input($this->vars['subject']).'))'; # Also include filters that do not have any rules concerning either # sender-email-addresses or sender-names or subjects $sql.=") OR filter.id IN (" ." SELECT filter_id " - ." FROM ".EMAIL_FILTER_RULE_TABLE." rule" - ." INNER JOIN ".EMAIL_FILTER_TABLE." filter" + ." FROM ".FILTER_RULE_TABLE." rule" + ." INNER JOIN ".FILTER_TABLE." filter" ." ON (rule.filter_id=filter.id)" + ." WHERE filter.isactive" + ." AND filter.target IN('Any', ".db_input($this->getTarget()).")" ." GROUP BY filter_id" ." HAVING COUNT(*)-COUNT(NULLIF(what,'email'))=0"; - if ($name!==false) $sql.=" AND COUNT(*)-COUNT(NULLIF(what,'name'))=0"; - if ($subj!==false) $sql.=" AND COUNT(*)-COUNT(NULLIF(what,'subject'))=0"; + if (!$this->vars['name']) $sql.=" AND COUNT(*)-COUNT(NULLIF(what,'name'))=0"; + if (!$this->vars['subject']) $sql.=" AND COUNT(*)-COUNT(NULLIF(what,'subject'))=0"; # Also include filters that do not have match_all_rules set to and # have at least one rule 'what' type that wasn't considered $sql.=") OR filter.id IN (" ." SELECT filter_id" - ." FROM ".EMAIL_FILTER_RULE_TABLE." rule" - ." INNER JOIN ".EMAIL_FILTER_TABLE." filter" + ." FROM ".FILTER_RULE_TABLE." rule" + ." INNER JOIN ".FILTER_TABLE." filter" ." ON (rule.filter_id=filter.id)" - ." WHERE what NOT IN ('email'" + ." WHERE filter.isactive" + ." AND filter.target IN ('Any', ".db_input($this->getTarget()).")" + ." AND what NOT IN ('email'" # Handle sender-name and subject if specified - .(($name!==false)?",'name'":"") - .(($subj!==false)?",'subject'":"") - .") AND filter.match_all_rules = false" + .((!$this->vars['name'])?",'name'":"") + .((!$this->vars['subject'])?",'subject'":"") + .") AND filter.match_all_rules = 0 " # Return filters in declared execution order .") ORDER BY filter.execorder"; @@ -751,10 +816,10 @@ class EmailFilter { /* static */ function isBanned($addr) { $sql='SELECT filter.id, what, how, UPPER(val) ' - .' FROM '.EMAIL_FILTER_TABLE.' filter' - .' INNER JOIN '.EMAIL_FILTER_RULE_TABLE.' rule' + .' FROM '.FILTER_TABLE.' filter' + .' INNER JOIN '.FILTER_RULE_TABLE.' rule' .' ON (filter.id=rule.filter_id)' - .' WHERE filter.reject_email' + .' WHERE filter.reject_ticket' .' AND filter.match_all_rules=0' .' AND filter.email_id=0' .' AND filter.isactive' @@ -762,20 +827,22 @@ class EmailFilter { .' AND rule.what="email"' .' AND LOCATE(rule.val,'.db_input($addr).')'; + if(!($res=db_query($sql)) || !db_num_rows($res)) + return false; + # XXX: Use MB_xxx function for proper unicode support $addr = strtoupper($addr); $how=array('equal' => array('strcmp', 0), 'contains' => array('strpos', null, false)); - - if ($res=db_query($sql)) { - while ($row=db_fetch_array($res)) { - list($func, $pos, $neg) = $how[$row['how']]; - if (!$func) continue; - $res = call_user_func($func, $addr, $row['val']); - if (($neg === null && $res === $pos) || $res !== $neg) - return $row['id']; - } + + while ($row=db_fetch_array($res)) { + list($func, $pos, $neg) = $how[$row['how']]; + if (!$func) continue; + $result = call_user_func($func, $addr, $row['val']); + if (($neg === null && $result === $pos) || $result !== $neg) + return $row['id']; } + return false; } @@ -814,5 +881,15 @@ class EmailFilter { } return false; } + + /** + * Normalize ticket source to supported filter target + * + */ + function origin2target($origin) { + $sources=array('web' => 'Web', 'email' => 'Email', 'phone' => 'Web', 'staff' => 'Web', 'api' => 'API'); + + return $sources[strtolower($origin)]; + } } ?> diff --git a/include/class.mailfetch.php b/include/class.mailfetch.php index fb8402169e83b39c258118329215d2459d7547a2..5a4e7e0f73e2edbe006f485f9dbe50b6d69809ce 100644 --- a/include/class.mailfetch.php +++ b/include/class.mailfetch.php @@ -376,7 +376,7 @@ class MailFetcher { return true; //Reporting success so the email can be moved or deleted. //Is the email address banned? - if($mailinfo['email'] && EmailFilter::isBanned($mailinfo['email'])) { + if($mailinfo['email'] && TicketFilter::isBanned($mailinfo['email'])) { //We need to let admin know... $ost->logWarning('Ticket denied', 'Banned email - '.$mailinfo['email']); return true; //Report success (moved or delete) diff --git a/include/class.ticket.php b/include/class.ticket.php index 8b9581d532a1e94c8076d3eca0b82bcfe88d7d0e..fc7eb1c520d45dfaab47ee3d7cd61db4f78f2eba 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -1331,7 +1331,7 @@ class Ticket{ if($newticket) return $msgid; //Our work is done... $autorespond = true; - if ($autorespond && $headers && EmailFilter::isAutoResponse(Mail_Parse::splitHeaders($headers))) + if ($autorespond && $headers && TicketFilter::isAutoResponse(Mail_Parse::splitHeaders($headers))) $autorespond=false; $this->onMessage($autorespond); //must be called b4 sending alerts to staff. @@ -1845,7 +1845,7 @@ class Ticket{ if ($vars['email'] && Validator::is_email($vars['email'])) { //Make sure the email address is not banned - if(EmailFilter::isBanned($vars['email'])) { + if(TicketFilter::isBanned($vars['email'])) { $errors['err']='Ticket denied. Error #403'; $ost->logWarning('Ticket denied', 'Banned email - '.$vars['email']); return 0; @@ -1865,12 +1865,15 @@ class Ticket{ return 0; } } + + //Init ticket filters... + $ticket_filter = new TicketFilter($origin, $vars); // Make sure email contents should not be rejected - if (($email_filter=new EmailFilter($vars)) - && ($filter=$email_filter->shouldReject())) { + if($ticket_filter + && ($filter=$ticket_filter->shouldReject())) { $errors['err']='Ticket denied. Error #403'; $ost->logWarning('Ticket denied', - sprintf('Banned email - %s by filter "%s"', + sprintf('Ticket rejected ( %s) by filter "%s"', $vars['email'], $filter->getName())); return 0; @@ -1915,7 +1918,7 @@ class Ticket{ } //Make sure the due date is valid - if($vars['duedate']){ + if($vars['duedate']) { if(!$vars['time'] || strpos($vars['time'],':')===false) $errors['time']='Select time'; elseif(strtotime($vars['duedate'].' '.$vars['time'])===false) @@ -1924,16 +1927,16 @@ class Ticket{ $errors['duedate']='Due date must be in the future'; } - # Perform email filter actions on the new ticket arguments XXX: Move filter to the top and check for reject... - if (!$errors && $email_filter) $email_filter->apply($vars); + //Any error above is fatal. + if($errors) return 0; + + # Perform ticket filter actions on the new ticket arguments + if ($ticket_filter) $ticket_filter->apply($vars); # Some things will need to be unpacked back into the scope of this # function if (isset($vars['autorespond'])) $autorespond=$vars['autorespond']; - //Any error above is fatal. - if($errors) return 0; - // OK...just do it. $deptId=$vars['deptId']; //pre-selected Dept if any. $priorityId=$vars['priorityId']; @@ -1951,11 +1954,7 @@ class Ticket{ if($autorespond) $autorespond=$email->autoRespond(); $email=null; $source='Email'; - }elseif($vars['deptId']){ //Opened by staff. - $deptId=$vars['deptId']; - $source=ucfirst($vars['source']); } - //Last minute checks $priorityId=$priorityId?$priorityId:$cfg->getDefaultPriorityId(); $deptId=$deptId?$deptId:$cfg->getDefaultDeptId(); @@ -2019,7 +2018,7 @@ class Ticket{ # Messages that are clearly auto-responses from email systems should # not have a return 'ping' message if ($autorespond && $vars['header'] && - EmailFilter::isAutoResponse(Mail_Parse::splitHeaders($vars['header']))) { + TicketFilter::isAutoResponse(Mail_Parse::splitHeaders($vars['header']))) { $autorespond=false; } diff --git a/include/staff/banlist.inc.php b/include/staff/banlist.inc.php index 0b61d1e8b779edaf48c448c82eb38c3d1ce3deed..b2b37b284b0ae4de0750650b2feb9fae2135cf5d 100644 --- a/include/staff/banlist.inc.php +++ b/include/staff/banlist.inc.php @@ -3,7 +3,7 @@ if(!defined('OSTADMININC') || !$thisstaff || !$thisstaff->isAdmin() || !$filter) $qstr=''; $select='SELECT rule.* '; -$from='FROM '.EMAIL_FILTER_RULE_TABLE.' rule '; +$from='FROM '.FILTER_RULE_TABLE.' rule '; $where='WHERE rule.filter_id='.db_input($filter->getId()); $search=false; if($_REQUEST['q'] && strlen($_REQUEST['q'])>3) { diff --git a/include/staff/filter.inc.php b/include/staff/filter.inc.php index c2aad0bcf4456d5bade4fa323a4ba3c991c39929..36186838bd93cdba6977add500645becba4d673e 100644 --- a/include/staff/filter.inc.php +++ b/include/staff/filter.inc.php @@ -33,7 +33,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <tr> <th colspan="2"> <h4><?php echo $title; ?></h4> - <em>Filters are executed based on execution order.</em> + <em>Filters are executed based on execution order. Filter can target specific ticket source.</em> </th> </tr> </thead> @@ -71,31 +71,37 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); </td> </tr> <tr> - <td width="180"> - To Email Address: + <td width="180" class="required"> + Target: </td> <td> - <select name="email_id"> - <option value="0">— Filter applies to ALL incoming emails ‐</option> - <?php + <select name="target"> + <option value="">— Select a Target ‐</option> + <?php + foreach(Filter::getTargets() as $k => $v) { + echo sprintf('<option value="%s" %s>%s</option>', + $k, (($k==$info['target'])?'selected="selected"':''), $v); + } $sql='SELECT email_id,email,name FROM '.EMAIL_TABLE.' email ORDER by name'; - if(($res=db_query($sql)) && db_num_rows($res)){ - while(list($id,$email,$name)=db_fetch_row($res)){ + if(($res=db_query($sql)) && db_num_rows($res)) { + echo '<OPTGROUP label="Specific System Email">'; + while(list($id,$email,$name)=db_fetch_row($res)) { $selected=($info['email_id'] && $id==$info['email_id'])?'selected="selected"':''; if($name) $email=Format::htmlchars("$name <$email>"); echo sprintf('<option value="%d" %s>%s</option>',$id,$selected,$email); } + echo '</OPTGROUP>'; } ?> </select> - <br><em>(Highly recommended if the filter is specific to one incoming email address)</em> + + <span class="error">* <?php echo $errors['target']; ?></span> </td> </tr> <tr> <th colspan="2"> - <em><strong>Filter Rules</strong>: Rules are applied based on the criteria. - <span class="error">* <?php echo $errors['rules']; ?></span></em> + <em><strong>Filter Rules</strong>: Rules are applied based on the criteria. <span class="error">* <?php echo $errors['rules']; ?></span></em> </th> </tr> <tr> @@ -156,11 +162,11 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); </tr> <tr> <td width="180"> - Ban Email: + Reject Ticket: </td> <td> - <input type="checkbox" name="reject_email" value="1" <?php echo $info['reject_email']?'checked="checked"':''; ?> > - <strong><font class="error">Reject email</font></strong> <em>(All other actions, rules and filters are ignored)</em> + <input type="checkbox" name="reject_ticket" value="1" <?php echo $info['reject_ticket']?'checked="checked"':''; ?> > + <strong><font class="error">Reject Ticket</font></strong> <em>(All other actions and filters are ignored)</em> </td> </tr> <tr> diff --git a/include/staff/filters.inc.php b/include/staff/filters.inc.php index 7f3aab393f56cb3b1eb3f8dc3da0113204d35e41..7573eceec7d3a82950a52e9e04ce2fce213754e8 100644 --- a/include/staff/filters.inc.php +++ b/include/staff/filters.inc.php @@ -1,13 +1,13 @@ <?php if(!defined('OSTADMININC') || !$thisstaff->isAdmin()) die('Access Denied'); - +$targets = Filter::getTargets(); $qstr=''; $sql='SELECT filter.*,count(rule.id) as rules '. - 'FROM '.EMAIL_FILTER_TABLE.' filter '. - 'LEFT JOIN '.EMAIL_FILTER_RULE_TABLE.' rule ON(rule.filter_id=filter.id) '. + 'FROM '.FILTER_TABLE.' filter '. + 'LEFT JOIN '.FILTER_RULE_TABLE.' rule ON(rule.filter_id=filter.id) '. 'GROUP BY filter.id'; $sortOptions=array('name'=>'filter.name','status'=>'filter.isactive','order'=>'filter.execorder','rules'=>'rules', - 'created'=>'filter.created','updated'=>'filter.updated'); + 'target'=>'filter.target', 'created'=>'filter.created','updated'=>'filter.updated'); $orderWays=array('DESC'=>'DESC','ASC'=>'ASC'); $sort=($_REQUEST['sort'] && $sortOptions[strtolower($_REQUEST['sort'])])?strtolower($_REQUEST['sort']):'name'; //Sorting options... @@ -28,7 +28,7 @@ $x=$sort.'_sort'; $$x=' class="'.strtolower($order).'" '; $order_by="$order_column $order "; -$total=db_count('SELECT count(*) FROM '.EMAIL_FILTER_TABLE.' filter '); +$total=db_count('SELECT count(*) FROM '.FILTER_TABLE.' filter '); $page=($_GET['p'] && is_numeric($_GET['p']))?$_GET['p']:1; $pageNav=new Pagenate($total, $page, PAGE_LIMIT); $pageNav->setURL('filters.php',$qstr.'&sort='.urlencode($_REQUEST['sort']).'&order='.urlencode($_REQUEST['order'])); @@ -44,7 +44,7 @@ else ?> <div style="width:700;padding-top:5px; float:left;"> - <h2>Email Filters</h2> + <h2>Ticket Filters</h2> </div> <div style="float:right;text-align:right;padding-top:5px;padding-right:5px;"> <b><a href="filters.php?a=add" class="Icon newEmailFilter">Add New Filter</a></b></div> @@ -58,9 +58,10 @@ else <tr> <th width="7"> </th> <th width="320"><a <?php echo $name_sort; ?> href="filters.php?<?php echo $qstr; ?>&sort=name">Name</a></th> - <th width="100"><a <?php echo $status_sort; ?> href="filters.php?<?php echo $qstr; ?>&sort=status">Status</a></th> + <th width="80"><a <?php echo $status_sort; ?> href="filters.php?<?php echo $qstr; ?>&sort=status">Status</a></th> <th width="80" style="text-align:center;"><a <?php echo $order_sort; ?> href="filters.php?<?php echo $qstr; ?>&sort=order">Order</a></th> <th width="80" style="text-align:center;"><a <?php echo $rules_sort; ?> href="filters.php?<?php echo $qstr; ?>&sort=rules">Rules</a></th> + <th width="100"><a <?php echo $target_sort; ?> href="filters.php?<?php echo $qstr; ?>&sort=target">Target</a></th> <th width="120" nowrap><a <?php echo $created_sort; ?>href="filters.php?<?php echo $qstr; ?>&sort=created">Date Added</a></th> <th width="150" nowrap><a <?php echo $updated_sort; ?>href="filters.php?<?php echo $qstr; ?>&sort=updated">Last Updated</a></th> </tr> @@ -85,6 +86,7 @@ else <td><?php echo $row['isactive']?'Active':'<b>Disabled</b>'; ?></td> <td style="text-align:right;padding-right:25px;"><?php echo $row['execorder']; ?> </td> <td style="text-align:right;padding-right:25px;"><?php echo $row['rules']; ?> </td> + <td> <?php echo Format::htmlchars($targets[$row['target']]); ?></td> <td> <?php echo Format::db_date($row['created']); ?></td> <td> <?php echo Format::db_datetime($row['updated']); ?></td> </tr> @@ -93,7 +95,7 @@ else endif; ?> <tfoot> <tr> - <td colspan="7"> + <td colspan="8"> <?php if($res && $num){ ?> Select: <a href="#" onclick="return select_all(document.forms['filters'],true)">All</a> diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php index a58206963acf4deb36fd48bf17d80c2ea63020aa..ddd2839b24a720341841edd2c9b81e4efd218164 100644 --- a/include/staff/ticket-view.inc.php +++ b/include/staff/ticket-view.inc.php @@ -27,7 +27,7 @@ if($ticket->isAssigned() && ( $warn.=' <span class="Icon assignedTicket">Ticket is assigned to '.implode('/', $ticket->getAssignees()).'</span>'; if(!$errors['err'] && ($lock && $lock->getStaffId()!=$thisstaff->getId())) $errors['err']='This ticket is currently locked by '.$lock->getStaffName(); -if(!$errors['err'] && ($emailBanned=EmailFilter::isBanned($ticket->getEmail()))) +if(!$errors['err'] && ($emailBanned=TicketFilter::isBanned($ticket->getEmail()))) $errors['err']='Email is in banlist! Must be removed before any reply/response'; $unbannable=($emailBanned) ? BanList::includes($ticket->getEmail()) : false; diff --git a/include/upgrader/sql/c00511c7-7be60a84.patch.sql b/include/upgrader/sql/c00511c7-7be60a84.patch.sql index 638248b976019a670c773578b564d99a3daacc6a..fdefd09bea960de619fc5a1feac8bd69d3c77b8e 100644 --- a/include/upgrader/sql/c00511c7-7be60a84.patch.sql +++ b/include/upgrader/sql/c00511c7-7be60a84.patch.sql @@ -63,7 +63,7 @@ ALTER TABLE `%TABLE_PREFIX%config` ADD `transfer_alert_dept_manager` TINYINT( 1 ) UNSIGNED NOT NULL DEFAULT '1' AFTER `transfer_alert_assigned` , ADD `transfer_alert_dept_members` TINYINT( 1 ) UNSIGNED NOT NULL DEFAULT '0' AFTER `transfer_alert_dept_manager`, ADD `send_sys_errors` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1' AFTER `enable_email_piping`, - ADD `enable_kb` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1' AFTER `use_email_priority`, + ADD `enable_kb` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0' AFTER `use_email_priority`, ADD `enable_premade` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1' AFTER `enable_kb`, ADD `show_related_tickets` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1' AFTER `auto_assign_reopened_tickets`, ADD `schema_signature` CHAR( 32 ) NOT NULL AFTER `ostversion`; diff --git a/include/upgrader/sql/d0e37dca-1da1bcba.patch.sql b/include/upgrader/sql/d0e37dca-1da1bcba.patch.sql new file mode 100644 index 0000000000000000000000000000000000000000..3d3bda68e2fd49293e1a73545506416c7a1cc126 --- /dev/null +++ b/include/upgrader/sql/d0e37dca-1da1bcba.patch.sql @@ -0,0 +1,23 @@ +/** + * @version v1.7 RC3 + * @signature 1da1bcbafcedc65efef58f142a48ac91 + * + * Upgrade from 1.6 RC3 + filters + * + */ + +RENAME TABLE `%TABLE_PREFIX%email_filter` TO `%TABLE_PREFIX%filter`; + +RENAME TABLE `%TABLE_PREFIX%email_filter_rule` TO `%TABLE_PREFIX%filter_rule`; + +ALTER TABLE `%TABLE_PREFIX%filter` CHANGE `reject_email` `reject_ticket` TINYINT( 1 ) UNSIGNED NOT NULL DEFAULT '0'; + +ALTER TABLE `%TABLE_PREFIX%filter` + ADD `target` ENUM( 'Any', 'Web', 'Email', 'API' ) NOT NULL DEFAULT 'Any' AFTER `sla_id` , + ADD INDEX ( `target` ); + +UPDATE `%TABLE_PREFIX%filter` SET `target` = 'Email' WHERE `email_id` != 0; + +-- Finished with patch +UPDATE `%TABLE_PREFIX%config` + SET `schema_signature`='1da1bcbafcedc65efef58f142a48ac91'; diff --git a/main.inc.php b/main.inc.php index abcbfeabdaee005bdd83abb7719ac163e0e531af..c3986f80922687722184fc90df9bfeb150f5fb71 100644 --- a/main.inc.php +++ b/main.inc.php @@ -63,8 +63,7 @@ #Current version && schema signature (Changes from version to version) define('THIS_VERSION','1.7-RC2'); //Shown on admin panel - define('SCHEMA_SIGNATURE','d0e37dca324648f1ce2d10528a6026d4'); //MD5 signature of the db schema. (used to trigger upgrades) - + define('SCHEMA_SIGNATURE','1da1bcbafcedc65efef58f142a48ac91'); //MD5 signature of the db schema. (used to trigger upgrades) #load config info $configfile=''; if(file_exists(ROOT_DIR.'ostconfig.php')) //Old installs prior to v 1.6 RC5 @@ -159,8 +158,10 @@ define('EMAIL_TABLE',TABLE_PREFIX.'email'); define('EMAIL_TEMPLATE_TABLE',TABLE_PREFIX.'email_template'); - define('EMAIL_FILTER_TABLE',TABLE_PREFIX.'email_filter'); - define('EMAIL_FILTER_RULE_TABLE',TABLE_PREFIX.'email_filter_rule'); + + define('FILTER_TABLE',TABLE_PREFIX.'filter'); + define('FILTER_RULE_TABLE',TABLE_PREFIX.'filter_rule'); + define('BANLIST_TABLE',TABLE_PREFIX.'email_banlist'); //Not in use anymore....as of v 1.7 define('SLA_TABLE',TABLE_PREFIX.'sla'); diff --git a/scp/banlist.php b/scp/banlist.php index 081fde9b4ed0cd18713cab78e795c2e0eaf1df1b..a31d91d7e8d2392c2d7e23dba570a07257532ec8 100644 --- a/scp/banlist.php +++ b/scp/banlist.php @@ -68,7 +68,7 @@ if($_POST && !$errors && $filter){ }else{ $count=count($_POST['ids']); if($_POST['enable']){ - $sql='UPDATE '.EMAIL_FILTER_RULE_TABLE.' SET isactive=1 WHERE filter_id='. + $sql='UPDATE '.FILTER_RULE_TABLE.' SET isactive=1 WHERE filter_id='. db_input($filter->getId()). ' AND id IN ('. implode(',', db_input($_POST['ids'])).')'; @@ -81,7 +81,7 @@ if($_POST && !$errors && $filter){ $errors['err']='Unable to enable selected emails'; } }elseif($_POST['disable']){ - $sql='UPDATE '.EMAIL_FILTER_RULE_TABLE.' SET isactive=0 WHERE filter_id='. + $sql='UPDATE '.FILTER_RULE_TABLE.' SET isactive=0 WHERE filter_id='. db_input($filter->getId()). ' AND id IN ('. implode(',', db_input($_POST['ids'])).')'; diff --git a/scp/filters.php b/scp/filters.php index 2fe1f9fb7c06f9848f958d1e2e8b6ebe62b17390..29045410fe685f10a86a362942f34259a6401edd 100644 --- a/scp/filters.php +++ b/scp/filters.php @@ -49,7 +49,7 @@ if($_POST){ }else{ $count=count($_POST['ids']); if($_POST['enable']){ - $sql='UPDATE '.EMAIL_FILTER_TABLE.' SET isactive=1 WHERE id IN ('. + $sql='UPDATE '.FILTER_TABLE.' SET isactive=1 WHERE id IN ('. implode(',', db_input($_POST['ids'])).')'; if(db_query($sql) && ($num=db_affected_rows())){ if($num==$count) @@ -60,7 +60,7 @@ if($_POST){ $errors['err']='Unable to enable selected filters'; } }elseif($_POST['disable']){ - $sql='UPDATE '.EMAIL_FILTER_TABLE.' SET isactive=0 WHERE id IN ('. + $sql='UPDATE '.FILTER_TABLE.' SET isactive=0 WHERE id IN ('. implode(',', db_input($_POST['ids'])).')'; if(db_query($sql) && ($num=db_affected_rows())) { if($num==$count) diff --git a/scp/tickets.php b/scp/tickets.php index 8c799a2a6a02a26c4185afece329ffc5e57cdcf4..77eec14eab39caed7e1c235ffa079bdeaa658ace 100644 --- a/scp/tickets.php +++ b/scp/tickets.php @@ -52,7 +52,7 @@ if($_POST && !$errors): $errors['err']='Action Denied. Ticket is locked by someone else!'; //Make sure the email is not banned - if(!$errors['err'] && EmailFilter::isBanned($ticket->getEmail())) + if(!$errors['err'] && TicketFilter::isBanned($ticket->getEmail())) $errors['err']='Email is in banlist. Must be removed to reply.'; $wasOpen =($ticket->isOpen()); diff --git a/setup/inc/sql/osTicket-mysql.sql b/setup/inc/sql/osTicket-mysql.sql index 5cfba00d6538506e29e136f188610df4508551cb..6be37af6d3ebdc802140748fc4c4b8b03b333796 100644 --- a/setup/inc/sql/osTicket-mysql.sql +++ b/setup/inc/sql/osTicket-mysql.sql @@ -91,7 +91,7 @@ CREATE TABLE `%TABLE_PREFIX%config` ( `clickable_urls` tinyint(1) unsigned NOT NULL default '1', `allow_priority_change` tinyint(1) unsigned NOT NULL default '0', `use_email_priority` tinyint(1) unsigned NOT NULL default '0', - `enable_kb` tinyint(1) unsigned NOT NULL default '1', + `enable_kb` tinyint(1) unsigned NOT NULL default '0', `enable_premade` tinyint(1) unsigned NOT NULL default '1', `enable_captcha` tinyint(1) unsigned NOT NULL default '0', `enable_auto_cron` tinyint(1) unsigned NOT NULL default '0', @@ -228,14 +228,14 @@ CREATE TABLE `%TABLE_PREFIX%email` ( KEY `dept_id` (`dept_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -DROP TABLE IF EXISTS `%TABLE_PREFIX%email_filter`; -CREATE TABLE `%TABLE_PREFIX%email_filter` ( +DROP TABLE IF EXISTS `%TABLE_PREFIX%filter`; +CREATE TABLE `%TABLE_PREFIX%filter` ( `id` int(11) unsigned NOT NULL auto_increment, `execorder` int(10) unsigned NOT NULL default '99', `isactive` tinyint(1) unsigned NOT NULL default '1', `match_all_rules` tinyint(1) unsigned NOT NULL default '0', `stop_onmatch` tinyint(1) unsigned NOT NULL default '0', - `reject_email` tinyint(1) unsigned NOT NULL default '0', + `reject_ticket` tinyint(1) unsigned NOT NULL default '0', `use_replyto_email` tinyint(1) unsigned NOT NULL default '0', `disable_autoresponder` tinyint(1) unsigned NOT NULL default '0', `canned_response_id` int(11) unsigned NOT NULL default '0', @@ -245,20 +245,22 @@ CREATE TABLE `%TABLE_PREFIX%email_filter` ( `staff_id` int(10) unsigned NOT NULL default '0', `team_id` int(10) unsigned NOT NULL default '0', `sla_id` int(10) unsigned NOT NULL default '0', + `target` ENUM( 'Any', 'Web', 'Email', 'API' ) NOT NULL DEFAULT 'Any', `name` varchar(32) NOT NULL default '', `notes` text, `created` datetime NOT NULL, `updated` datetime NOT NULL, PRIMARY KEY (`id`), + KEY `target` (`target`), KEY `email_id` (`email_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -INSERT INTO `%TABLE_PREFIX%email_filter` ( - `id`,`isactive`,`execorder`,`reject_email`,`name`,`notes`,`created`) +INSERT INTO `%TABLE_PREFIX%filter` ( + `id`,`isactive`,`execorder`,`reject_ticket`,`name`,`notes`,`created`) VALUES (1, 1, 99, 1, 'SYSTEM BAN LIST', 'Internal list for email banning. Do not remove', NOW()); -DROP TABLE IF EXISTS `%TABLE_PREFIX%email_filter_rule`; +DROP TABLE IF EXISTS `%TABLE_PREFIX%filter_rule`; CREATE TABLE `%TABLE_PREFIX%email_filter_rule` ( `id` int(11) unsigned NOT NULL auto_increment, `filter_id` int(10) unsigned NOT NULL default '0', @@ -274,7 +276,7 @@ CREATE TABLE `%TABLE_PREFIX%email_filter_rule` ( UNIQUE `filter` (`filter_id`, `what`, `how`, `val`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -INSERT INTO `%TABLE_PREFIX%email_filter_rule` ( +INSERT INTO `%TABLE_PREFIX%filter_rule` ( `id`, `filter_id`, `isactive`, `what`,`how`,`val`,`created`) VALUES (1, 1, 1, 'email', 'equal', 'test@example.com',NOW()); diff --git a/setup/inc/sql/osTicket-mysql.sql.md5 b/setup/inc/sql/osTicket-mysql.sql.md5 index 63d2ce443b0448ca776ebc37b298a3c4ff93c387..29a60022fd9f87dda3a08126c338d76ae84bbef8 100644 --- a/setup/inc/sql/osTicket-mysql.sql.md5 +++ b/setup/inc/sql/osTicket-mysql.sql.md5 @@ -1 +1 @@ -d0e37dca324648f1ce2d10528a6026d4 +1da1bcbafcedc65efef58f142a48ac91