diff --git a/client.inc.php b/client.inc.php index 91956c0d7dfc36e5ffb374f0812cea2f9693c6b9..ce36e7b68d886cb948ac4c9c4cd16555d104df08 100644 --- a/client.inc.php +++ b/client.inc.php @@ -50,6 +50,8 @@ if($_SESSION['_client']['userID'] && $_SESSION['_client']['key']) //is the user logged in? if($thisclient && $thisclient->getId() && $thisclient->isValid()){ $thisclient->refreshSession(); +} else { + $thisclient = null; } /******* CSRF Protectin *************/ diff --git a/include/class.filter.php b/include/class.filter.php index ce7d7d92cb273705bc458e32e6c7dd93cf8668e7..9c172edaabaf3f819df46e49e5fd2da33eb90d62 100644 --- a/include/class.filter.php +++ b/include/class.filter.php @@ -224,18 +224,10 @@ class Filter { * headers - array of email headers * emailId - osTicket system email id */ - function matches($info) { + function matches($what) { - if(!$info || !is_array($info)) return false; + if(!$what || !is_array($what)) return false; - $what = array( - 'email' => $info['email'], - 'subject' => $info['subject'], - # XXX: Support reply-to too ? - 'name' => $info['name'], - 'body' => $info['message'] - # XXX: Support headers - ); $how = array( # how => array(function, null or === this, null or !== this) 'equal' => array('strcmp', 0), @@ -248,7 +240,7 @@ class Filter { # Respect configured filter email-id if ($this->getEmailId() && !strcasecmp($this->getTarget(), 'Email') - && $this->getEmailId() != $info['emailId']) + && $this->getEmailId() != $what['emailId']) return false; foreach ($this->getRules() as $rule) { @@ -271,6 +263,7 @@ class Filter { } } } + return $match; } /** @@ -644,10 +637,20 @@ class TicketFilter { */ function TicketFilter($origin, $vars=null) { + //Normalize the target based on ticket's origin. $this->target = self::origin2target($origin); - $this->vars = ($vars && is_array($vars))?array_filter(array_map('trim', $vars)):null; - - //Init filters. + + //Extract the vars we care about (fields we filter by!). + $this->vars = array_filter(array_map('trim', + array( + 'email' => $vars['email'], + 'subject' => $vars['subject'], + 'name' => $vars['name'], + 'body' => $vars['message'], + 'emailId' => $vars['emailId']) + )); + + //Init filters. $this->build(); } @@ -655,7 +658,7 @@ class TicketFilter { //Clear any memoized filters $this->filters = array(); - $this->short_list = array(); + $this->short_list = null; //Query DB for "possibly" matching filters. $res = $this->vars?$this->quickList():$this->getAllActive(); @@ -677,6 +680,7 @@ class TicketFilter { * return immediately. */ function getMatchingFilterList() { + if (!isset($this->short_list)) { $this->short_list = array(); foreach ($this->filters as $filter) @@ -719,8 +723,13 @@ class TicketFilter { $sql='SELECT id FROM '.FILTER_TABLE .' WHERE isactive=1 ' - .' AND target IN ("Any", '.db_input($this->getTarget()).') ' - .' ORDER BY execorder'; + .' AND target IN ("Any", '.db_input($this->getTarget()).') '; + + #Take into account email ID. + if($this->vars['emailId']) + $sql.=' AND (email_id=0 OR email_id='.db_input($this->vars['emailId']).')'; + + $sql.=' ORDER BY execorder'; return db_query($sql); } @@ -770,6 +779,8 @@ class TicketFilter { $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 (" @@ -784,7 +795,7 @@ class TicketFilter { 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 + # have at least one rule 'what' type that wasn't considered e.g body $sql.=") OR filter.id IN (" ." SELECT filter_id" ." FROM ".FILTER_RULE_TABLE." rule" @@ -799,7 +810,7 @@ class TicketFilter { .") AND filter.match_all_rules = 0 " # Return filters in declared execution order .") ORDER BY filter.execorder"; - + return db_query($sql); } /** diff --git a/include/class.ticket.php b/include/class.ticket.php index 9f8ce96d5649c75c9a9035aad404e9aef39fdeb8..d04fd5dd045827fa93289056149ff3f3e021b548 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -29,6 +29,7 @@ include_once(INCLUDE_DIR.'class.template.php'); include_once(INCLUDE_DIR.'class.variable.php'); include_once(INCLUDE_DIR.'class.priority.php'); include_once(INCLUDE_DIR.'class.sla.php'); +include_once(INCLUDE_DIR.'class.canned.php'); class Ticket { @@ -1423,6 +1424,22 @@ class Ticket { return $msgid; } + function postCannedReply($canned, $msgId, $alert=true) { + + if((!is_object($canned) && !($canned=Canned::lookup($canned))) || !$canned->isEnabled()) + return false; + + $files = array(); + foreach ($canned->getAttachments() as $file) + $files[] = $file['id']; + + $info = array('msgId' => $msgId, + 'response' => $this->replaceVars($canned->getResponse()), + 'cannedattachments' => $files); + + return $this->postReply($info, $errors, $alert); + } + /* public */ function postReply($vars, $errors, $alert = true) { global $thisstaff, $cfg; @@ -2063,18 +2080,15 @@ class Ticket { //Auto assign staff or team - auto assignment based on filter rules. if($vars['staffId'] && !$vars['assignId']) - $ticket->assignToStaff($vars['staffId'],'auto-assignment'); + $ticket->assignToStaff($vars['staffId'], 'Auto Assignment'); if($vars['teamId'] && !$vars['assignId']) - $ticket->assignToTeam($vars['teamId'],'auto-assignment'); + $ticket->assignToTeam($vars['teamId'], 'Auto Assignment'); /********** double check auto-response ************/ //Overwrite auto responder if the FROM email is one of the internal emails...loop control. if($autorespond && (Email::getIdByEmail($ticket->getEmail()))) $autorespond=false; - if($autorespond && $dept && !$dept->autoRespONNewTicket()) - $autorespond=false; - # Messages that are clearly auto-responses from email systems should # not have a return 'ping' message if ($autorespond && $vars['header'] && @@ -2089,25 +2103,18 @@ class Ticket { $autorespond=false; } + //post canned auto-response IF any (disables new ticket auto-response). if ($vars['cannedResponseId'] - && ($canned = Canned::lookup($vars['cannedResponseId'])) - && $canned->isEnabled()) { - $files = array(); - foreach ($canned->getAttachments() as $file) - $files[] = $file['id']; - $ticket->postReply( - array( - 'msgId' => $msgid, - 'response' => - $ticket->replaceVars($canned->getResponse()), - 'cannedattachments' => $files - ),$errors, true); - - // If a canned-response is immediately queued for this ticket, - // disable the autoresponse - $autorespond=false; + && $ticket->postCannedReply($vars['cannedResponseId'], $msgid, $autorespond)) { + $ticket->markUnAnswered(); //Leave the ticket as unanswred. + $autorespond = false; } + //Check department's auto response settings + // XXX: Dept. setting doesn't affect canned responses. + if($autorespond && $dept && !$dept->autoRespONNewTicket()) + $autorespond=false; + /***** See if we need to send some alerts ****/ $ticket->onNewTicket($vars['message'], $autorespond, $alertstaff); diff --git a/include/client/view.inc.php b/include/client/view.inc.php index ccea4c927cfdf31793ae325f79572a743fa35f26..fa8a5b4a5420df21565f463b79c59ac33ecceca7 100644 --- a/include/client/view.inc.php +++ b/include/client/view.inc.php @@ -65,7 +65,7 @@ if($ticket->getThreadCount() && ($thread=$ticket->getClientThread())) { //Making sure internal notes are not displayed due to backend MISTAKES! if(!$threadType[$entry['thread_type']]) continue; $poster = $entry['poster']; - if($entry['thread_type']=='R' && $cfg->hideStaffName()) + if($entry['thread_type']=='R' && ($cfg->hideStaffName() || !$entry['staff_id'])) $poster = ' '; ?> <table class="<?php echo $threadType[$entry['thread_type']]; ?>" cellspacing="0" cellpadding="1" width="800" border="0">