Newer
Older
<?php
/*********************************************************************
class.ticket.php
The most important class! Don't play with fire please.
Peter Rotich <peter@osticket.com>
http://www.osticket.com
Released under the GNU General Public License WITHOUT ANY WARRANTY.
See LICENSE.TXT for details.
vim: expandtab sw=4 ts=4 sts=4:
**********************************************************************/
include_once(INCLUDE_DIR.'class.thread.php');
include_once(INCLUDE_DIR.'class.client.php');
include_once(INCLUDE_DIR.'class.team.php');
include_once(INCLUDE_DIR.'class.email.php');
include_once(INCLUDE_DIR.'class.dept.php');
include_once(INCLUDE_DIR.'class.topic.php');
include_once(INCLUDE_DIR.'class.lock.php');
include_once(INCLUDE_DIR.'class.file.php');
include_once(INCLUDE_DIR.'class.attachment.php');
include_once(INCLUDE_DIR.'class.pdf.php');
include_once(INCLUDE_DIR.'class.banlist.php');
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.canned.php');
require_once(INCLUDE_DIR.'class.dynamic_forms.php');
require_once(INCLUDE_DIR.'class.user.php');
class Ticket {
Peter Rotich
committed
var $number;
var $ht;
Peter Rotich
committed
var $dept; //Dept obj
var $sla; // SLA obj
var $staff; //Staff obj
var $team; //Team obj
var $topic; //Topic obj
var $tlock; //TicketLock obj
var $thread; //Thread obj.
Peter Rotich
committed
function Ticket($id) {
Peter Rotich
committed
function load($id=0) {
if(!$id && !($id=$this->getId()))
return false;
.' ,IF(sla.id IS NULL, NULL, DATE_ADD(ticket.created, INTERVAL sla.grace_period HOUR)) as sla_duedate '
.' ,count(attach.attach_id) as attachments '
.' FROM '.TICKET_TABLE.' ticket '
.' LEFT JOIN '.DEPT_TABLE.' dept ON (ticket.dept_id=dept.dept_id) '
.' LEFT JOIN '.SLA_TABLE.' sla ON (ticket.sla_id=sla.id AND sla.isactive=1) '
.' LEFT JOIN '.TICKET_LOCK_TABLE.' tlock ON ('
.'ticket.ticket_id=tlock.ticket_id AND tlock.expire>NOW()) '
.' LEFT JOIN '.TICKET_ATTACHMENT_TABLE.' attach ON ('
.'ticket.ticket_id=attach.ticket_id) '
.' WHERE ticket.ticket_id='.db_input($id)
.' GROUP BY ticket.ticket_id';
//echo $sql;
if(!($res=db_query($sql)) || !db_num_rows($res))
return false;
Peter Rotich
committed
$this->ht = db_fetch_array($res);
Peter Rotich
committed
$this->number = $this->ht['ticketID'];
//Reset the sub classes (initiated ondemand)...good for reloads.
$this->staff = null;
$this->team = null;
$this->dept = null;
$this->sla = null;
$this->tlock = null;
$this->stats = null;
$this->topic = null;
$this->thread = null;
Peter Rotich
committed
//REQUIRED: Preload thread obj - checked on lookup!
$this->getThread();
Peter Rotich
committed
function loadDynamicData() {
$this->_answers = array();
foreach (DynamicFormEntry::forTicket($this->getId()) as $form)
foreach ($form->getAnswers() as $answer)
$this->_answers[$answer->getField()->get('name')] =
function reload() {
return $this->load();
}
Peter Rotich
committed
function isOpen() {
return (strcasecmp($this->getStatus(),'Open')==0);
}
function isReopened() {
return ($this->getReopenDate());
}
function isClosed() {
return (strcasecmp($this->getStatus(),'Closed')==0);
}
function isAssigned() {
return ($this->isOpen() && ($this->getStaffId() || $this->getTeamId()));
}
function isOverdue() {
Peter Rotich
committed
return ($this->ht['isoverdue']);
Peter Rotich
committed
function isAnswered() {
return ($this->ht['isanswered']);
}
function isLocked() {
return ($this->getLockId());
}
function checkStaffAccess($staff) {
if(!is_object($staff) && !($staff=Staff::lookup($staff)))
return false;
return ((!$staff->showAssignedOnly() && $staff->canAccessDept($this->getDeptId()))
|| ($this->getTeamId() && $staff->isTeamMember($this->getTeamId()))
|| $staff->getId()==$this->getStaffId());
}
function checkClientAccess($client) {
global $cfg;
if(!is_object($client) && !($client=Client::lookup($client)))
return false;
Peter Rotich
committed
if(!strcasecmp($client->getEmail(), $this->getEmail()))
Peter Rotich
committed
return ($cfg && $cfg->showRelatedTickets()
&& $client->getTicketId()==$this->getExtId());
function getId() {
function getExtId() {
Peter Rotich
committed
return $this->getNumber();
function getNumber() {
Peter Rotich
committed
return $this->number;
Peter Rotich
committed
function getOwnerId() {
return $this->ht['user_id'];
}
function getOwner() {
if (!isset($this->user))
$this->user = User::lookup($this->getOwnerId());
return $this->user;
}
if ($o = $this->getOwner())
return $o->getEmail();
return null;
}
function getReplyToEmail() {
if ($this->ht['user_email_id']) {
if (!isset($this->reply_email))
$this->reply_email = UserEmail::lookup($this->ht['user_email_id']);
return $this->reply_email->address;
}
else {
return $this->getEmail();
}
function getAuthToken() {
# XXX: Support variable email address (for CCs)
return md5($this->getId() . $this->getEmail() . SECRET_SALT);
}
}
/* Help topic title - NOT object -> $topic */
function getHelpTopic() {
Peter Rotich
committed
if(!$this->ht['helptopic'] && ($topic=$this->getTopic()))
$this->ht['helptopic'] = $topic->getName();
return $this->ht['helptopic'];
Peter Rotich
committed
function getCreateDate() {
return $this->ht['created'];
}
function getOpenDate() {
return $this->getCreateDate();
}
function getReopenDate() {
Peter Rotich
committed
return $this->ht['reopened'];
Peter Rotich
committed
function getUpdateDate() {
return $this->ht['updated'];
Peter Rotich
committed
function getDueDate() {
return $this->ht['duedate'];
function getSLADueDate() {
return $this->ht['sla_duedate'];
}
function getEstDueDate() {
//Real due date
if(($duedate=$this->getDueDate()))
return $duedate;
//return sla due date (If ANY)
return $this->getSLADueDate();
}
Peter Rotich
committed
function getCloseDate() {
return $this->ht['closed'];
Peter Rotich
committed
function getStatus() {
return $this->ht['status'];
Peter Rotich
committed
function getDeptId() {
return $this->ht['dept_id'];
Peter Rotich
committed
function getDeptName() {
if(!$this->ht['dept_name'] && ($dept = $this->getDept()))
$this->ht['dept_name'] = $dept->getName();
return $this->ht['dept_name'];
global $cfg;
if ($a = $this->_answers['priority'])
return $a->getId();
return $cfg->getDefaultPriorityId();
Peter Rotich
committed
function getPriority() {
if ($a = $this->_answers['priority'])
return $a->getDesc();
return '...ummm...';
Peter Rotich
committed
list($phone, $ext) = explode(" ", $this->_answers['phone'], 2);
return $phone;
list($phone, $ext) = explode(" ", $this->_answers['phone'], 2);
return $ext;
}
function getSource() {
return $this->ht['source'];
}
Peter Rotich
committed
function getIP() {
return $this->ht['ip_address'];
}
function getHashtable() {
return $this->ht;
}
function getUpdateInfo() {
'phone_ext' => $this->getPhoneExt(),
'source' => $this->getSource(),
'topicId' => $this->getTopicId(),
'priorityId' => $this->getPriorityId(),
'slaId' => $this->getSLAId(),
'duedate' => $this->getDueDate()?(Format::userdate('m/d/Y', Misc::db2gmtime($this->getDueDate()))):'',
'time' => $this->getDueDate()?(Format::userdate('G:i', Misc::db2gmtime($this->getDueDate()))):'',
);
Peter Rotich
committed
Peter Rotich
committed
return $this->ht['lock_id'];
Peter Rotich
committed
function getLock() {
Peter Rotich
committed
$this->tlock= TicketLock::lookup($this->getLockId(), $this->getId());
Peter Rotich
committed
Peter Rotich
committed
if(!$staffId or !$lockTime) //Lockig disabled?
return null;
//Check if the ticket is already locked.
if(($lock=$this->getLock()) && !$lock->isExpired()) {
if($lock->getStaffId()!=$staffId) //someone else locked the ticket.
return null;
//Lock already exits...renew it
$lock->renew($lockTime); //New clock baby.
Peter Rotich
committed
return $lock;
}
//No lock on the ticket or it is expired
Peter Rotich
committed
$this->tlock = null; //clear crap
$this->ht['lock_id'] = TicketLock::acquire($this->getId(), $staffId, $lockTime); //Create a new lock..
//load and return the newly created lock if any!
return $this->getLock();
}
Peter Rotich
committed
function getDept() {
if(!$this->dept && $this->getDeptId())
$this->dept= Dept::lookup($this->getDeptId());
return $this->dept;
}
function getClient() {
if(!$this->client)
$this->client = Client::lookup($this->getExtId(), $this->getEmail());
return $this->client;
}
Peter Rotich
committed
function getStaffId() {
return $this->ht['staff_id'];
Peter Rotich
committed
function getStaff() {
if(!$this->staff && $this->getStaffId())
$this->staff= Staff::lookup($this->getStaffId());
return $this->staff;
}
Peter Rotich
committed
function getTeamId() {
return $this->ht['team_id'];
Peter Rotich
committed
function getTeam() {
if(!$this->team && $this->getTeamId())
$this->team = Team::lookup($this->getTeamId());
return $this->team;
}
function getAssignee() {
if($staff=$this->getStaff())
return $staff->getName();
if($team=$this->getTeam())
return $team->getName();
return '';
}
Peter Rotich
committed
Peter Rotich
committed
function getAssigned($glue='/') {
$assignees = $this->getAssignees();
return $assignees?implode($glue, $assignees):'';
}
Peter Rotich
committed
return $this->ht['topic_id'];
Peter Rotich
committed
function getTopic() {
$this->topic = Topic::lookup($this->getTopicId());
Peter Rotich
committed
Peter Rotich
committed
return $this->ht['sla_id'];
}
function getSLA() {
if(!$this->sla && $this->getSLAId())
return $this->sla;
}
function getLastRespondent() {
$sql ='SELECT resp.staff_id '
.' FROM '.TICKET_THREAD_TABLE.' resp '
.' LEFT JOIN '.STAFF_TABLE. ' USING(staff_id) '
.' WHERE resp.ticket_id='.db_input($this->getId()).' AND resp.staff_id>0 '
.' AND resp.thread_type="R"'
.' ORDER BY resp.created DESC LIMIT 1';
if(!($res=db_query($sql)) || !db_num_rows($res))
return null;
Peter Rotich
committed
list($id)=db_fetch_row($res);
return Staff::lookup($id);
}
function getLastMessageDate() {
Peter Rotich
committed
return $this->ht['lastmessage'];
}
function getLastMsgDate() {
return $this->getLastMessageDate();
}
function getLastResponseDate() {
Peter Rotich
committed
return $this->ht['lastresponse'];
}
function getLastRespDate() {
return $this->getLastResponseDate();
}
Peter Rotich
committed
function getLastMsgId() {
return $this->lastMsgId;
}
function getLastMessage() {
if($this->getLastMsgId())
return Message::lookup($this->getLastMsgId(), $this->getId());
return Message::lastByTicketId($this->getId());
}
function getThread() {
if(!$this->thread)
$this->thread = Thread::lookup($this);
return $this->thread;
}
function getThreadCount() {
return $this->getNumMessages() + $this->getNumResponses();
}
function getNumMessages() {
return $this->getThread()->getNumMessages();
return $this->getThread()->getNumResponses();
return $this->getThread()->getNumNotes();
return $this->getThreadEntries('M');
function getResponses() {
return $this->getThreadEntries('R');
return $this->getThreadEntries('N');
return $this->getThreadEntries(array('M', 'R'));
function getThreadEntry($id) {
return $this->getThread()->getEntry($id);
function getThreadEntries($type, $order='') {
return $this->getThread()->getEntries($type, $order);
}
/* -------------------- Setters --------------------- */
function setLastMsgId($msgid) {
return $this->lastMsgId=$msgid;
}
//DeptId can NOT be 0. No orphans please!
Peter Rotich
committed
function setDeptId($deptId) {
if(!($dept=Dept::lookup($deptId)) || $dept->getId()==$this->getDeptId())
Peter Rotich
committed
$sql='UPDATE '.TICKET_TABLE.' SET updated=NOW(), dept_id='.db_input($deptId)
.' WHERE ticket_id='.db_input($this->getId());
return (db_query($sql) && db_affected_rows());
}
Peter Rotich
committed
//Set staff ID...assign/unassign/release (id can be 0)
function setStaffId($staffId) {
if(!is_numeric($staffId)) return false;
Peter Rotich
committed
$sql='UPDATE '.TICKET_TABLE.' SET updated=NOW(), staff_id='.db_input($staffId)
.' WHERE ticket_id='.db_input($this->getId());
if (!db_query($sql) || !db_affected_rows())
return false;
Peter Rotich
committed
$this->staff = null;
$this->ht['staff_id'] = $staffId;
}
function setSLAId($slaId) {
if ($slaId == $this->getSLAId()) return true;
return db_query(
'UPDATE '.TICKET_TABLE.' SET sla_id='.db_input($slaId)
.' WHERE ticket_id='.db_input($this->getId()))
&& db_affected_rows();
}
/**
* Selects the appropriate service-level-agreement plan for this ticket.
* When tickets are transfered between departments, the SLA of the new
* department should be applied to the ticket. This would be useful,
* for instance, if the ticket is transferred to a different department
* which has a shorter grace period, the ticket should be considered
* overdue in the shorter window now that it is owned by the new
* department.
*
* $trump - if received, should trump any other possible SLA source.
* This is used in the case of email filters, where the SLA
* specified in the filter should trump any other SLA to be
* considered.
*/
function selectSLAId($trump=null) {
global $cfg;
# XXX Should the SLA be overridden if it was originally set via an
# email filter? This method doesn't consider such a case
if ($trump && is_numeric($trump)) {
} elseif ($this->getDept() && $this->getDept()->getSLAId()) {
} elseif ($this->getTopic() && $this->getTopic()->getSLAId()) {
$slaId = $this->getTopic()->getSLAId();
} else {
$slaId = $cfg->getDefaultSLAId();
}
return ($slaId && $this->setSLAId($slaId)) ? $slaId : false;
}
//Set team ID...assign/unassign/release (id can be 0)
Peter Rotich
committed
Peter Rotich
committed
$sql='UPDATE '.TICKET_TABLE.' SET updated=NOW(), team_id='.db_input($teamId)
.' WHERE ticket_id='.db_input($this->getId());
}
//Status helper.
function setStatus($status) {
Peter Rotich
committed
if(strcasecmp($this->getStatus(), $status)==0)
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
return true; //No changes needed.
switch(strtolower($status)) {
case 'open':
return $this->reopen();
break;
case 'closed':
return $this->close();
break;
}
return false;
}
function setState($state, $alerts=false) {
switch(strtolower($state)) {
case 'open':
return $this->setStatus('open');
break;
case 'closed':
return $this->setStatus('closed');
break;
case 'answered':
return $this->setAnsweredState(1);
break;
case 'unanswered':
return $this->setAnsweredState(0);
break;
case 'overdue':
return $this->markOverdue();
break;
case 'notdue':
return $this->clearOverdue();
break;
case 'unassined':
return $this->unassign();
}
return false;
}
function setAnsweredState($isanswered) {
$sql='UPDATE '.TICKET_TABLE.' SET isanswered='.db_input($isanswered)
.' WHERE ticket_id='.db_input($this->getId());
return (db_query($sql) && db_affected_rows());
}
//Close the ticket
Peter Rotich
committed
function close() {
Peter Rotich
committed
Peter Rotich
committed
$sql='UPDATE '.TICKET_TABLE.' SET closed=NOW(),isoverdue=0, duedate=NULL, updated=NOW(), status='.db_input('closed');
Peter Rotich
committed
if($thisstaff) //Give the closing staff credit.
$sql.=', staff_id='.db_input($thisstaff->getId());
$sql.=' WHERE ticket_id='.db_input($this->getId());
Peter Rotich
committed
if(!db_query($sql) || !db_affected_rows())
return false;
$this->reload();
$this->logEvent('closed');
Peter Rotich
committed
return true;
}
//set status to open on a closed ticket.
Peter Rotich
committed
function reopen($isanswered=0) {
$sql='UPDATE '.TICKET_TABLE.' SET updated=NOW(), reopened=NOW() '
.' ,status='.db_input('open')
.' ,isanswered='.db_input($isanswered)
.' WHERE ticket_id='.db_input($this->getId());
Peter Rotich
committed
//TODO: log reopen event here
$this->logEvent('reopened', 'closed');
return (db_query($sql) && db_affected_rows());
}
function onNewTicket($message, $autorespond=true, $alertstaff=true) {
global $cfg;
//Log stuff here...
Peter Rotich
committed
if(!$autorespond && !$alertstaff) return true; //No alerts to send.
/* ------ SEND OUT NEW TICKET AUTORESP && ALERTS ----------*/
Peter Rotich
committed
$this->reload(); //get the new goodies.
$dept= $this->getDept();
if(!$dept || !($tpl = $dept->getTemplate()))
$tpl= $cfg->getDefaultTemplate();
Peter Rotich
committed
if(!$tpl) return false; //bail out...missing stuff.
if(!$dept || !($email=$dept->getAutoRespEmail()))
$email =$cfg->getDefaultEmail();
$options = array('references'=>$message->getEmailMessageId());
Peter Rotich
committed
if($autorespond && $email && $cfg->autoRespONNewTicket()
&& $dept->autoRespONNewTicket()
Peter Rotich
committed
$msg = $this->replaceVars($msg->asArray(),
array('message' => $message,
'signature' => ($dept && $dept->isPublic())?$dept->getSignature():'')
);
if($cfg->stripQuotedReply() && ($tag=$cfg->getReplySeparator()))
Peter Rotich
committed
$email->sendAutoReply($this->getEmail(), $msg['subj'], $msg['body'],
null, $options);
Peter Rotich
committed
if(!($email=$cfg->getAlertEmail()))
$email =$cfg->getDefaultEmail();
Peter Rotich
committed
//Send alert to out sleepy & idle staff.
if($alertstaff && $email
Peter Rotich
committed
&& $cfg->alertONNewTicket()
&& ($msg=$tpl->getNewTicketAlertMsgTemplate())) {
Peter Rotich
committed
$msg = $this->replaceVars($msg->asArray(), array('message' => $message));
$recipients=$sentlist=array();
//Alert admin??
if($cfg->alertAdminONNewTicket()) {
$alert = str_replace('%{recipient}', 'Admin', $msg['body']);
$email->sendAlert($cfg->getAdminEmail(), $msg['subj'],
$alert, null, $options);
Peter Rotich
committed
//Only alerts dept members if the ticket is NOT assigned.
if($cfg->alertDeptMembersONNewTicket() && !$this->isAssigned()) {
$recipients=array_merge($recipients, $members);
}
Peter Rotich
committed
if($cfg->alertDeptManagerONNewTicket() && $dept && ($manager=$dept->getManager()))
$recipients[]= $manager;
Peter Rotich
committed
foreach( $recipients as $k=>$staff) {
if(!is_object($staff) || !$staff->isAvailable() || in_array($staff->getEmail(), $sentlist)) continue;
$alert = str_replace('%{recipient}', $staff->getFirstName(), $msg['body']);
$email->sendAlert($staff->getEmail(), $msg['subj'], $alert,
null, $options);
Peter Rotich
committed
Peter Rotich
committed
global $ost, $cfg;
//Log the limit notice as a warning for admin.
$msg=sprintf('Max open tickets (%d) reached for %s ', $cfg->getMaxOpenTickets(), $this->getEmail());
$ost->logWarning('Max. Open Tickets Limit ('.$this->getEmail().')', $msg);
if(!$sendNotice || !$cfg->sendOverLimitNotice()) return true;
//Send notice to user.
$dept = $this->getDept();
Peter Rotich
committed
if(!$dept || !($tpl=$dept->getTemplate()))
$tpl=$cfg->getDefaultTemplate();
Peter Rotich
committed
if(!$dept || !($email=$dept->getAutoRespEmail()))
$email=$cfg->getDefaultEmail();
if($tpl && ($msg=$tpl->getOverlimitMsgTemplate()) && $email) {
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']);
Peter Rotich
committed
//Alert admin...this might be spammy (no option to disable)...but it is helpful..I think.
$alert='Max. open tickets reached for '.$this->getEmail()."\n"
.'Open ticket: '.$client->getNumOpenTickets()."\n"
.'Max Allowed: '.$cfg->getMaxOpenTickets()."\n\nNotice 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()));
}
function onMessage($autorespond=true, $message=null) {
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(!($staff=$this->getStaff()) || !$staff->isAvailable()) {
if($cfg->autoAssignReopenedTickets() && ($lastrep=$this->getLastRespondent()) && $lastrep->isAvailable()) {
$this->setStaffId($lastrep->getId()); //direct assignment;
} else {
$this->setStaffId(0); //unassign - last respondent is not available.
}
}
if($this->isClosed()) $this->reopen(); //reopen..
/********** double check auto-response ************/
if($autorespond && (Email::getIdByEmail($this->getEmail())))
$autorespond=false;
elseif($autorespond && ($dept=$this->getDept()))
$autorespond=$dept->autoRespONNewMessage();
if(!$autorespond || !$cfg->autoRespONNewMessage()) return; //no autoresp or alerts.
if(!$dept || !($tpl = $dept->getTemplate()))
$tpl = $cfg->getDefaultTemplate();
if(!$dept || !($email = $dept->getAutoRespEmail()))
$email = $cfg->getDefaultEmail();
Peter Rotich
committed
//If enabled...send confirmation to user. ( New Message AutoResponse)
if($email && $tpl && ($msg=$tpl->getNewMessageAutorepMsgTemplate())) {
$msg = $this->replaceVars($msg->asArray(),
array('signature' => ($dept && $dept->isPublic())?$dept->getSignature():''));
//Reply separator tag.
if($cfg->stripQuotedReply() && ($tag=$cfg->getReplySeparator()))
Peter Rotich
committed
if (!$message)
$message = $this->getLastMessage();
$options = array('references' => $message->getEmailMessageId());
$email->sendAutoReply($this->getEmail(), $msg['subj'], $msg['body'],
null, $options);
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?$comments:'Ticket assignment';
$assigner = $thisstaff?$thisstaff:'SYSTEM (Auto Assignment)';
Peter Rotich
committed
//Log an internal note - no alerts on the internal note.
$note = $this->logNote('Ticket Assigned to '.$assignee->getName(),
$comments, $assigner, false);
//See if we need to send alerts
if(!$alert || !$cfg->alertONAssignment()) return true; //No alerts!
$dept = $this->getDept();
//Get template.
if(!$dept || !($tpl = $dept->getTemplate()))
//Email to use!
if(!($email=$cfg->getAlertEmail()))
$email = $cfg->getDefaultEmail();
//recipients
$recipients=array();
if(!strcasecmp(get_class($assignee), 'Staff')) {
if($cfg->alertStaffONAssignment())
$recipients[] = $assignee;
} elseif(!strcasecmp(get_class($assignee), 'Team')) {
if($cfg->alertTeamMembersONAssignment() && ($members=$assignee->getMembers()))
$recipients+=$members;
elseif($cfg->alertTeamLeadONAssignment() && ($lead=$assignee->getTeamLead()))
$recipients[] = $lead;
}
if($email && $recipients && $tpl && ($msg=$tpl->getAssignedAlertMsgTemplate())) {
$msg = $this->replaceVars($msg->asArray(),
array('comments' => $comments,
'assignee' => $assignee,
'assigner' => $assigner
$options = array('references' => $note->getEmailMessageId());
Peter Rotich
committed
if(!is_object($staff) || !$staff->isAvailable() || in_array($staff->getEmail(), $sentlist)) continue;
$alert = str_replace('%{recipient}', $staff->getFirstName(), $msg['body']);
$email->sendAlert($staff->getEmail(), $msg['subj'], $alert,
null, $options);
function onOverdue($whine=true, $comments="") {
if($whine && ($sla=$this->getSLA()) && !$sla->alertOnOverdue())
$whine = false;
//check if we need to send alerts.
if(!$whine || !$cfg->alertONOverdueTicket())
return true;
$dept = $this->getDept();
//Get department-defined or default template.
if(!$dept || !($tpl = $dept->getTemplate()))
$tpl= $cfg->getDefaultTemplate();
//Email to use!
if(!($email=$cfg->getAlertEmail()))
$email =$cfg->getDefaultEmail();