Newer
Older
//Exclude the auto responding email just incase it's from staff member.
if ($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);
Peter Rotich
committed
//Only alerts dept members if the ticket is NOT assigned.
if($cfg->alertDeptMembersONNewTicket() && !$this->isAssigned()) {
if(($members=$dept->getMembersForAlerts()))
$recipients=array_merge($recipients, $members);
}
Peter Rotich
committed
if($cfg->alertDeptManagerONNewTicket() && $dept && ($manager=$dept->getManager()))
$recipients[]= $manager;
Peter Rotich
committed
// Account manager
if ($cfg->alertAcctManagerONNewMessage()
&& ($org = $this->getOwner()->getOrganization())
&& ($acct_manager = $org->getAccountManager())) {
if ($acct_manager instanceof Team)
$recipients = array_merge($recipients, $acct_manager->getMembers());
else
$recipients[] = $acct_manager;
}
Peter Rotich
committed
foreach( $recipients as $k=>$staff) {
if(!is_object($staff) || !$staff->isAvailable() || in_array($staff->getEmail(), $sentlist)) continue;
$alert = $this->replaceVars($msg, array('recipient' => $staff));
$email->sendAlert($staff->getEmail(), $alert['subj'], $alert['body'], null, $options);
Peter Rotich
committed
global $ost, $cfg;
//Log the limit notice as a warning for admin.
$msg=sprintf(_S('Maximum open tickets (%1$d) reached for %2$s'),
$cfg->getMaxOpenTickets(), $this->getEmail());
$ost->logWarning(sprintf(_S('Maximum Open Tickets Limit (%s)'),$this->getEmail()),
$msg);
if(!$sendNotice || !$cfg->sendOverLimitNotice())
return true;
if(($dept = $this->getDept())
&& ($tpl=$dept->getTemplate())
&& ($msg=$tpl->getOverlimitMsgTemplate())
&& ($email=$dept->getAutoRespEmail())) {
Peter Rotich
committed
$msg = $this->replaceVars($msg->asArray(),
array('signature' => ($dept && $dept->isPublic())?$dept->getSignature():''));
Peter Rotich
committed
$email->sendAutoReply($this->getEmail(), $msg['subj'], $msg['body']);
$user = $this->getOwner();
Peter Rotich
committed
//Alert admin...this might be spammy (no option to disable)...but it is helpful..I think.
$alert=sprintf(__('Maximum open tickets reached for %s.'), $this->getEmail())."\n"
.sprintf(__('Open tickets: %d'), $user->getNumOpenTickets())."\n"
.sprintf(__('Max allowed: %d'), $cfg->getMaxOpenTickets())
."\n\n".__("Notice sent to the user.");
Peter Rotich
committed
$ost->alertAdmin(__('Overlimit Notice'), $alert);
Peter Rotich
committed
Peter Rotich
committed
function onResponse() {
db_query('UPDATE '.TICKET_TABLE.' SET isanswered=1, lastresponse=NOW(), updated=NOW() WHERE ticket_id='.db_input($this->getId()));
$this->reload();
}
/*
* Notify collaborators on response or new message
*
*/
function notifyCollaborators($entry, $vars = array()) {
if (!$entry instanceof ThreadEntry
|| !($dept=$this->getDept())
|| !($tpl=$dept->getTemplate())
|| !($msg=$tpl->getActivityNoticeMsgTemplate())
|| !($email=$dept->getEmail()))
return;
//Who posted the entry?
$uid = 0;
if ($entry instanceof Message) {
$poster = $entry->getUser();
// Skip the person who sent in the message
$uid = $entry->getUserId();
$poster = $entry->getStaff();
// Skip the ticket owner
$uid = $this->getUserId();
}
$vars = array_merge($vars, array(
'message' => (string) $entry,
'poster' => $poster ?: _S('A collaborator'),
)
);
$msg = $this->replaceVars($msg->asArray(), $vars);
$attachments = $cfg->emailAttachments()?$entry->getAttachments():array();
$options = array('inreplyto' => $entry->getEmailMessageId(),
'thread' => $entry);
foreach ($recipients as $recipient) {
if ($uid == $recipient->getUserId()) continue;
$options['references'] = $entry->getEmailReferencesForUser($recipient);
$notice = $this->replaceVars($msg, array('recipient' => $recipient));
$email->send($recipient->getEmail(), $notice['subj'], $notice['body'], $attachments,
$options);
}
return;
function onMessage($message, $autorespond=true) {
global $cfg;
db_query('UPDATE '.TICKET_TABLE.' SET isanswered=0,lastmessage=NOW() WHERE ticket_id='.db_input($this->getId()));
Peter Rotich
committed
// Auto-assign to closing staff or last respondent
// If the ticket is closed and auto-claim is not enabled then put the
// ticket back to unassigned pool.
if ($this->isClosed() && !$cfg->autoClaimTickets()) {
$this->setStaffId(0);
} elseif(!($staff=$this->getStaff()) || !$staff->isAvailable()) {
// Ticket has no assigned staff - if auto-claim is enabled then
// try assigning it to the last respondent (if available)
// otherwise leave the ticket unassigned.
if ($cfg->autoClaimTickets() //Auto claim is enabled.
&& ($lastrep=$this->getLastRespondent())
&& $lastrep->isAvailable()) {
$this->setStaffId($lastrep->getId()); //direct assignment;
} else {
$this->setStaffId(0); //unassign - last respondent is not available.
}
}
// Reopen if closed AND reopenable
if ($this->isClosed() && $this->isReopenable())
$this->reopen();
/********** double check auto-response ************/
if (!($user = $message->getUser()))
$autorespond=false;
elseif ($autorespond && (Email::getIdByEmail($user->getEmail())))
elseif ($autorespond && ($dept=$this->getDept()))
$autorespond=$dept->autoRespONNewMessage();
if(!$autorespond
|| !$cfg->autoRespONNewMessage()
|| !$message) return; //no autoresp or alerts.
$dept = $this->getDept();
$email = $dept->getAutoRespEmail();
Peter Rotich
committed
//If enabled...send confirmation to user. ( New Message AutoResponse)
if($email
&& ($tpl=$dept->getTemplate())
&& ($msg=$tpl->getNewMessageAutorepMsgTemplate())) {
$msg = $this->replaceVars($msg->asArray(),
array(
'recipient' => $user,
'signature' => ($dept && $dept->isPublic())?$dept->getSignature():''));
'inreplyto'=>$message->getEmailMessageId(),
'references' => $message->getEmailReferencesForUser($user),
'thread'=>$message);
$email->sendAutoReply($user->getEmail(), $msg['subj'], $msg['body'],
function onAssign($assignee, $comments, $alert=true) {
if($this->isClosed()) $this->reopen(); //Assigned tickets must be open - otherwise why assign?
//Assignee must be an object of type Staff or Team
if(!$assignee || !is_object($assignee)) return false;
$comments = $comments ?: _S('Ticket assignment');
$assigner = $thisstaff ?: _S('SYSTEM (Auto Assignment)');
Peter Rotich
committed
//Log an internal note - no alerts on the internal note.
$note = $this->logNote(
sprintf(_S('Ticket Assigned to %s'), $assignee->getName()),
$comments, $assigner, false);
//See if we need to send alerts
if(!$alert || !$cfg->alertONAssignment()) return true; //No alerts!
$dept = $this->getDept();
if(!$dept
|| !($tpl = $dept->getTemplate())
|| !($email = $cfg->getAlertEmail()))
return true;
//recipients
$recipients=array();
if ($assignee instanceof Staff) {
if ($cfg->alertStaffONAssignment())
} elseif (($assignee instanceof Team) && $assignee->alertsEnabled()) {
if ($cfg->alertTeamMembersONAssignment() && ($members=$assignee->getMembers()))
$recipients = array_merge($recipients, $members);
elseif ($cfg->alertTeamLeadONAssignment() && ($lead=$assignee->getTeamLead()))
if ($recipients
&& ($msg=$tpl->getAssignedAlertMsgTemplate())) {
$msg = $this->replaceVars($msg->asArray(),
array('comments' => $comments,
'assignee' => $assignee,
'assigner' => $assigner
'inreplyto'=>$note->getEmailMessageId(),
'references'=>$note->getEmailReferences(),
'thread'=>$note);
Peter Rotich
committed
if(!is_object($staff) || !$staff->isAvailable() || in_array($staff->getEmail(), $sentlist)) continue;
$alert = $this->replaceVars($msg, array('recipient' => $staff));
$email->sendAlert($staff->getEmail(), $alert['subj'], $alert['body'], null, $options);
function onOverdue($whine=true, $comments="") {
if($whine && ($sla=$this->getSLA()) && !$sla->alertOnOverdue())
$whine = false;
if(!$whine
|| !$cfg->alertONOverdueTicket()
|| !($dept = $this->getDept()))
return true;
//Get the message template
if(($tpl = $dept->getTemplate())
&& ($msg=$tpl->getOverdueAlertMsgTemplate())
&& ($email=$cfg->getAlertEmail())) {
Peter Rotich
committed
$msg = $this->replaceVars($msg->asArray(),
array('comments' => $comments));
//recipients
$recipients=array();
//Assigned staff or team... if any
if($this->isAssigned() && $cfg->alertAssignedONOverdueTicket()) {
if($this->getStaffId())
$recipients[]=$this->getStaff();
elseif($this->getTeamId() && ($team=$this->getTeam()) && ($members=$team->getMembers()))
$recipients=array_merge($recipients, $members);
} elseif($cfg->alertDeptMembersONOverdueTicket() && !$this->isAssigned()) {
//Only alerts dept members if the ticket is NOT assigned.
if ($members = $dept->getMembersForAlerts())
$recipients = array_merge($recipients, $members);
}
//Always alert dept manager??
if($cfg->alertDeptManagerONOverdueTicket() && $dept && ($manager=$dept->getManager()))
$recipients[]= $manager;
$sentlist=array();
Peter Rotich
committed
foreach( $recipients as $k=>$staff) {
if(!is_object($staff) || !$staff->isAvailable() || in_array($staff->getEmail(), $sentlist)) continue;
$alert = $this->replaceVars($msg, array('recipient' => $staff));
$email->sendAlert($staff->getEmail(), $alert['subj'], $alert['body'], null);
Peter Rotich
committed
Peter Rotich
committed
//ticket obj as variable = ticket number.
function asVar() {
return $this->getNumber();
if($tag && is_callable(array($this, 'get'.ucfirst($tag))))
return call_user_func(array($this, 'get'.ucfirst($tag)));
switch(mb_strtolower($tag)) {
case 'phone_number':
return $this->getPhoneNumber();
break;
case 'auth_token':
return $this->getAuthToken();
break;
case 'client_link':
return sprintf('%s/view.php?t=%s',
$cfg->getBaseUrl(), $this->getNumber());
break;
case 'staff_link':
return sprintf('%s/scp/tickets.php?id=%d', $cfg->getBaseUrl(), $this->getId());
break;
case 'create_date':
return Format::datetime($this->getCreateDate(), true, 'UTC');
break;
case 'due_date':
$duedate ='';
if($this->getEstDueDate())
$duedate = Format::datetime($this->getEstDueDate(), true, 'UTC');
$closedate ='';
if($this->isClosed())
$closedate = Format::datetime($this->getCloseDate(), true, 'UTC');
case 'user':
return $this->getOwner();
break;
default:
if (isset($this->_answers[$tag]))
// The answer object is retrieved here which will
// automatically invoke the toString() method when the
// answer is coerced into text
return $this->_answers[$tag];
return false;
}
//Replace base variables.
function replaceVars($input, $vars = array()) {
global $ost;
$vars = array_merge($vars, array('ticket' => $this));
return $ost->replaceTemplateVariables($input, $vars);
}
function markUnAnswered() {
return (!$this->isAnswered() || $this->setAnsweredState(0));
}
function markAnswered() {
return ($this->isAnswered() || $this->setAnsweredState(1));
}
function markOverdue($whine=true) {
Peter Rotich
committed
Peter Rotich
committed
if($this->isOverdue())
return true;
$sql='UPDATE '.TICKET_TABLE.' SET isoverdue=1, updated=NOW() '
.' WHERE ticket_id='.db_input($this->getId());
if(!db_query($sql) || !db_affected_rows())
return false;
$this->logEvent('overdue');
Peter Rotich
committed
if(!$this->isOverdue())
Peter Rotich
committed
//NOTE: Previously logged overdue event is NOT annuled.
$sql='UPDATE '.TICKET_TABLE.' SET isoverdue=0, updated=NOW() ';
Peter Rotich
committed
if($this->getDueDate() && Misc::db2gmtime($this->getDueDate()) <= Misc::gmtime())
Peter Rotich
committed
//Clear SLA if est. due date is in the past
if($this->getSLADueDate() && Misc::db2gmtime($this->getSLADueDate()) <= Misc::gmtime())
Peter Rotich
committed
$sql.=', sla_id=0 ';
$sql.=' WHERE ticket_id='.db_input($this->getId());
return (db_query($sql) && db_affected_rows());
}
Peter Rotich
committed
//Dept Tranfer...with alert.. done by staff
function transfer($deptId, $comments, $alert = true) {
Peter Rotich
committed
Peter Rotich
committed
if(!$thisstaff || !$thisstaff->canTransferTickets())
$currentDept = $this->getDeptName(); //Current department
if(!$deptId || !$this->setDeptId($deptId))
return false;
Peter Rotich
committed
// Reopen ticket if closed
if($this->isClosed()) $this->reopen();
$this->reload();
// Set SLA of the new department
if(!$this->getSLAId() || $this->getSLA()->isTransient())
$this->selectSLAId();
Peter Rotich
committed
/*** log the transfer comments as internal note - with alerts disabled - ***/
$title=sprintf(_S('Ticket transferred from %1$s to %2$s'),
$currentDept, $this->getDeptName());
Peter Rotich
committed
$comments=$comments?$comments:$title;
$note = $this->logNote($title, $comments, $thisstaff, false);
Peter Rotich
committed
if(!$alert || !$cfg->alertONTransfer() || !($dept=$this->getDept()))
return true; //no alerts!!
if(($email=$cfg->getAlertEmail())
&& ($tpl = $dept->getTemplate())
&& ($msg=$tpl->getTransferAlertMsgTemplate())) {
Peter Rotich
committed
$msg = $this->replaceVars($msg->asArray(),
array('comments' => $comments, 'staff' => $thisstaff));
Peter Rotich
committed
//recipients
$recipients=array();
//Assigned staff or team... if any
if($this->isAssigned() && $cfg->alertAssignedONTransfer()) {
if($this->getStaffId())
$recipients[]=$this->getStaff();
elseif($this->getTeamId() && ($team=$this->getTeam()) && ($members=$team->getMembers()))
$recipients = array_merge($recipients, $members);
} elseif($cfg->alertDeptMembersONTransfer() && !$this->isAssigned()) {
//Only alerts dept members if the ticket is NOT assigned.
if(($members=$dept->getMembersForAlerts()))
$recipients = array_merge($recipients, $members);
}
//Always alert dept manager??
if($cfg->alertDeptManagerONTransfer() && $dept && ($manager=$dept->getManager()))
$recipients[]= $manager;
Peter Rotich
committed
'inreplyto'=>$note->getEmailMessageId(),
'references'=>$note->getEmailReferences(),
'thread'=>$note);
Peter Rotich
committed
foreach( $recipients as $k=>$staff) {
if(!is_object($staff) || !$staff->isAvailable() || in_array($staff->getEmail(), $sentlist)) continue;
$alert = $this->replaceVars($msg, array('recipient' => $staff));
$email->sendAlert($staff->getEmail(), $alert['subj'], $alert['body'], null, $options);
}
}
return true;
}
function assignToStaff($staff, $note, $alert=true) {
if(!is_object($staff) && !($staff=Staff::lookup($staff)))
return false;
Peter Rotich
committed
if (!$staff->isAvailable() || !$this->setStaffId($staff->getId()))
$this->logEvent('assigned');
return true;
}
function assignToTeam($team, $note, $alert=true) {
if(!is_object($team) && !($team=Team::lookup($team)))
return false;
if (!$team->isActive() || !$this->setTeamId($team->getId()))
return false;
//Clear - staff if it's a closed ticket
// staff_id is overloaded -> assigned to & closed by.
if($this->isClosed())
$this->setStaffId(0);
$this->logEvent('assigned');
return true;
}
//Assign ticket to staff or team - overloaded ID.
function assign($assignId, $note, $alert=true) {
global $thisstaff;
$rv=0;
Peter Rotich
committed
$id=preg_replace("/[^0-9]/", "", $assignId);
if($assignId[0]=='t') {
$rv=$this->assignToTeam($id, $note, $alert);
} elseif($assignId[0]=='s' || is_numeric($assignId)) {
$alert=($alert && $thisstaff && $thisstaff->getId()==$id)?false:$alert; //No alerts on self assigned tickets!!!
//We don't care if a team is already assigned to the ticket - staff assignment takes precedence
$rv=$this->assignToStaff($id, $note, $alert);
}
return $rv;
}
Peter Rotich
committed
//unassign primary assignee
function unassign() {
if(!$this->isAssigned()) //We can't release what is not assigned buddy!
return true;
//We can only unassigned OPEN tickets.
if($this->isClosed())
return false;
//Unassign staff (if any)
if($this->getStaffId() && !$this->setStaffId(0))
return false;
//unassign team (if any)
if($this->getTeamId() && !$this->setTeamId(0))
return false;
$this->reload();
return true;
}
Peter Rotich
committed
function release() {
return $this->unassign();
}
//Change ownership
function changeOwner($user) {
global $thisstaff;
if (!$user
|| ($user->getId() == $this->getOwnerId())
|| !$thisstaff->canEditTickets())
return false;
$sql ='UPDATE '.TICKET_TABLE.' SET updated = NOW() '
.', user_id = '.db_input($user->getId())
.' WHERE ticket_id = '.db_input($this->getId());
if (!db_query($sql) || !db_affected_rows())
return false;
$this->ht['user_id'] = $user->getId();
$this->user = null;
$this->collaborators = null;
$this->recipients = null;
//Log an internal note
$note = sprintf(_S('%s changed ticket ownership to %s'),
$thisstaff->getName(), $user->getName());
//Remove the new owner from list of collaborators
$c = Collaborator::lookup(array('userId' => $user->getId(),
'ticketId' => $this->getId()));
if ($c && $c->remove())
$note.= ' '._S('(removed as collaborator)');
$this->logNote('Ticket ownership changed', $note);
return true;
}
function postMessage($vars, $origin='', $alerts=true) {
$vars['ip_address'] = $vars['ip'];
elseif(!$vars['ip_address'] && $_SERVER['REMOTE_ADDR'])
$vars['ip_address'] = $_SERVER['REMOTE_ADDR'];
$errors = array();
if(!($message = $this->getThread()->addMessage($vars, $errors)))
return null;
$this->setLastMessage($message);
//Add email recipients as collaborators...
if ($vars['recipients']
&& (strtolower($origin) != 'email' || ($cfg && $cfg->addCollabsViaEmail()))
//Only add if we have a matched local address
&& $vars['to-email-id']) {
//New collaborators added by other collaborators are disable --
// requires staff approval.
$info = array(
'isactive' => ($message->getUserId() == $this->getUserId())? 1: 0);
$collabs = array();
foreach ($vars['recipients'] as $recipient) {
// Skip virtual delivered-to addresses
if (strcasecmp($recipient['source'], 'delivered-to') === 0)
continue;
if (($user=User::fromVars($recipient)))
if ($c=$this->addCollaborator($user, $info, $errors))
(string) $c,
$recipient['source']
? " ".sprintf(_S('via %s'), $recipient['source'])
: ''
);
}
//TODO: Can collaborators add others?
if ($collabs) {
//TODO: Change EndUser to name of user.
$this->logNote(_S('Collaborators added by end user'),
implode("<br>", $collabs), _S('End User'), false);
if(!$alerts) return $message; //Our work is done...
// Do not auto-respond to bounces and other auto-replies
$autorespond = isset($vars['flags'])
? !$vars['flags']['bounce'] && !$vars['flags']['auto-reply']
: true;
if ($autorespond && $message->isAutoReply())
$autorespond = false;
$this->onMessage($message, $autorespond); //must be called b4 sending alerts to staff.
if ($autorespond && $cfg && $cfg->notifyCollabsONNewMessage())
$this->notifyCollaborators($message, array('signature' => ''));
$variables = array(
'message' => $message,
'poster' => ($vars['poster'] ? $vars['poster'] : $this->getName())
);
$options = array(
'inreplyto' => $message->getEmailMessageId(),
'references' => $message->getEmailReferences(),
'thread'=>$message);
//If enabled...send alert to staff (New Message Alert)
if($cfg->alertONNewMessage()
&& ($email = $cfg->getAlertEmail())
&& ($tpl = $dept->getTemplate())
&& ($msg = $tpl->getNewMessageAlertMsgTemplate())) {
$msg = $this->replaceVars($msg->asArray(), $variables);
//Build list of recipients and fire the alerts.
$recipients=array();
//Last respondent.
if($cfg->alertLastRespondentONNewMessage() || $cfg->alertAssignedONNewMessage())
$recipients[]=$this->getLastRespondent();
Peter Rotich
committed
//Assigned staff if any...could be the last respondent
Peter Rotich
committed
if($this->isAssigned() && ($staff=$this->getStaff()))
$recipients[]=$staff;
Peter Rotich
committed
//Dept manager
if($cfg->alertDeptManagerONNewMessage() && $dept && ($manager=$dept->getManager()))
$recipients[]=$manager;
Peter Rotich
committed
// Account manager
if ($cfg->alertAcctManagerONNewMessage()
&& ($org = $this->getOwner()->getOrganization())
&& ($acct_manager = $org->getAccountManager())) {
if ($acct_manager instanceof Team)
$recipients = array_merge($recipients, $acct_manager->getMembers());
else
$recipients[] = $acct_manager;
}
$sentlist=array(); //I know it sucks...but..it works.
Peter Rotich
committed
foreach( $recipients as $k=>$staff) {
if(!$staff || !$staff->getEmail() || !$staff->isAvailable() || in_array($staff->getEmail(), $sentlist)) continue;
$alert = $this->replaceVars($msg, array('recipient' => $staff));
$email->sendAlert($staff->getEmail(), $alert['subj'], $alert['body'], null, $options);
return $message;
function postCannedReply($canned, $msgId, $alert=true) {
if((!is_object($canned) && !($canned=Canned::lookup($canned))) || !$canned->isEnabled())
return false;
$files = array();
foreach ($canned->attachments->getAll() as $file)
if ($cfg->isHtmlThreadEnabled())
$response = new HtmlThreadBody(
$this->replaceVars($canned->getHtml()));
else
$this->replaceVars($canned->getPlainText()));
'poster' => __('SYSTEM (Canned Reply)'),
if(!($response=$this->postReply($info, $errors, false)))
return null;
if(!$alert) return $response;
if(($email=$dept->getEmail())
&& ($tpl = $dept->getTemplate())
&& ($msg=$tpl->getAutoReplyMsgTemplate())) {
if($dept && $dept->isPublic())
$signature=$dept->getSignature();
else
$signature='';
$msg = $this->replaceVars($msg->asArray(),
array(
'response' => $response,
'signature' => $signature,
'recipient' => $this->getOwner(),
));
$attachments =($cfg->emailAttachments() && $files)?$response->getAttachments():array();
'inreplyto'=>$response->getEmailMessageId(),
'references'=>$response->getEmailReferences(),
'thread'=>$response);
$email->sendAutoReply($this->getEmail(), $msg['subj'], $msg['body'], $attachments,
$options);
return $response;
function postReply($vars, &$errors, $alert = true) {
if(!$vars['poster'] && $thisstaff)
$vars['poster'] = $thisstaff;
if(!$vars['staffId'] && $thisstaff)
$vars['staffId'] = $thisstaff->getId();
if(!($response = $this->getThread()->addResponse($vars, $errors)))
return null;
// Set status - if checked.
if ($vars['reply_status_id']
&& $vars['reply_status_id'] != $this->getStatusId())
$this->setStatus($vars['reply_status_id']);
if($thisstaff && $this->isOpen() && !$this->getStaffId()
&& $cfg->autoClaimTickets())
$this->setStaffId($thisstaff->getId()); //direct assignment;
$this->onResponse(); //do house cleaning..
/* email the user?? - if disabled - then bail out */
if(!$alert) return $response;
if($thisstaff && $vars['signature']=='mine')
$signature=$thisstaff->getSignature();
elseif($vars['signature']=='dept' && $dept && $dept->isPublic())
$signature=$dept->getSignature();
else
$signature='';
$variables = array(
'response' => $response,
'signature' => $signature,
'staff' => $thisstaff,
'poster' => $thisstaff);
$options = array(
'inreplyto' => $response->getEmailMessageId(),
'references' => $response->getEmailReferences(),
'thread'=>$response);
if(($email=$dept->getEmail())
&& ($tpl = $dept->getTemplate())
&& ($msg=$tpl->getReplyMsgTemplate())) {
$msg = $this->replaceVars($msg->asArray(),
$variables + array('recipient' => $this->getOwner()));
$attachments = $cfg->emailAttachments()?$response->getAttachments():array();
$email->send($this->getEmail(), $msg['subj'], $msg['body'], $attachments,
$options);
if($vars['emailcollab'])
$this->notifyCollaborators($response,
array('signature' => $signature));
return $response;
}
//Activity log - saved as internal notes WHEN enabled!!
Peter Rotich
committed
function logActivity($title, $note) {
return $this->logNote($title, $note, 'SYSTEM', false);
// History log -- used for statistics generation (pretty reports)
function logEvent($state, $annul=null, $staff=null) {
global $thisstaff;
if ($staff === null) {
if ($thisstaff) $staff=$thisstaff->getUserName();
else $staff='SYSTEM'; # XXX: Security Violation ?
}
# Annul previous entries if requested (for instance, reopening a
# ticket will annul an 'closed' entry). This will be useful to
# easily prevent repeated statistics.
if ($annul) {
db_query('UPDATE '.TICKET_EVENT_TABLE.' SET annulled=1'
.' WHERE ticket_id='.db_input($this->getId())
.' AND state='.db_input($annul));
}
return db_query('INSERT INTO '.TICKET_EVENT_TABLE
.' SET ticket_id='.db_input($this->getId())
.', staff_id='.db_input($this->getStaffId())
.', team_id='.db_input($this->getTeamId())
.', dept_id='.db_input($this->getDeptId())
.', topic_id='.db_input($this->getTopicId())
.', timestamp=NOW(), state='.db_input($state)
.', staff='.db_input($staff))
&& db_affected_rows() == 1;
}
function logNote($title, $note, $poster='SYSTEM', $alert=true) {
//Unless specified otherwise, assume HTML
if ($note && is_string($note))
$note = new HtmlThreadBody($note);
array(
'title' => $title,
'note' => $note,
),
$alert
);
function postNote($vars, &$errors, $poster, $alert=true) {
//Who is posting the note - staff or system?
$vars['staffId'] = 0;
$vars['poster'] = 'SYSTEM';
$vars['staffId'] = $poster->getId();
$vars['poster'] = $poster->getName();
}elseif($poster) { //string
$vars['poster'] = $poster;
if(!($note=$this->getThread()->addNote($vars, $errors)))
return null;
$alert = $alert && (
isset($vars['flags'])
// No alerts for bounce and auto-reply emails
? !$vars['flags']['bounce'] && !$vars['flags']['auto-reply']
: true
);
// Get assigned staff just in case the ticket is closed.
$assignee = $this->getStaff();
if ($vars['note_status_id']
&& ($status=TicketStatus::lookup($vars['note_status_id']))) {
if ($this->setStatus($status))
// If alerts are not enabled then return a success.
if(!$alert || !$cfg->alertONNewNote() || !($dept=$this->getDept()))
return $note;
if(($email=$cfg->getAlertEmail())
&& ($tpl = $dept->getTemplate())
&& ($msg=$tpl->getNoteAlertMsgTemplate())) {
Peter Rotich
committed
$msg = $this->replaceVars($msg->asArray(),
array('note' => $note));
Peter Rotich
committed
// Alert recipients
Peter Rotich
committed
if ($cfg->alertLastRespondentONNewNote())
$recipients[] = $this->getLastRespondent();
// Assigned staff / team
if ($cfg->alertAssignedONNewNote()) {
if ($assignee && $assignee instanceof Staff)
$recipients[] = $assignee;
Peter Rotich
committed
if ($team = $this->getTeam())
$recipients = array_merge($recipients, $team->getMembers());
}
Peter Rotich
committed
// Dept manager
if ($cfg->alertDeptManagerONNewNote() && $dept && $dept->getManagerId())
$recipients[] = $dept->getManager();
'inreplyto'=>$note->getEmailMessageId(),
'references'=>$note->getEmailReferences(),
'thread'=>$note);
$sentlist=array();
foreach( $recipients as $k=>$staff) {
Peter Rotich
committed
if(!is_object($staff)
// Don't bother vacationing staff.
|| !$staff->isAvailable()
// No duplicates.
|| isset($sentlist[$staff->getEmail()])
// No need to alert the poster!
|| $note->getStaffId() == $staff->getId()
// Make sure staff has access to ticket
|| ($isClosed && !$this->checkStaffAccess($staff))
)
Peter Rotich
committed
continue;
$alert = $this->replaceVars($msg, array('recipient' => $staff));
$email->sendAlert($staff->getEmail(), $alert['subj'], $alert['body'], null, $options);
$sentlist[$staff->getEmail()] = 1;