From f9e9da44d22bb420900cdf3288e48fa34b2bb512 Mon Sep 17 00:00:00 2001 From: Peter Rotich <peter@osticket.com> Date: Fri, 11 Sep 2015 18:10:47 -0500 Subject: [PATCH] bug: Collaborators notice Fix case where collaborators were not being alerted Alert admin last on new ticket - just in case admin email is used by an agent. --- include/class.mailer.php | 21 +++++++++++++++++---- include/class.mailparse.php | 18 +++++++++--------- include/class.task.php | 2 +- include/class.thread.php | 12 ++++++++++-- include/class.ticket.php | 28 ++++++++++++++++++---------- 5 files changed, 55 insertions(+), 26 deletions(-) diff --git a/include/class.mailer.php b/include/class.mailer.php index 49b15ec28..ee22db849 100644 --- a/include/class.mailer.php +++ b/include/class.mailer.php @@ -150,14 +150,27 @@ class Mailer { $thread = $entry ? $entry->getThread() : (isset($options['thread']) && $options['thread'] instanceof Thread ? $options['thread'] : false); + + switch (true) { + case $recipient instanceof Staff: + $utype = 'S'; + break; + case $recipient instanceof TicketOwner: + $utype = 'U'; + break; + case $recipient instanceof Collaborator: + $utype = 'C'; + break; + default: + $utype = $options['utype'] ?: '?'; + } + + $tag = pack('VVVa', $recipient instanceof EmailContact ? $recipient->getUserId() : 0, $entry ? $entry->getId() : 0, $thread ? $thread->getId() : 0, - ($recipient instanceof Staff ? 'S' - : ($recipient instanceof TicketOwner ? 'U' - : ($recipient instanceof Collaborator ? 'C' - : '?'))) + $utype ?: '?' ); // Sign the tag with the system secret salt $tag .= substr(hash_hmac('sha1', $tag.$rand.$sysid, SECRET_SALT, true), -5); diff --git a/include/class.mailparse.php b/include/class.mailparse.php index f530ac50b..1efd5a8b1 100644 --- a/include/class.mailparse.php +++ b/include/class.mailparse.php @@ -208,14 +208,14 @@ class Mail_Parse { if (!($header = $this->struct->headers['from'])) return null; - return Mail_Parse::parseAddressList($header); + return Mail_Parse::parseAddressList($header, $this->charset); } function getDeliveredToAddressList() { if (!($header = $this->struct->headers['delivered-to'])) return null; - return Mail_Parse::parseAddressList($header); + return Mail_Parse::parseAddressList($header, $this->charset); } function getToAddressList(){ @@ -223,7 +223,7 @@ class Mail_Parse { $tolist = array(); if ($header = $this->struct->headers['to']) $tolist = array_merge($tolist, - Mail_Parse::parseAddressList($header)); + Mail_Parse::parseAddressList($header, $this->charset)); return $tolist ? $tolist : null; } @@ -231,14 +231,14 @@ class Mail_Parse { if (!($header = @$this->struct->headers['cc'])) return null; - return Mail_Parse::parseAddressList($header); + return Mail_Parse::parseAddressList($header, $this->charset); } function getBccAddressList(){ if (!($header = @$this->struct->headers['bcc'])) return null; - return Mail_Parse::parseAddressList($header); + return Mail_Parse::parseAddressList($header, $this->charset); } function getMessageId(){ @@ -258,7 +258,7 @@ class Mail_Parse { if (!($header = @$this->struct->headers['reply-to'])) return null; - return Mail_Parse::parseAddressList($header); + return Mail_Parse::parseAddressList($header, $this->charset); } function isBounceNotice() { @@ -543,7 +543,7 @@ class Mail_Parse { return 0; } - function parseAddressList($address){ + function parseAddressList($address, $charset='UTF-8'){ if (!$address) return array(); @@ -558,11 +558,11 @@ class Mail_Parse { // Decode name and mailbox foreach ($parsed as $p) { - $p->personal = Format::mimedecode($p->personal, $this->charset); + $p->personal = Format::mimedecode($p->personal, $charset); // Some mail clients may send ISO-8859-1 strings without proper encoding. // Also, handle the more sane case where the mailbox is properly encoded // against RFC2047 - $p->mailbox = Format::mimedecode($p->mailbox, $this->charset); + $p->mailbox = Format::mimedecode($p->mailbox, $charset); } return $parsed; diff --git a/include/class.task.php b/include/class.task.php index 55671d1af..f327a6cb1 100644 --- a/include/class.task.php +++ b/include/class.task.php @@ -1078,7 +1078,7 @@ class Task extends TaskModel implements RestrictedAccess, Threadable { // Who posted the entry? $skip = array(); - if ($entry instanceof Message) { + if ($entry instanceof MessageThreadEntry) { $poster = $entry->getUser(); // Skip the person who sent in the message $skip[$entry->getUserId()] = 1; diff --git a/include/class.thread.php b/include/class.thread.php index 5e3ef13a6..aa78db5dd 100644 --- a/include/class.thread.php +++ b/include/class.thread.php @@ -348,7 +348,6 @@ class Thread extends VerySimpleModel { $vars['attachments'] = $mailinfo['attachments']; $body = $mailinfo['message']; - $poster = $mailinfo['email']; // Attempt to determine the user posting the entry and the // corresponding entry type by the information determined by the @@ -403,6 +402,10 @@ class Thread extends VerySimpleModel { } } + // Ensure we record the name of the person posting + $vars['poster'] = $vars['poster'] + ?: $mailinfo['name'] ?: $mailinfo['email']; + // TODO: Consider security constraints if (!$vars['thread-type']) { //XXX: Are we potentially leaking the email address to @@ -432,7 +435,6 @@ class Thread extends VerySimpleModel { case 'N': $vars['note'] = $body; - $vars['poster'] = $vars['poster'] ?: $poster; if ($object instanceof Threadable) return $object->postThreadEntry('N', $vars); @@ -1180,6 +1182,12 @@ implements TemplateVariable { elseif (@$mid_info['staffId']) { $mailinfo['staffId'] = $mid_info['staffId']; } + + // Capture the user type + if (@$mid_info['userClass']) + $mailinfo['userClass'] = $mid_info['userClass']; + + // ThreadEntry was positively identified return $t; } diff --git a/include/class.ticket.php b/include/class.ticket.php index c93b9856a..55e3f9fbb 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -1275,21 +1275,16 @@ implements RestrictedAccess, Threadable { if ($message instanceof ThreadEntry && $message->isAutoReply()) $sentlist[] = $this->getEmail(); - // Alert admin?? - if ($cfg->alertAdminONNewTicket()) { - $alert = $this->replaceVars($msg, array('recipient' => 'Admin')); - $email->sendAlert($cfg->getAdminEmail(), $alert['subj'], $alert['body'], null, $options); - $sentlist[]=$cfg->getAdminEmail(); - } - // Only alerts dept members if the ticket is NOT assigned. if ($cfg->alertDeptMembersONNewTicket() && !$this->isAssigned()) { if ($members = $dept->getMembersForAlerts()->all()) $recipients = array_merge($recipients, $members); } - if ($cfg->alertDeptManagerONNewTicket() && $dept && ($manager=$dept->getManager())) + if ($cfg->alertDeptManagerONNewTicket() && $dept && + ($manager=$dept->getManager())) { $recipients[] = $manager; + } // Account manager if ($cfg->alertAcctManagerONNewMessage() @@ -1313,6 +1308,16 @@ implements RestrictedAccess, Threadable { $email->sendAlert($staff, $alert['subj'], $alert['body'], null, $options); $sentlist[] = $staff->getEmail(); } + + // Alert admin ONLY if not already a staff?? + if ($cfg->alertAdminONNewTicket() + && !in_array($cfg->getAdminEmail(), $sentlist)) { + $options += array('utype'=>'A'); + $alert = $this->replaceVars($msg, array('recipient' => 'Admin')); + $email->sendAlert($cfg->getAdminEmail(), $alert['subj'], + $alert['body'], null, $options); + } + } return true; } @@ -1388,7 +1393,7 @@ implements RestrictedAccess, Threadable { } // Who posted the entry? $skip = array(); - if ($entry instanceof Message) { + if ($entry instanceof MessageThreadEntry) { $poster = $entry->getUser(); // Skip the person who sent in the message $skip[$entry->getUserId()] = 1; @@ -2478,7 +2483,10 @@ implements RestrictedAccess, Threadable { global $cfg, $thisstaff; //Who is posting the note - staff or system? - $vars['staffId'] = 0; + if ($vars['staffId'] && !$poster) + $poster = Staff::lookup($vars['staffId']); + + $vars['staffId'] = $vars['staffId'] ?: 0; if ($poster && is_object($poster)) { $vars['staffId'] = $poster->getId(); $vars['poster'] = $poster->getName(); -- GitLab