diff --git a/include/class.config.php b/include/class.config.php index b420a7325b7ab16312769ca7452fa47aad905c97..bfaa0a5fe7664b3fc41a6e587421f62da7d781f9 100644 --- a/include/class.config.php +++ b/include/class.config.php @@ -363,11 +363,56 @@ class OsticketConfig extends Config { function getDefaultTemplate() { if(!$this->defaultTemplate && $this->getDefaultTemplateId()) - $this->defaultTemplate = Template::lookup($this->getDefaultTemplateId()); + $this->defaultTemplate = EmailTemplateGroup::lookup($this->getDefaultTemplateId()); return $this->defaultTemplate; } + function getLandingPageId() { + return $this->get('landing_page_id'); + } + + function getLandingPage() { + + if(!$this->landing_page && $this->getLandingPageId()) + $this->landing_page = Page::lookup($this->getLandingPageId()); + + return $this->landing_page; + } + + function getOfflinePageId() { + return $this->get('offline_page_id'); + } + + function getOfflinePage() { + + if(!$this->offline_page && $this->getOfflinePageId()) + $this->offline_page = Page::lookup($this->getOfflinePageId()); + + return $this->offline_page; + } + + function getThankYouPageId() { + return $this->get('thank-you_page_id'); + } + + function getThankYouPage() { + + if(!$this->thankyou_page && $this->getThankYouPageId()) + $this->thankyou_page = Page::lookup($this->getThankYouPageId()); + + return $this->thankyou_page; + } + + function getDefaultPages() { + /* Array of ids...as opposed to objects */ + return array( + $this->getLandingPageId(), + $this->getOfflinePageId(), + $this->getThankYouPageId(), + ); + } + function getMaxOpenTickets() { return $this->get('max_open_tickets'); } @@ -641,6 +686,9 @@ class OsticketConfig extends Config { case 'emails': return $this->updateEmailsSettings($vars, $errors); break; + case 'pages': + return $this->updatePagesSettings($vars, $errors); + break; case 'autoresp': return $this->updateAutoresponderSettings($vars, $errors); break; @@ -804,6 +852,23 @@ class OsticketConfig extends Config { )); } + function updatePagesSettings($vars, &$errors) { + + $f=array(); + $f['landing_page_id'] = array('type'=>'int', 'required'=>1, 'error'=>'required'); + $f['offline_page_id'] = array('type'=>'int', 'required'=>1, 'error'=>'required'); + $f['thank-you_page_id'] = array('type'=>'int', 'required'=>1, 'error'=>'required'); + + if(!Validator::process($f, $vars, $errors) || $errors) + return false; + + return $this->updateAll(array( + 'landing_page_id' => $vars['landing_page_id'], + 'offline_page_id' => $vars['offline_page_id'], + 'thank-you_page_id' => $vars['thank-you_page_id'], + )); + } + function updateAutoresponderSettings($vars, &$errors) { if($errors) return false; diff --git a/include/class.dept.php b/include/class.dept.php index cd89c2cbb86770c2c0aff2c41c42fda8828c560a..edcf2d6988f7960cb6e5eea2340ab486eeeeadc2 100644 --- a/include/class.dept.php +++ b/include/class.dept.php @@ -1,7 +1,7 @@ <?php /********************************************************************* class.dept.php - + Department class Peter Rotich <peter@osticket.com> @@ -18,23 +18,23 @@ class Dept { var $email; var $sla; - var $manager; + var $manager; var $members; var $groups; var $ht; - + function Dept($id) { $this->id=0; $this->load($id); } - + function load($id=0) { global $cfg; if(!$id && !($id=$this->getId())) return false; - + $sql='SELECT dept.*,dept.dept_id as id,dept.dept_name as name, dept.dept_signature as signature, count(staff.staff_id) as users ' .' FROM '.DEPT_TABLE.' dept ' .' LEFT JOIN '.STAFF_TABLE.' staff ON (dept.dept_id=staff.dept_id) ' @@ -66,21 +66,21 @@ class Dept { function getId() { return $this->id; } - + function getName() { return $this->ht['name']; } - + function getEmailId() { return $this->ht['email_id']; } function getEmail() { - + if(!$this->email && $this->getEmailId()) $this->email=Email::lookup($this->getEmailId()); - + return $this->email; } @@ -88,7 +88,7 @@ class Dept { return $this->ht['users']; } - + function getNumUsers() { return $this->getNumStaff(); } @@ -103,14 +103,14 @@ class Dept { $this->members = array(); $sql='SELECT DISTINCT s.staff_id FROM '.STAFF_TABLE.' s ' .' LEFT JOIN '.GROUP_DEPT_TABLE.' g ON(s.group_id=g.group_id) ' - .' INNER JOIN '.DEPT_TABLE.' d - ON(d.dept_id=s.dept_id - OR d.manager_id=s.staff_id + .' INNER JOIN '.DEPT_TABLE.' d + ON(d.dept_id=s.dept_id + OR d.manager_id=s.staff_id OR (d.dept_id=g.dept_id AND d.group_membership=1) ) ' .' WHERE d.dept_id='.db_input($this->getId()) .' ORDER BY s.lastname, s.firstname'; - + if(($res=db_query($sql)) && db_num_rows($res)) { while(list($id)=db_fetch_row($res)) $this->members[] = Staff::lookup($id); @@ -140,11 +140,11 @@ class Dept { function getTemplate() { if(!$this->template && $this->getTemplateId()) - $this->template = Template::lookup($this->getTemplateId()); + $this->template = EmailTemplateGroup::lookup($this->getTemplateId()); return $this->template; } - + function getAutoRespEmail() { if(!$this->autorespEmail && $this->ht['autoresp_email_id'] && ($email=Email::lookup($this->ht['autoresp_email_id']))) @@ -154,12 +154,12 @@ class Dept { return $this->autorespEmail; } - + function getEmailAddress() { if(($email=$this->getEmail())) return $email->getAddress(); } - + function getSignature() { return $this->ht['signature']; } @@ -167,13 +167,13 @@ class Dept { function canAppendSignature() { return ($this->getSignature() && $this->isPublic()); } - + function getManagerId() { return $this->ht['manager_id']; } function getManager() { - + if(!$this->manager && $this->getManagerId()) $this->manager=Staff::lookup($this->getManagerId()); @@ -191,11 +191,11 @@ class Dept { function isPublic() { return ($this->ht['ispublic']); } - + function autoRespONNewTicket() { return ($this->ht['ticket_auto_response']); } - + function autoRespONNewMessage() { return ($this->ht['message_auto_response']); } @@ -208,7 +208,7 @@ class Dept { function isGroupMembershipEnabled() { return ($this->ht['group_membership']); } - + function getHashtable() { return $this->ht; } @@ -218,7 +218,7 @@ class Dept { } - + function getAllowedGroups() { if($this->groups) return $this->groups; @@ -244,9 +244,9 @@ class Dept { } } - + $sql='DELETE FROM '.GROUP_DEPT_TABLE.' WHERE dept_id='.db_input($this->getId()); - if($groups && is_array($groups)) + if($groups && is_array($groups)) $sql.=' AND group_id NOT IN('.implode(',', db_input($groups)).')'; db_query($sql); @@ -262,13 +262,13 @@ class Dept { $this->updateAllowedGroups($vars['groups']); $this->reload(); - + return true; } function delete() { global $cfg; - + if(!$cfg || $this->getId()==$cfg->getDefaultDeptId() || $this->getNumUsers()) return 0; @@ -317,7 +317,7 @@ class Dept { } function getDepartments( $criteria=null) { - + $depts=array(); $sql='SELECT dept_id, dept_name FROM '.DEPT_TABLE.' WHERE 1'; if($criteria['publiconly']) @@ -347,13 +347,13 @@ class Dept { function save($id, $vars, &$errors) { global $cfg; - + if($id && $id!=$vars['id']) $errors['err']='Missing or invalid Dept ID (internal error).'; - + if(!$vars['email_id'] || !is_numeric($vars['email_id'])) $errors['email_id']='Email selection required'; - + if(!is_numeric($vars['tpl_id'])) $errors['tpl_id']='Template selection required'; @@ -364,13 +364,13 @@ class Dept { } elseif(($did=Dept::getIdByName($vars['name'])) && $did!=$id) { $errors['name']='Department already exist'; } - + if(!$vars['ispublic'] && ($vars['id']==$cfg->getDefaultDeptId())) $errors['ispublic']='System default department can not be private'; if($errors) return false; - + $sql='SET updated=NOW() ' .' ,ispublic='.db_input($vars['ispublic']) .' ,email_id='.db_input($vars['email_id']) @@ -384,25 +384,25 @@ class Dept { .' ,ticket_auto_response='.db_input(isset($vars['ticket_auto_response'])?$vars['ticket_auto_response']:1) .' ,message_auto_response='.db_input(isset($vars['message_auto_response'])?$vars['message_auto_response']:1); - + if($id) { $sql='UPDATE '.DEPT_TABLE.' '.$sql.' WHERE dept_id='.db_input($id); if(db_query($sql) && db_affected_rows()) return true; - + $errors['err']='Unable to update '.Format::htmlchars($vars['name']).' Dept. Error occurred'; - + } else { $sql='INSERT INTO '.DEPT_TABLE.' '.$sql.',created=NOW()'; if(db_query($sql) && ($id=db_insert_id())) return $id; - + $errors['err']='Unable to create department. Internal error'; - + } - + return false; } diff --git a/include/class.nav.php b/include/class.nav.php index ad30e1219f8eb33f597867f64615773a710e2c90..a92a5629ec149579cd3d7883be2aa8ff2ef661fc 100644 --- a/include/class.nav.php +++ b/include/class.nav.php @@ -196,6 +196,7 @@ class AdminNav extends StaffNav{ $subnav[]=array('desc'=>'System Preferences','href'=>'settings.php?t=system','iconclass'=>'preferences'); $subnav[]=array('desc'=>'Tickets','href'=>'settings.php?t=tickets','iconclass'=>'ticket-settings'); $subnav[]=array('desc'=>'Emails','href'=>'settings.php?t=emails','iconclass'=>'email-settings'); + $subnav[]=array('desc'=>'Pages','href'=>'settings.php?t=pages','iconclass'=>'pages'); $subnav[]=array('desc'=>'Knowledgebase','href'=>'settings.php?t=kb','iconclass'=>'kb-settings'); $subnav[]=array('desc'=>'Autoresponder','href'=>'settings.php?t=autoresp','iconclass'=>'email-autoresponders'); $subnav[]=array('desc'=>'Alerts & Notices','href'=>'settings.php?t=alerts','iconclass'=>'alert-settings'); @@ -206,6 +207,7 @@ class AdminNav extends StaffNav{ 'title'=>'Ticket Filters','iconclass'=>'ticketFilters'); $subnav[]=array('desc'=>'SLA Plans','href'=>'slas.php','iconclass'=>'sla'); $subnav[]=array('desc'=>'API Keys','href'=>'apikeys.php','iconclass'=>'api'); + $subnav[]=array('desc'=>'Site Pages', 'href'=>'pages.php','title'=>'Pages','iconclass'=>'pages'); break; case 'emails': $subnav[]=array('desc'=>'Emails','href'=>'emails.php', 'title'=>'Email Addresses', 'iconclass'=>'emailSettings'); diff --git a/include/class.page.php b/include/class.page.php new file mode 100644 index 0000000000000000000000000000000000000000..f0c1f604b125674d8ae208e1e77114b0a2b5daa7 --- /dev/null +++ b/include/class.page.php @@ -0,0 +1,261 @@ +<?php +/********************************************************************* + class.page.php + + Page class + + Copyright (c) 2006-2013 osTicket + 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: +**********************************************************************/ + +class Page { + + var $id; + var $ht; + + function Page($id) { + $this->id=0; + $this->ht = array(); + $this->load($id); + } + + function load($id=0) { + + if(!$id && !($id=$this->getId())) + return false; + + $sql='SELECT page.*, count(topic.page_id) as topics ' + .' FROM '.PAGE_TABLE.' page ' + .' LEFT JOIN '.TOPIC_TABLE. ' topic ON(topic.page_id=page.id) ' + .' WHERE page.id='.db_input($id) + .' GROUP By page.id'; + + if (!($res=db_query($sql)) || !db_num_rows($res)) + return false; + + $this->ht = db_fetch_array($res); + $this->id = $this->ht['id']; + + return true; + } + + function reload() { + return $this->load(); + } + + function getId() { + return $this->id; + } + + function getHashtable() { + return $this->ht; + } + + function getType() { + return $this->ht['type']; + } + + function getName() { + return $this->ht['name']; + } + + function getBody() { + return $this->ht['body']; + } + + function getNotes() { + return $this->ht['notes']; + } + + function isActive() { + return ($this->ht['isactive']); + } + + function isInUse() { + global $cfg; + + return ($this->getNumTopics() + || in_array($this->getId(), $cfg->getDefaultPages())); + } + + + function getCreateDate() { + return $this->ht['created']; + } + + function getUpdateDate() { + return $this->ht['updated']; + } + + function getNumTopics() { + return $this->ht['topics']; + } + + function update($vars, &$errors) { + + if(!$vars['isactive'] && $this->isInUse()) { + $errors['err'] = 'A page currently in-use CANNOT be disabled!'; + $errors['isactive'] = 'Page is in-use!'; + } + + if($errors || !$this->save($this->getId(), $vars, $errors)) + return false; + + $this->reload(); + + return true; + } + + function disable() { + + if(!$this->isActive()) + return true; + + if($this->isInUse()) + return false; + + + $sql=' UPDATE '.PAGE_TABLE.' SET isactive=0 ' + .' WHERE id='.db_input($this->getId()); + + if(!db_query($sql) || !db_affected_rows()) + return false; + + $this->reload(); + + return true; + } + + function delete() { + + if($this->isInUse()) + return false; + + $sql='DELETE FROM '.PAGE_TABLE + .' WHERE id='.db_input($this->getId()) + .' LIMIT 1'; + + if(!db_query($sql) || !db_affected_rows()) + return false; + + db_query('UPDATE '.TOPIC_TABLE.' SET page_id=0 WHERE page_id='.db_input($this->getId())); + + return true; + } + + /* ------------------> Static methods <--------------------- */ + + function add($vars, &$errors) { + if(!($id=self::create($vars, $errors))) + return false; + + return self::lookup($id); + } + + function create($vars, &$errors) { + return self::save(0, $vars, $errors); + } + + function getPages($criteria=array()) { + + $sql = ' SELECT id FROM '.PAGE_TABLE.' WHERE 1'; + if(isset($criteria['active'])) + $sql.=' AND isactive='.db_input($criteria['active']?1:0); + if(isset($criteria['type'])) + $sql.=' AND `type`='.db_input($criteria['type']); + + $sql.=' ORDER BY name'; + + $pages = array(); + if(($res=db_query($sql)) && db_num_rows($res)) + while(list($id) = db_fetch_row($res)) + $pages[] = Page::lookup($id); + + return array_filter($pages); + } + + function getActivePages($criteria=array()) { + + $criteria = array_merge($criteria, array('active'=>true)); + + return self::getPages($criteria); + } + + function getActiveThankYouPages() { + return self::getActivePages(array('type' => 'thank-you')); + } + + function getIdByName($name) { + + $id = 0; + $sql = ' SELECT id FROM '.PAGE_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) { + return ($id + && is_numeric($id) + && ($p= new Page($id)) + && $p->getId()==$id) + ? $p : null; + } + + function save($id, $vars, &$errors) { + + //Cleanup. + $vars['name']=Format::striptags(trim($vars['name'])); + + //validate + if($id && $id!=$vars['id']) + $errors['err'] = 'Internal error. Try again'; + + if(!$vars['type']) + $errors['type'] = 'Type required'; + elseif(!in_array($vars['type'], array('landing', 'offline', 'thank-you', 'other'))) + $errors['type'] = 'Invalid selection'; + + if(!$vars['name']) + $errors['name'] = 'Name required'; + elseif(($pid=self::getIdByName($vars['name'])) && $pid!=$id) + $errors['name'] = 'Name already exists'; + + if(!$vars['body']) + $errors['body'] = 'Page body is required'; + + if($errors) return false; + + //save + $sql=' updated=NOW() ' + .', `type`='.db_input($vars['type']) + .', name='.db_input($vars['name']) + .', body='.db_input(Format::safe_html($vars['body'])) + .', isactive='.db_input(isset($vars['isactive'])?1:0) + .', notes='.db_input($vars['notes']); + + if($id) { + $sql='UPDATE '.PAGE_TABLE.' SET '.$sql.' WHERE id='.db_input($id); + if(db_query($sql)) + return true; + + $errors['err']='Unable to update page.'; + + } else { + $sql='INSERT INTO '.PAGE_TABLE.' SET '.$sql.', created=NOW()'; + if(db_query($sql) && ($id=db_insert_id())) + return $id; + + $errors['err']='Unable to create page. Internal error'; + } + + return false; + } +} +?> diff --git a/include/class.template.php b/include/class.template.php index 0ed98ca6473f4167a25bba4f5e64cbd07c5d39f7..2dcb5d00ea7c5d8e15f56859548d29efdf1a76b1 100644 --- a/include/class.template.php +++ b/include/class.template.php @@ -14,12 +14,51 @@ vim: expandtab sw=4 ts=4 sts=4: **********************************************************************/ -class Template { +class EmailTemplateGroup { var $id; var $ht; - - function Template($id){ + var $_templates; + var $all_names=array( + 'ticket.autoresp'=>array( + 'name'=>'New Ticket Auto-response', + 'desc'=>'Autoresponse sent to user, if enabled, on new ticket.'), + 'ticket.autoreply'=>array( + 'name'=>'New Ticket Auto-reply', + 'desc'=>'Canned Auto-reply sent to user on new ticket, based on filter matches. Overwrites "normal" auto-response.'), + 'message.autoresp'=>array( + 'name'=>'New Message Auto-response', + 'desc'=>'Confirmation sent to user when a new message is appended to an existing ticket.'), + 'ticket.notice'=>array( + 'name'=>'New Ticket Notice', + 'desc'=>'Notice sent to user, if enabled, on new ticket created by staff on their behalf (e.g phone calls).'), + 'ticket.overlimit'=>array( + 'name'=>'Over Limit Notice', + 'desc'=>'A one time notice sent, if enabled, when user has reached the maximum allowed open tickets.'), + 'ticket.reply'=>array( + 'name'=>'Response/Reply Template', + 'desc'=>'Template used on ticket response/reply'), + 'ticket.alert'=>array( + 'name'=>'New Ticket Alert', + 'desc'=>'Alert sent to staff, if enabled, on new ticket.'), + 'message.alert'=>array( + 'name'=>'New Message Alert', + 'desc'=>'Alert sent to staff, if enabled, when user replies to an existing ticket.'), + 'note.alert'=>array( + 'name'=>'Internal Note Alert', + 'desc'=>'Alert sent to selected staff, if enabled, on new internal note.'), + 'assigned.alert'=>array( + 'name'=>'Ticket Assignment Alert', + 'desc'=>'Alert sent to staff on ticket assignment.'), + 'transfer.alert'=>array( + 'name'=>'Ticket Transfer Alert', + 'desc'=>'Alert sent to staff on ticket transfer.'), + 'ticket.overdue'=>array( + 'name'=>'Overdue Ticket Alert', + 'desc'=>'Alert sent to staff on stale or overdue tickets.'), + ); + + function EmailTemplateGroup($id){ $this->id=0; $this->load($id); } @@ -28,9 +67,9 @@ class Template { if(!$id && !($id=$this->getId())) return false; - + $sql='SELECT tpl.*,count(dept.tpl_id) as depts ' - .' FROM '.EMAIL_TEMPLATE_TABLE.' tpl ' + .' FROM '.EMAIL_TEMPLATE_GRP_TABLE.' tpl ' .' LEFT JOIN '.DEPT_TABLE.' dept USING(tpl_id) ' .' WHERE tpl.tpl_id='.db_input($id) .' GROUP BY tpl.tpl_id'; @@ -38,21 +77,21 @@ class Template { if(!($res=db_query($sql))|| !db_num_rows($res)) return false; - + $this->ht=db_fetch_array($res); $this->id=$this->ht['tpl_id']; return true; } - + function reload() { return $this->load($this->getId()); } - + function getId(){ return $this->id; } - + function getName(){ return $this->ht['name']; } @@ -71,7 +110,7 @@ class Template { function isInUse(){ global $cfg; - + return ($this->ht['depts'] || ($cfg && $this->getId()==$cfg->getDefaultTemplateId())); } @@ -85,172 +124,93 @@ class Template { function setStatus($status){ - $sql='UPDATE '.EMAIL_TEMPLATE_TABLE.' SET updated=NOW(), isactive='.db_input($status?1:0) + $sql='UPDATE '.EMAIL_TEMPLATE_GRP_TABLE.' SET updated=NOW(), isactive='.db_input($status?1:0) .' WHERE tpl_id='.db_input($this->getId()); return (db_query($sql) && db_affected_rows()); } + function getTemplateDescription($name) { + return $this->all_names[$name]; + } + function getMsgTemplate($name) { global $ost; - //TODO: Don't preload - do ondemand fetch! - $tpl=array(); - switch(strtolower($name)) { - case 'ticket_autoresp': - $tpl=array('subj'=>$this->ht['ticket_autoresp_subj'],'body'=>$this->ht['ticket_autoresp_body']); - break; - case 'ticket_autoreply': - $tpl=array('subj'=>$this->ht['ticket_autoreply_subj'],'body'=>$this->ht['ticket_autoreply_body']); - break; - case 'msg_autoresp': - $tpl=array('subj'=>$this->ht['message_autoresp_subj'],'body'=>$this->ht['message_autoresp_body']); - break; - case 'ticket_notice': - $tpl=array('subj'=>$this->ht['ticket_notice_subj'],'body'=>$this->ht['ticket_notice_body']); - break; - case 'overlimit_notice': - $tpl=array('subj'=>$this->ht['ticket_overlimit_subj'],'body'=>$this->ht['ticket_overlimit_body']); - break; - case 'ticket_reply': - $tpl=array('subj'=>$this->ht['ticket_reply_subj'],'body'=>$this->ht['ticket_reply_body']); - break; - case 'ticket_alert': - $tpl=array('subj'=>$this->ht['ticket_alert_subj'],'body'=>$this->ht['ticket_alert_body']); - break; - case 'msg_alert': - $tpl=array('subj'=>$this->ht['message_alert_subj'],'body'=>$this->ht['message_alert_body']); - break; - case 'note_alert': - $tpl=array('subj'=>$this->ht['note_alert_subj'],'body'=>$this->ht['note_alert_body']); - break; - case 'assigned_alert': - $tpl=array('subj'=>$this->ht['assigned_alert_subj'],'body'=>$this->ht['assigned_alert_body']); - break; - case 'transfer_alert': - $tpl=array('subj'=>$this->ht['transfer_alert_subj'],'body'=>$this->ht['transfer_alert_body']); - break; - case 'overdue_alert': - $tpl=array('subj'=>$this->ht['ticket_overdue_subj'],'body'=>$this->ht['ticket_overdue_body']); - break; - default: - $ost->logWarning('Template Fetch Error', "Unable to fetch '$name' template - id #".$this->getId()); - $tpl=array(); + if ($tpl=EmailTemplate::lookupByName($this->getId(), $name, $this)) + return $tpl; + + $ost->logWarning('Template Fetch Error', "Unable to fetch '$name' template - id #".$this->getId()); + return false; + } + + function getTemplates() { + if (!$this->_tempates) { + $this->_templates = array(); + $sql = 'SELECT id, code_name FROM '.EMAIL_TEMPLATE_TABLE + .' WHERE tpl_id='.db_input($this->getId()) + .' ORDER BY code_name'; + $res = db_query($sql); + while (list($id, $cn)=db_fetch_row($res)) + $this->_templates[$cn] = EmailTemplate::lookup($id, $this); } + return $this->_templates; + } - return $tpl; + function getUndefinedTemplateNames() { + $list = $this->all_names; + foreach ($this->getTemplates() as $cn=>$tpl) + unset($list[$cn]); + return $list; } - + function getNewTicketAlertMsgTemplate() { - return $this->getMsgTemplate('ticket_alert'); + return $this->getMsgTemplate('ticket.alert'); } function getNewMessageAlertMsgTemplate() { - return $this->getMsgTemplate('msg_alert'); + return $this->getMsgTemplate('message.alert'); } function getNewTicketNoticeMsgTemplate() { - return $this->getMsgTemplate('ticket_notice'); + return $this->getMsgTemplate('ticket.notice'); } function getNewMessageAutorepMsgTemplate() { - return $this->getMsgTemplate('msg_autoresp'); + return $this->getMsgTemplate('message.autoresp'); } function getAutoRespMsgTemplate() { - return $this->getMsgTemplate('ticket_autoresp'); + return $this->getMsgTemplate('ticket.autoresp'); } function getAutoReplyMsgTemplate() { - return $this->getMsgTemplate('ticket_autoreply'); + return $this->getMsgTemplate('ticket.autoreply'); } function getReplyMsgTemplate() { - return $this->getMsgTemplate('ticket_reply'); + return $this->getMsgTemplate('ticket.reply'); } function getOverlimitMsgTemplate() { - return $this->getMsgTemplate('overlimit_notice'); + return $this->getMsgTemplate('ticket.overlimit'); } function getNoteAlertMsgTemplate() { - return $this->getMsgTemplate('note_alert'); + return $this->getMsgTemplate('note.alert'); } function getTransferAlertMsgTemplate() { - return $this->getMsgTemplate('transfer_alert'); + return $this->getMsgTemplate('transfer.alert'); } function getAssignedAlertMsgTemplate() { - return $this->getMsgTemplate('assigned_alert'); + return $this->getMsgTemplate('assigned.alert'); } function getOverdueAlertMsgTemplate() { - return $this->getMsgTemplate('overdue_alert'); - } - - function updateMsgTemplate($vars, &$errors) { - - if(!($tpls=Template::message_templates()) || !$tpls[$vars['tpl']]) - $errors['tpl']='Unknown or invalid template'; - - if(!$vars['subj']) - $errors['subj']='Message subject required'; - - if(!$vars['body']) - $errors['body']='Message body required'; - - - if($errors) return false; - - $sql='UPDATE '.EMAIL_TEMPLATE_TABLE.' SET updated=NOW() '; - switch(strtolower($vars['tpl'])) { - case 'ticket_autoresp': - $sql.=',ticket_autoresp_subj='.db_input($vars['subj']).',ticket_autoresp_body='.db_input($vars['body']); - break; - case 'ticket_autoreply': - $sql.=',ticket_autoreply_subj='.db_input($vars['subj']).',ticket_autoreply_body='.db_input($vars['body']); - break; - case 'msg_autoresp': - $sql.=',message_autoresp_subj='.db_input($vars['subj']).',message_autoresp_body='.db_input($vars['body']); - break; - case 'ticket_notice': - $sql.=',ticket_notice_subj='.db_input($vars['subj']).',ticket_notice_body='.db_input($vars['body']); - break; - case 'overlimit_notice': - $sql.=',ticket_overlimit_subj='.db_input($vars['subj']).',ticket_overlimit_body='.db_input($vars['body']); - break; - case 'ticket_reply': - $sql.=',ticket_reply_subj='.db_input($vars['subj']).',ticket_reply_body='.db_input($vars['body']); - break; - case 'ticket_alert': - $sql.=',ticket_alert_subj='.db_input($vars['subj']).',ticket_alert_body='.db_input($vars['body']); - break; - case 'msg_alert': - $sql.=',message_alert_subj='.db_input($vars['subj']).',message_alert_body='.db_input($vars['body']); - break; - case 'note_alert': - $sql.=',note_alert_subj='.db_input($vars['subj']).',note_alert_body='.db_input($vars['body']); - break; - case 'assigned_alert': - $sql.=',assigned_alert_subj='.db_input($vars['subj']).',assigned_alert_body='.db_input($vars['body']); - break; - case 'transfer_alert': - $sql.=',transfer_alert_subj='.db_input($vars['subj']).',transfer_alert_body='.db_input($vars['body']); - break; - case 'overdue_alert': - $sql.=',ticket_overdue_subj='.db_input($vars['subj']).',ticket_overdue_body='.db_input($vars['body']); - break; - default: - $errors['tpl']='Unknown or invalid template'; - return false; - } - - $sql.=' WHERE tpl_id='.db_input($this->getId()); - - return (db_query($sql)); - + return $this->getMsgTemplate('ticket.overdue'); } function update($vars,&$errors) { @@ -260,9 +220,9 @@ class Template { if(!$this->save($this->getId(),$vars,$errors)) return false; - + $this->reload(); - + return true; } @@ -280,55 +240,28 @@ class Template { if($this->isInUse() || $cfg->getDefaultTemplateId()==$this->getId()) return 0; - $sql='DELETE FROM '.EMAIL_TEMPLATE_TABLE.' WHERE tpl_id='.db_input($this->getId()).' LIMIT 1'; + $sql='DELETE FROM '.EMAIL_TEMPLATE_GRP_TABLE + .' WHERE tpl_id='.db_input($this->getId()).' LIMIT 1'; if(db_query($sql) && ($num=db_affected_rows())) { - //isInuse check is enough - but it doesn't hurt make sure deleted tpl is not in-use. + //isInuse check is enough - but it doesn't hurt make sure deleted tpl is not in-use. db_query('UPDATE '.DEPT_TABLE.' SET tpl_id=0 WHERE tpl_id='.db_input($this->getId())); + db_query('DELETE FROM '.EMAIL_TEMPLATE_TABLE + .' WHERE tpl_id='.db_input($this->getId())); } return $num; } - /*** Static functions ***/ - function message_templates(){ - - //TODO: Make it database driven and dynamic - $messages=array('ticket_autoresp'=>array('name'=>'New Ticket Auto-response', - 'desc'=>'Autoresponse sent to user, if enabled, on new ticket.'), - 'ticket_autoreply'=>array('name'=>'New Ticket Auto-reply', - 'desc'=>'Canned Auto-reply sent to user on new ticket, based on filter matches. Overwrites "normal" auto-response.'), - 'msg_autoresp'=>array('name'=>'New Message Auto-response', - 'desc'=>'Confirmation sent to user when a new message is appended to an existing ticket.'), - 'ticket_notice'=>array('name'=>'New Ticket Notice', - 'desc'=>'Notice sent to user, if enabled, on new ticket created by staff on their behalf (e.g phone calls).'), - 'overlimit_notice'=>array('name'=>'Over Limit Notice', - 'desc'=>'A one time notice sent, if enabled, when user has reached the maximum allowed open tickets.'), - 'ticket_reply'=>array('name'=>'Response/Reply Template', - 'desc'=>'Template used on ticket response/reply'), - 'ticket_alert'=>array('name'=>'New Ticket Alert', - 'desc'=>'Alert sent to staff, if enabled, on new ticket.'), - 'msg_alert'=>array('name'=>'New Message Alert', - 'desc'=>'Alert sent to staff, if enabled, when user replies to an existing ticket.'), - 'note_alert'=>array('name'=>'Internal Note Alert', - 'desc'=>'Alert sent to selected staff, if enabled, on new internal note.'), - 'assigned_alert'=>array('name'=>'Ticket Assignment Alert', - 'desc'=>'Alert sent to staff on ticket assignment.'), - 'transfer_alert'=>array('name'=>'Ticket Transfer Alert', - 'desc'=>'Alert sent to staff on ticket transfer.'), - 'overdue_alert'=>array('name'=>'Overdue Ticket Alert', - 'desc'=>'Alert sent to staff on stale or overdue tickets.') - ); - return $messages; - } - - - function create($vars,&$errors) { - - return Template::save(0,$vars,$errors); + function create($vars,&$errors) { + return EmailTemplateGroup::save(0,$vars,$errors); + } + + function add($vars, &$errors) { + return self::lookup(self::create($vars, $errors)); } function getIdByName($name){ - $sql='SELECT tpl_id FROM '.EMAIL_TEMPLATE_TABLE.' WHERE name='.db_input($name); + $sql='SELECT tpl_id FROM '.EMAIL_TEMPLATE_GRP_TABLE.' WHERE name='.db_input($name); if(($res=db_query($sql)) && db_num_rows($res)) list($id)=db_fetch_row($res); @@ -336,7 +269,7 @@ class Template { } function lookup($id){ - return ($id && is_numeric($id) && ($t= new Template($id)) && $t->getId()==$id)?$t:null; + return ($id && is_numeric($id) && ($t= new EmailTemplateGroup($id)) && $t->getId()==$id)?$t:null; } function save($id, $vars, &$errors) { @@ -345,67 +278,185 @@ class Template { $tpl=null; $vars['name']=Format::striptags(trim($vars['name'])); - if($id && $id!=$vars['id']) + if($id && $id!=$vars['tpl_id']) $errors['err']='Internal error. Try again'; if(!$vars['name']) $errors['name']='Name required'; - elseif(($tid=Template::getIdByName($vars['name'])) && $tid!=$id) + elseif(($tid=EmailTemplateGroup::getIdByName($vars['name'])) && $tid!=$id) $errors['name']='Template name already exists'; - if(!$id && (!$vars['tpl_id'] || !($tpl=Template::lookup($vars['tpl_id'])))) + if(!$id && (!$vars['tpl_id'] || !($tpl=EmailTemplateGroup::lookup($vars['tpl_id'])))) $errors['tpl_id']='Selection required'; - + if($errors) return false; $sql=' updated=NOW() ' .' ,name='.db_input($vars['name']) .' ,isactive='.db_input($vars['isactive']) .' ,notes='.db_input($vars['notes']); - + if($id) { - $sql='UPDATE '.EMAIL_TEMPLATE_TABLE.' SET '.$sql.' WHERE tpl_id='.db_input($id); + $sql='UPDATE '.EMAIL_TEMPLATE_GRP_TABLE.' SET '.$sql.' WHERE tpl_id='.db_input($id); if(db_query($sql)) return true; $errors['err']='Unable to update the template. Internal error occurred'; - + } elseif($tpl && ($info=$tpl->getInfo())) { - $sql='INSERT INTO '.EMAIL_TEMPLATE_TABLE.' SET '.$sql - .' ,created=NOW() ' - .' ,ticket_autoresp_subj='.db_input($info['ticket_autoresp_subj']) - .' ,ticket_autoresp_body='.db_input($info['ticket_autoresp_body']) - .' ,ticket_autoreply_subj='.db_input($info['ticket_autoreply_subj']) - .' ,ticket_autoreply_body='.db_input($info['ticket_autoreply_body']) - .' ,ticket_notice_subj='.db_input($info['ticket_notice_subj']) - .' ,ticket_notice_body='.db_input($info['ticket_notice_body']) - .' ,ticket_alert_subj='.db_input($info['ticket_alert_subj']) - .' ,ticket_alert_body='.db_input($info['ticket_alert_body']) - .' ,message_autoresp_subj='.db_input($info['message_autoresp_subj']) - .' ,message_autoresp_body='.db_input($info['message_autoresp_body']) - .' ,message_alert_subj='.db_input($info['message_alert_subj']) - .' ,message_alert_body='.db_input($info['message_alert_body']) - .' ,note_alert_subj='.db_input($info['note_alert_subj']) - .' ,note_alert_body='.db_input($info['note_alert_body']) - .' ,transfer_alert_subj='.db_input($info['transfer_alert_subj']) - .' ,transfer_alert_body='.db_input($info['transfer_alert_body']) - .' ,assigned_alert_subj='.db_input($info['assigned_alert_subj']) - .' ,assigned_alert_body='.db_input($info['assigned_alert_body']) - .' ,ticket_overdue_subj='.db_input($info['ticket_overdue_subj']) - .' ,ticket_overdue_body='.db_input($info['ticket_overdue_body']) - .' ,ticket_overlimit_subj='.db_input($info['ticket_overlimit_subj']) - .' ,ticket_overlimit_body='.db_input($info['ticket_overlimit_body']) - .' ,ticket_reply_subj='.db_input($info['ticket_reply_subj']) - .' ,ticket_reply_body='.db_input($info['ticket_reply_body']); - - if(db_query($sql) && ($id=db_insert_id())) + $sql='INSERT INTO '.EMAIL_TEMPLATE_GRP_TABLE + .' SET created=NOW(), '.$sql; + if(!db_query($sql) || !($new_id=db_insert_id())) { + $errors['err']='Unable to create template. Internal error'; + return false; + } + + $sql='INSERT INTO '.EMAIL_TEMPLATE_TABLE.' + (created, updated, tpl_id, code_name, subject, body) + SELECT NOW() as created, NOW() as updated, '.db_input($new_id) + .' as tpl_id, code_name, subject, body + FROM '.EMAIL_TEMPLATE_TABLE + .' WHERE tpl_id='.db_input($tpl->getId()); + + if(db_query($sql) && db_insert_id()) + return $new_id; + } + + return false; + } +} + +class EmailTemplate { + + var $id; + var $_group; + + function EmailTemplate($id, $group=null){ + $this->id=0; + $this->load($id); + if ($group) $this->_group = $group; + } + + function load($id) { + + if(!$id && !($id=$this->getId())) + return false; + + $sql='SELECT * FROM '.EMAIL_TEMPLATE_TABLE + .' WHERE id='.db_input($id); + + if(!($res=db_query($sql))|| !db_num_rows($res)) + return false; + + + $this->ht=db_fetch_array($res); + $this->id=$this->ht['id']; + + return true; + } + + function reload() { + return $this->load($this->getId()); + } + + function getId(){ + return $this->id; + } + + function getSubject() { + return $this->ht['subject']; + } + + function getBody() { + return $this->ht['body']; + } + + function getCodeName() { + return $this->ht['code_name']; + } + + function getTplId() { + return $this->ht['tpl_id']; + } + + function getGroup() { + if (!isset($this->_group)) + $this->_group = EmailTemplateGroup::lookup($this->getTplId()); + return $this->_group; + + } + + function getDescription() { + return $this->getGroup()->getTemplateDescription($this->ht['code_name']); + } + + function update($vars, &$errors) { + + if(!$this->save($this->getId(),$vars,$errors)) + return false; + + $this->reload(); + + return true; + } + + function save($id, $vars, &$errors) { + if(!$vars['subj']) + $errors['subj']='Message subject required'; + + if(!$vars['body']) + $errors['body']='Message body required'; + + if (!$id) { + if (!$vars['tpl_id']) + $errors['tpl_id']='Template group required'; + if (!$vars['code_name']) + $errprs['code_name']='Code name required'; + } + + if ($errors) + return false; + + if ($id) { + $sql='UPDATE '.EMAIL_TEMPLATE_TABLE.' SET updated=NOW() ' + .', subject='.db_input($vars['subj']) + .', body='.db_input($vars['body']) + .' WHERE id='.db_input($this->getId()); + + return (db_query($sql)); + } else { + $sql='INSERT INTO '.EMAIL_TEMPLATE_TABLE.' SET created=NOW(), + updated=NOW(), tpl_id='.db_input($vars['tpl_id']) + .', code_name='.db_input($vars['code_name']) + .', subject='.db_input($vars['subj']) + .', body='.db_input($vars['body']); + if (db_query($sql) && ($id=db_insert_id())) return $id; - - $errors['err']='Unable to create template. Internal error'; } - + return null; + } + + function create($vars, &$errors) { + return self::save(0, $vars, $errors); + } + + function add($vars, &$errors) { + return self::lookup(self::create($vars, $errors)); + } + + function lookupByName($tpl, $name, $group=null) { + $sql = 'SELCT id FROM '.EMAIL_TEMPLATE_TABLE + .' WHERE tpl_id='.db_input($tpl_id) + .' AND code_name='.db_input($name); + if (($res=db_query($sql)) && ($id=db_result($res))) + return self::lookup($id, $group); + return false; } + + function lookup($id, $group=null) { + return ($id && is_numeric($id) && ($t= new EmailTemplate($id, $group)) && $t->getId()==$id)?$t:null; + } } ?> diff --git a/include/class.topic.php b/include/class.topic.php index 9379e8ec95ec94a2e72f20bfe8a587da946f5398..8b02e5eeab5fe04344a3c81ea987f7577c51235a 100644 --- a/include/class.topic.php +++ b/include/class.topic.php @@ -16,10 +16,12 @@ class Topic { var $id; - + var $ht; + var $parent; - + var $page; + function Topic($id) { $this->id=0; $this->load($id); @@ -40,11 +42,14 @@ class Topic { return false; $this->ht = db_fetch_array($res); - $this->id=$this->ht['topic_id']; - + $this->id = $this->ht['topic_id']; + + $this->page = null; + + return true; } - + function reload() { return $this->load(); } @@ -52,7 +57,7 @@ class Topic { function asVar() { return $this->getName(); } - + function getId() { return $this->id; } @@ -71,7 +76,7 @@ class Topic { function getName() { return $this->ht['name']; } - + function getDeptId() { return $this->ht['dept_id']; } @@ -91,7 +96,18 @@ class Topic { function getTeamId() { return $this->ht['team_id']; } - + + function getPageId() { + return $this->ht['page_id']; + } + + function getPage() { + if(!$this->page && $this->getPageId()) + $this->page = Page::lookup($this->getPageId()); + + return $this->page; + } + function autoRespond() { return (!$this->ht['noautoresp']); } @@ -137,7 +153,7 @@ class Topic { return $num; } /*** Static functions ***/ - function create($vars,&$errors) { + function create($vars, &$errors) { return self::save(0, $vars, $errors); } @@ -195,10 +211,10 @@ class Topic { if(!$vars['dept_id']) $errors['dept_id']='You must select a department'; - + if(!$vars['priority_id']) $errors['priority_id']='You must select a priority'; - + if($errors) return false; $sql=' updated=NOW() ' @@ -207,6 +223,7 @@ class Topic { .',dept_id='.db_input($vars['dept_id']) .',priority_id='.db_input($vars['priority_id']) .',sla_id='.db_input($vars['sla_id']) + .',page_id='.db_input($vars['page_id']) .',isactive='.db_input($vars['isactive']) .',ispublic='.db_input($vars['ispublic']) .',noautoresp='.db_input(isset($vars['noautoresp'])?1:0) @@ -219,7 +236,7 @@ class Topic { $sql.=',staff_id=0, team_id='.db_input(preg_replace("/[^0-9]/", "", $vars['assign'])); else $sql.=',staff_id=0, team_id=0 '; //no auto-assignment! - + if($id) { $sql='UPDATE '.TOPIC_TABLE.' SET '.$sql.' WHERE topic_id='.db_input($id); if(db_query($sql)) @@ -230,10 +247,10 @@ class Topic { $sql='INSERT INTO '.TOPIC_TABLE.' SET '.$sql.',created=NOW()'; if(db_query($sql) && ($id=db_insert_id())) return $id; - + $errors['err']='Unable to create the topic. Internal error'; } - + return false; } } diff --git a/include/client/thankyou.inc.php b/include/client/thankyou.inc.php deleted file mode 100644 index 6e2fe3b4b7218ec1468d09ec71fd1b70624cd70f..0000000000000000000000000000000000000000 --- a/include/client/thankyou.inc.php +++ /dev/null @@ -1,20 +0,0 @@ -<?php -if(!defined('OSTCLIENTINC') || !is_object($ticket)) die('Kwaheri rafiki!'); -//Please customize the message below to fit your organization speak! -?> -<div style="margin:5px 100px 100px 0;"> - <?php echo Format::htmlchars($ticket->getName()); ?>,<br> - <p> - Thank you for contacting us.<br> - A support ticket request has been created and a representative will be getting back to you shortly if necessary.</p> - - <?php if($cfg->autoRespONNewTicket()){ ?> - <p>An email with the ticket number has been sent to <b><?php echo $ticket->getEmail(); ?></b>. - You'll need the ticket number along with your email to view status and progress online. - </p> - <p> - If you wish to send additional comments or information regarding same issue, please follow the instructions on the email. - </p> - <?php } ?> - <p>Support Team </p> -</div> diff --git a/include/staff/department.inc.php b/include/staff/department.inc.php index 00a65ebc54cfc1345d55ea365e00f5ff9aaa12ca..707aa69dda1d5756453c9f86caa1efcff33406b4 100644 --- a/include/staff/department.inc.php +++ b/include/staff/department.inc.php @@ -88,7 +88,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <select name="tpl_id"> <option value="0">— System default —</option> <?php - $sql='SELECT tpl_id,name FROM '.EMAIL_TEMPLATE_TABLE.' tpl WHERE isactive=1 ORDER by name'; + $sql='SELECT tpl_id,name FROM '.EMAIL_TEMPLATE_GRP_TABLE.' tpl WHERE isactive=1 ORDER by name'; if(($res=db_query($sql)) && db_num_rows($res)){ while(list($id,$name)=db_fetch_row($res)){ $selected=($info['tpl_id'] && $id==$info['tpl_id'])?'selected="selected"':''; @@ -144,7 +144,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <span class="error"> <?php echo $errors['manager_id']; ?></span> </td> </tr> - <?php + <?php } ?> <tr> @@ -167,7 +167,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); </td> <td> <input type="checkbox" name="ticket_auto_response" value="0" <?php echo !$info['ticket_auto_response']?'checked="checked"':''; ?> > - + <strong>Disable</strong> new ticket auto-response for this Dept. </td> </tr> @@ -217,7 +217,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); .' ORDER BY group_name'; if(($res=db_query($sql)) && db_num_rows($res)){ while(list($id, $name, $members) = db_fetch_row($res)) { - if($members>0) + if($members>0) $members=sprintf('<a href="staff.php?a=filter&gid=%d">%d</a>', $id, $members); $ck=($info['groups'] && in_array($id,$info['groups']))?'checked="checked"':''; diff --git a/include/staff/helptopic.inc.php b/include/staff/helptopic.inc.php index e5dac76027006cdbbd6631a66c3df119c758d292..e54323ac491f61eb8ea4044440523369446ed5e0 100644 --- a/include/staff/helptopic.inc.php +++ b/include/staff/helptopic.inc.php @@ -149,6 +149,26 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <em>(Overwrites department's SLA)</em> </td> </tr> + <tr> + <td width="180">Thank-you Page:</td> + <td> + <select name="page_id"> + <option value="">— System Default —</option> + <?php + if(($pages = Page::getActiveThankYouPages())) { + foreach($pages as $page) { + if(strcasecmp($page->getType(), 'thank-you')) continue; + echo sprintf('<option value="%d" %s>%s</option>', + $page->getId(), + ($info['page_id']==$page->getId())?'selected="selected"':'', + $page->getName()); + } + } + ?> + </select> <font class="error"><?php echo $errors['page_id']; ?></font> + <em>(Overwrites global setting. Applies to web tickets only.)</em> + </td> + </tr> <tr> <td width="180"> Auto-assign To: @@ -156,14 +176,9 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <td> <select name="assign"> <option value="0">— Unassigned —</option> - - <?php - - $sql=' SELECT staff_id,CONCAT_WS(", ",lastname,firstname) as name '. ' FROM '.STAFF_TABLE.' WHERE isactive=1 ORDER BY name'; - if(($res=db_query($sql)) && db_num_rows($res)){ echo '<OPTGROUP label="Staff Members">'; while (list($id,$name) = db_fetch_row($res)){ @@ -171,10 +186,9 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); $selected = ($info['assign']==$k || $info['staff_id']==$id)?'selected="selected"':''; ?> <option value="<?php echo $k; ?>"<?php echo $selected; ?>><?php echo $name; ?></option> - + <?php } echo '</OPTGROUP>'; - } $sql='SELECT team_id, name FROM '.TEAM_TABLE.' WHERE isenabled=1'; if(($res=db_query($sql)) && db_num_rows($res)){ diff --git a/include/staff/page.inc.php b/include/staff/page.inc.php new file mode 100644 index 0000000000000000000000000000000000000000..be52b3607bda6e269d5f85bc7f8efc49f423b0bc --- /dev/null +++ b/include/staff/page.inc.php @@ -0,0 +1,104 @@ +<?php +if(!defined('OSTADMININC') || !$thisstaff || !$thisstaff->isAdmin()) die('Access Denied'); +$pageTypes = array( + 'landing' => 'Landing page', + 'offline' => 'Offline page', + 'thank-you' => 'Thank you page', + 'other' => 'Other', + ); +$info=array(); +$qstr=''; +if($page && $_REQUEST['a']!='add'){ + $title='Update Page'; + $action='update'; + $submit_text='Save Changes'; + $info=$page->getHashtable(); + $qstr.='&id='.$page->getId(); +}else { + $title='Add New Page'; + $action='add'; + $submit_text='Add Page'; + $info['isactive']=isset($info['isactive'])?$info['isactive']:0; + $qstr.='&a='.urlencode($_REQUEST['a']); +} +$info=Format::htmlchars(($errors && $_POST)?$_POST:$info); +?> +<form action="pages.php?<?php echo $qstr; ?>" method="post" id="save"> + <?php csrf_token(); ?> + <input type="hidden" name="do" value="<?php echo $action; ?>"> + <input type="hidden" name="a" value="<?php echo Format::htmlchars($_REQUEST['a']); ?>"> + <input type="hidden" name="id" value="<?php echo $info['id']; ?>"> + <h2>Email Template</h2> + <table class="form_table" width="940" border="0" cellspacing="0" cellpadding="2"> + <thead> + <tr> + <th colspan="2"> + <h4><?php echo $title; ?></h4> + <em>Page information.</em> + </th> + </tr> + </thead> + <tbody> + <tr> + <td width="180" class="required"> + Name: + </td> + <td> + <input type="text" size="40" name="name" value="<?php echo $info['name']; ?>"> + <span class="error">* <?php echo $errors['name']; ?></span> + </td> + </tr> + <tr> + <td width="180" class="required"> + Type: + </td> + <td> + <select name="type"> + <option value="" selected="selected">Select Page Type</option> + <?php + foreach($pageTypes as $k => $v) + echo sprintf('<option value="%s" %s>%s</option>', + $k, (($info['type']==$k)?'selected="selected"':''), $v); + ?> + </select> + <span class="error">* <?php echo $errors['type']; ?></span> + </td> + </tr> + <tr> + <td width="180" class="required"> + Status: + </td> + <td> + <input type="radio" name="isactive" value="1" <?php echo $info['isactive']?'checked="checked"':''; ?>><strong>Active</strong> + <input type="radio" name="isactive" value="0" <?php echo !$info['isactive']?'checked="checked"':''; ?>>Disabled + <span class="error">* <?php echo $errors['isactive']; ?></span> + </td> + </tr> + <tr> + <th colspan="2"> + <em><b>Page body</b>: Ticket variables are only supported in thank-you pages.<font class="error">* <?php echo $errors['body']; ?></font></em> + </th> + </tr> + <tr> + <td colspan=2 style="padding-left:3px;"> + <textarea name="body" cols="21" rows="12" style="width:98%;" class="richtext"><?php echo $info['body']; ?></textarea> + </td> + </tr> + <tr> + <th colspan="2"> + <em><strong>Admin Notes</strong>: Internal notes. </em> + </th> + </tr> + <tr> + <td colspan=2> + <textarea name="notes" cols="21" rows="8" style="width: 80%;"><?php echo $info['notes']; ?></textarea> + </td> + </tr> + </tbody> +</table> +<p style="padding-left:225px;"> + <input type="submit" name="submit" value="<?php echo $submit_text; ?>"> + <input type="reset" name="reset" value="Reset"> + <input type="button" name="cancel" value="Cancel" onclick='window.location.href="pages.php"'> +</p> +</form> diff --git a/include/staff/pages.inc.php b/include/staff/pages.inc.php new file mode 100644 index 0000000000000000000000000000000000000000..8fc14be6239ff685c0bb57630fe17fc313e7951c --- /dev/null +++ b/include/staff/pages.inc.php @@ -0,0 +1,152 @@ +<?php +if(!defined('OSTADMININC') || !$thisstaff->isAdmin()) die('Access Denied'); + +$qstr=''; +$sql='SELECT page.id, page.isactive, page.name, page.created, page.updated, count(topic.topic_id) as topics ' + .' FROM '.PAGE_TABLE.' page ' + .' LEFT JOIN '.TOPIC_TABLE.' topic ON(topic.page_id=page.id) ' + .' WHERE 1 '; +$sortOptions=array( + 'name'=>'page.name', 'status'=>'page.isactive', + 'created'=>'page.created', 'updated'=>'page.updated'); + +$orderWays=array('DESC'=>'DESC','ASC'=>'ASC'); +$sort=($_REQUEST['sort'] && $sortOptions[strtolower($_REQUEST['sort'])])?strtolower($_REQUEST['sort']):'name'; +//Sorting options... +if($sort && $sortOptions[$sort]) { + $order_column =$sortOptions[$sort]; +} + +$order_column=$order_column?$order_column:'page.name'; + +if($_REQUEST['order'] && $orderWays[strtoupper($_REQUEST['order'])]) { + $order=$orderWays[strtoupper($_REQUEST['order'])]; +} +$order=$order?$order:'ASC'; + +if($order_column && strpos($order_column,',')){ + $order_column=str_replace(','," $order,",$order_column); +} +$x=$sort.'_sort'; +$$x=' class="'.strtolower($order).'" '; +$order_by="$order_column $order "; + +$total=db_count('SELECT count(*) FROM '.PAGE_TABLE.' page '); +$page=($_GET['p'] && is_numeric($_GET['p']))?$_GET['p']:1; +$pageNav=new Pagenate($total, $page, PAGE_LIMIT); +$pageNav->setURL('pages.php',$qstr.'&sort='.urlencode($_REQUEST['sort']).'&order='.urlencode($_REQUEST['order'])); +//Ok..lets roll...create the actual query +$qstr.='&order='.($order=='DESC'?'ASC':'DESC'); +$query="$sql GROUP BY page.id ORDER BY $order_by LIMIT ".$pageNav->getStart().",".$pageNav->getLimit(); +$res=db_query($query); +if($res && ($num=db_num_rows($res))) + $showing=$pageNav->showing(); +else + $showing='No pages found!'; + +?> + +<div style="width:700;padding-top:5px; float:left;"> + <h2>Site Pages</h2> +</div> +<div style="float:right;text-align:right;padding-top:5px;padding-right:5px;"> + <b><a href="pages.php?a=add" class="Icon newPage">Add New Page</a></b></div> +<div class="clear"></div> +<form action="pages.php" method="POST" name="tpls"> + <?php csrf_token(); ?> + <input type="hidden" name="do" value="mass_process" > +<input type="hidden" id="action" name="a" value="" > + <table class="list" border="0" cellspacing="1" cellpadding="0" width="940"> + <caption><?php echo $showing; ?></caption> + <thead> + <tr> + <th width="7"> </th> + <th width="380"><a <?php echo $name_sort; ?> href="pages.php?<?php echo $qstr; ?>&sort=name">Name</a></th> + <th width="120"><a <?php echo $status_sort; ?> href="pages.php?<?php echo $qstr; ?>&sort=status">Status</a></th> + <th width="150" nowrap><a <?php echo $created_sort; ?>href="pages.php?<?php echo $qstr; ?>&sort=created">Date Added</a></th> + <th width="150" nowrap><a <?php echo $updated_sort; ?>href="pages.php?<?php echo $qstr; ?>&sort=updated">Last Updated</a></th> + </tr> + </thead> + <tbody> + <?php + $total=0; + $ids=($errors && is_array($_POST['ids']))?$_POST['ids']:null; + if($res && db_num_rows($res)): + $defaultPages=$cfg->getDefaultPages(); + while ($row = db_fetch_array($res)) { + $sel=false; + if($ids && in_array($row['id'], $ids)) + $sel=true; + $inuse = ($row['topics'] || in_array($row['id'], $defaultPages)); + ?> + <tr id="<?php echo $row['id']; ?>"> + <td width=7px> + <input type="checkbox" class="ckb" name="ids[]" value="<?php echo $row['id']; ?>" + <?php echo $sel?'checked="checked"':''; ?>> + </td> + <td> <a href="pages.php?id=<?php echo $row['id']; ?>"><?php echo Format::htmlchars($row['name']); ?></a></td> + <td> + <?php echo $row['isactive']?'Active':'<b>Disabled</b>'; ?> + <?php echo $inuse?'<em>(in-use)</em>':''; ?> + </td> + <td> <?php echo Format::db_date($row['created']); ?></td> + <td> <?php echo Format::db_datetime($row['updated']); ?></td> + </tr> + <?php + } //end of while. + endif; ?> + <tfoot> + <tr> + <td colspan="6"> + <?php if($res && $num){ ?> + Select: + <a id="selectAll" href="#ckb">All</a> + <a id="selectNone" href="#ckb">None</a> + <a id="selectToggle" href="#ckb">Toggle</a> + <?php }else{ + echo 'No pages found'; + } ?> + </td> + </tr> + </tfoot> +</table> +<?php +if($res && $num): //Show options.. + echo '<div> Page:'.$pageNav->getPageLinks().' </div>'; +?> +<p class="centered" id="actions"> + <input class="button" type="submit" name="enable" value="Enable" > + <input class="button" type="submit" name="disable" value="Disable" > + <input class="button" type="submit" name="delete" value="Delete" > +</p> +<?php +endif; +?> +</form> + +<div style="display:none;" class="dialog" id="confirm-action"> + <h3>Please Confirm</h3> + <a class="close" href="">×</a> + <hr/> + <p class="confirm-action" style="display:none;" id="enable-confirm"> + Are you sure want to <b>enable</b> selected pages? + </p> + <p class="confirm-action" style="display:none;" id="disable-confirm"> + Are you sure want to <b>disable</b> selected pages? + </p> + <p class="confirm-action" style="display:none;" id="delete-confirm"> + <font color="red"><strong>Are you sure you want to DELETE selected pages?</strong></font> + <br><br>Deleted pages CANNOT be recovered. + </p> + <div>Please confirm to continue.</div> + <hr style="margin-top:1em"/> + <p class="full-width"> + <span class="buttons" style="float:left"> + <input type="button" value="No, Cancel" class="close"> + </span> + <span class="buttons" style="float:right"> + <input type="button" value="Yes, Do it!" class="confirm"> + </span> + </p> + <div class="clear"></div> +</div> diff --git a/include/staff/settings-pages.inc.php b/include/staff/settings-pages.inc.php new file mode 100644 index 0000000000000000000000000000000000000000..c9c91343c153af42b048b6b6da121d5bc47f37cb --- /dev/null +++ b/include/staff/settings-pages.inc.php @@ -0,0 +1,73 @@ +<?php +if(!defined('OSTADMININC') || !$thisstaff || !$thisstaff->isAdmin() || !$config) die('Access Denied'); +$pages = Page::getPages(); +?> +<h2>Site Pages</h2> +<form action="settings.php?t=pages" method="post" id="save"> +<?php csrf_token(); ?> +<input type="hidden" name="t" value="pages" > +<table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2"> + <thead> + <tr> + <th colspan="2"> + <h4>Pages</h4> + <em>To edit or add new pages go to <a href="pages">Manage > Site Pages</a></em> + </th> + </tr> + </thead> + <tbody> + <tr> + <td width="220" class="required">Default Landing Page:</td> + <td> + <select name="landing_page_id"> + <option value="">— Select Landing Page —</option> + <?php + foreach($pages as $page) { + if(strcasecmp($page->getType(), 'landing')) continue; + echo sprintf('<option value="%d" %s>%s</option>', + $page->getId(), + ($config['landing_page_id']==$page->getId())?'selected="selected"':'', + $page->getName()); + } ?> + </select> <font class="error">* <?php echo $errors['landing_page_id']; ?></font> + </td> + </tr> + <tr> + <td width="220" class="required">Default Offline Page:</td> + <td> + <select name="offline_page_id"> + <option value="">— Select Offline Page —</option> + <?php + foreach($pages as $page) { + if(strcasecmp($page->getType(), 'offline')) continue; + echo sprintf('<option value="%d" %s>%s</option>', + $page->getId(), + ($config['offline_page_id']==$page->getId())?'selected="selected"':'', + $page->getName()); + } ?> + </select> <font class="error">* <?php echo $errors['offline_page_id']; ?></font> + </td> + </tr> + <tr> + <td width="220" class="required">Default Thank-You Page:</td> + <td> + <select name="thank-you_page_id"> + <option value="">— Select Thank-You Page —</option> + <?php + foreach($pages as $page) { + if(strcasecmp($page->getType(), 'thank-you')) continue; + echo sprintf('<option value="%d" %s>%s</option>', + $page->getId(), + ($config['thank-you_page_id']==$page->getId())?'selected="selected"':'', + $page->getName()); + } ?> + </select> <font class="error">* <?php echo $errors['thank-you_page_id']; ?></font> + </td> + </tr> + </tbody> +</table> +<p style="padding-left:250px;"> + <input class="button" type="submit" name="submit" value="Save Changes"> + <input class="button" type="reset" name="reset" value="Reset Changes"> +</p> +</form> diff --git a/include/staff/settings-system.inc.php b/include/staff/settings-system.inc.php index 1576ca1f9ab0f51f4ef60b120a1d7ec046f879dc..6fade6d964b1fab6cca118fa0b8cff86841aa417 100644 --- a/include/staff/settings-system.inc.php +++ b/include/staff/settings-system.inc.php @@ -60,7 +60,7 @@ $gmtime = Misc::gmtime(); <select name="default_template_id"> <option value="">— Select Default Template —</option> <?php - $sql='SELECT tpl_id,name FROM '.EMAIL_TEMPLATE_TABLE.' WHERE isactive=1 ORDER BY name'; + $sql='SELECT tpl_id,name FROM '.EMAIL_TEMPLATE_GRP_TABLE.' WHERE isactive=1 ORDER BY name'; if(($res=db_query($sql)) && db_num_rows($res)){ while (list($id, $name) = db_fetch_row($res)){ $selected = ($config['default_template_id']==$id)?'selected="selected"':''; ?> @@ -99,7 +99,7 @@ $gmtime = Misc::gmtime(); </tr> <tr> <td>Purge Logs:</td> - <td> + <td> <select name="log_graceperiod"> <option value=0 selected>Never Purge Logs</option> <?php @@ -172,7 +172,7 @@ $gmtime = Misc::gmtime(); echo sprintf('<option value="%d" %s>%d</option>', $i,(($config['client_login_timeout']==$i)?'selected="selected"':''), $i); } ?> - </select> minute lock-out is enforced. + </select> minute lock-out is enforced. </td> </tr> diff --git a/include/staff/template.inc.php b/include/staff/template.inc.php index aff5f8e3b780e46bd54bc23e0ded14694fe63e71..e4c52705acc893f63c623695517ee9077932bc4d 100644 --- a/include/staff/template.inc.php +++ b/include/staff/template.inc.php @@ -8,8 +8,8 @@ if($template && $_REQUEST['a']!='add'){ $action='update'; $submit_text='Save Changes'; $info=$template->getInfo(); - $info['id']=$template->getId(); - $qstr.='&id='.$template->getId(); + $info['tpl_id']=$template->getId(); + $qstr.='&tpl_id='.$template->getId(); }else { $title='Add New Template'; $action='add'; @@ -23,7 +23,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <?php csrf_token(); ?> <input type="hidden" name="do" value="<?php echo $action; ?>"> <input type="hidden" name="a" value="<?php echo Format::htmlchars($_REQUEST['a']); ?>"> - <input type="hidden" name="id" value="<?php echo $info['id']; ?>"> + <input type="hidden" name="tpl_id" value="<?php echo $info['tpl_id']; ?>"> <h2>Email Template</h2> <table class="form_table" width="940" border="0" cellspacing="0" cellpadding="2"> <thead> @@ -74,10 +74,31 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); </th> </tr> <?php - foreach(Template::message_templates() as $k=>$tpl){ - echo sprintf('<tr><td colspan=2> <strong><a href="templates.php?id=%d&a=manage&tpl=%s">%s</a></strong> - <em>%s</em></td></tr>', - $template->getId(),$k,Format::htmlchars($tpl['name']),Format::htmlchars($tpl['desc'])); + foreach($template->getTemplates() as $tpl){ + $info = $tpl->getDescription(); + if (!$info['name']) + continue; + echo sprintf('<tr><td colspan=2> <strong><a href="templates.php?id=%d&a=manage">%s</a></strong> - <em>%s</em></td></tr>', + $tpl->getId(),Format::htmlchars($info['name']), + Format::htmlchars($info['desc'])); } + if (($undef = $template->getUndefinedTemplateNames())) { ?> + <tr> + <th colspan="2"> + <em><strong>Unimplemented Template Messages</strong>: Click + on the message to implement</em> + </th> + </tr> + <?php + foreach($template->getUndefinedTemplateNames() as $cn=>$info){ + echo sprintf('<tr><td colspan=2> <strong><a + href="templates.php?tpl_id=%d&a=implement&code_name=%s" + style="color:red;text-decoration:underline" + >%s</a></strong> - <em>%s</em></td></tr>', + $template->getId(),$cn,Format::htmlchars($info['name']), + Format::htmlchars($info['desc'])); + } + } }else{ ?> <tr> <td width="180" class="required"> @@ -87,7 +108,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <select name="tpl_id"> <option value="0">— Select One ‐</option> <?php - $sql='SELECT tpl_id,name FROM '.EMAIL_TEMPLATE_TABLE.' ORDER by name'; + $sql='SELECT tpl_id,name FROM '.EMAIL_TEMPLATE_GRP_TABLE.' ORDER by name'; if(($res=db_query($sql)) && db_num_rows($res)){ while(list($id,$name)=db_fetch_row($res)){ $selected=($info['tpl_id'] && $id==$info['tpl_id'])?'selected="selected"':''; diff --git a/include/staff/templates.inc.php b/include/staff/templates.inc.php index a0f5de468a76bf7cde53e73bdc0767606ea6207b..1e1057353bfa82eadaca4d08857d7061fa0ce9fd 100644 --- a/include/staff/templates.inc.php +++ b/include/staff/templates.inc.php @@ -3,7 +3,7 @@ if(!defined('OSTADMININC') || !$thisstaff->isAdmin()) die('Access Denied'); $qstr=''; $sql='SELECT tpl.*,count(dept.tpl_id) as depts '. - 'FROM '.EMAIL_TEMPLATE_TABLE.' tpl '. + 'FROM '.EMAIL_TEMPLATE_GRP_TABLE.' tpl '. 'LEFT JOIN '.DEPT_TABLE.' dept USING(tpl_id) '. 'WHERE 1 '; $sortOptions=array('name'=>'tpl.name','status'=>'tpl.isactive','created'=>'tpl.created','updated'=>'tpl.updated'); @@ -27,7 +27,7 @@ $x=$sort.'_sort'; $$x=' class="'.strtolower($order).'" '; $order_by="$order_column $order "; -$total=db_count('SELECT count(*) FROM '.EMAIL_TEMPLATE_TABLE.' tpl '); +$total=db_count('SELECT count(*) FROM '.EMAIL_TEMPLATE_GRP_TABLE.' tpl '); $page=($_GET['p'] && is_numeric($_GET['p']))?$_GET['p']:1; $pageNav=new Pagenate($total, $page, PAGE_LIMIT); $pageNav->setURL('templates.php',$qstr.'&sort='.urlencode($_REQUEST['sort']).'&order='.urlencode($_REQUEST['order'])); @@ -56,7 +56,7 @@ else <caption><?php echo $showing; ?></caption> <thead> <tr> - <th width="7"> </th> + <th width="7"> </th> <th width="350"><a <?php echo $name_sort; ?> href="templates.php?<?php echo $qstr; ?>&sort=name">Name</a></th> <th width="100"><a <?php echo $status_sort; ?> href="templates.php?<?php echo $qstr; ?>&sort=status">Status</a></th> <th width="80"><a <?php echo $inuse_sort; ?> href="templates.php?<?php echo $qstr; ?>&sort=inuse">In-Use</a></th> @@ -75,15 +75,15 @@ else $sel=false; if($ids && in_array($row['tpl_id'],$ids)) $sel=true; - + $default=($defaultTplId==$row['tpl_id'])?'<small class="fadded">(System Default)</small>':''; ?> <tr id="<?php echo $row['tpl_id']; ?>"> <td width=7px> - <input type="checkbox" class="ckb" name="ids[]" value="<?php echo $row['tpl_id']; ?>" + <input type="checkbox" class="ckb" name="ids[]" value="<?php echo $row['tpl_id']; ?>" <?php echo $sel?'checked="checked"':''; ?> <?php echo $default?'disabled="disabled"':''; ?> > </td> - <td> <a href="templates.php?id=<?php echo $row['tpl_id']; ?>"><?php echo Format::htmlchars($row['name']); ?></a> + <td> <a href="templates.php?tpl_id=<?php echo $row['tpl_id']; ?>"><?php echo Format::htmlchars($row['name']); ?></a> <?php echo $default; ?></td> <td> <?php echo $row['isactive']?'Active':'<b>Disabled</b>'; ?></td> <td> <?php echo ($inuse)?'<b>Yes</b>':'No'; ?></td> diff --git a/include/staff/tpl.inc.php b/include/staff/tpl.inc.php index 13dcf25718874fb7eb48371ad68daba9ff078312..8c1ede75e5e4ed12092c08201d22a0aebeaa2cc2 100644 --- a/include/staff/tpl.inc.php +++ b/include/staff/tpl.inc.php @@ -1,23 +1,45 @@ <?php -$msgtemplates=Template::message_templates(); $info=Format::htmlchars(($errors && $_POST)?$_POST:$_REQUEST); -$info['tpl']=($info['tpl'] && $msgtemplates[$info['tpl']])?$info['tpl']:'ticket_autoresp'; + +if (is_a($template, EmailTemplateGroup)) { + // New template implementation + $id = 0; + $tpl_id = $template->getId(); + $name = $template->getName(); + $selected = $_REQUEST['code_name']; + $action = 'implement'; + $extras = array('code_name'=>$selected, 'tpl_id'=>$tpl_id); + $msgtemplates=$template->all_names; +} else { + // Template edit + $id = $template->getId(); + $tpl_id = $template->getTplId(); + $name = $template->getGroup()->getName(); + $selected = $template->getCodeName(); + $action = 'updatetpl'; + $extras = array(); + $msgtemplates=$template->getGroup()->all_names; + $info=array_merge(array('subj'=>$template->getSubject(), 'body'=>$template->getBody()),$info); +} +$info['tpl']=($info['tpl'] && $msgtemplates[$info['tpl']])?$info['tpl']:'ticket.autoresp'; $tpl=$msgtemplates[$info['tpl']]; -$info=array_merge($template->getMsgTemplate($info['tpl']),$info); ?> -<h2>Email Template Message - <span><?php echo $template->getName(); ?></span></h2> +<h2>Email Template Message - <span><?php echo $name; ?></span></h2> <div style="padding-top:10px;padding-bottom:5px;"> <form method="get" action="templates.php"> - <input type="hidden" name="id" value="<?php echo $template->getId(); ?>"> <input type="hidden" name="a" value="manage"> Message Template: - <select id="tpl_options" name="tpl" style="width:300px;"> + <select id="tpl_options" name="id" style="width:300px;"> <option value="">— Select Setting Group —</option> <?php - foreach($msgtemplates as $k=>$v) { - $sel=($info['tpl']==$k)?'selected="selected"':''; - echo sprintf('<option value="%s" %s>%s</option>',$k,$sel,$v['name']); + foreach($template->getGroup()->getTemplates() as $cn=>$t) { + $nfo=$t->getDescription(); + if (!$nfo['name']) + continue; + $sel=($selected==$cn)?'selected="selected"':''; + echo sprintf('<option value="%s" %s>%s</option>', + $t->getId(),$sel,$nfo['name']); } ?> </select> @@ -25,12 +47,14 @@ $info=array_merge($template->getMsgTemplate($info['tpl']),$info); <font color="red"><?php echo $errors['tpl']; ?></font> </form> </div> -<form action="templates.php?id=<?php echo $template->getId(); ?>" method="post" id="save"> +<form action="templates.php?id=<?php echo $id; ?>" method="post" id="save"> <?php csrf_token(); ?> -<input type="hidden" name="id" value="<?php echo $template->getId(); ?>"> -<input type="hidden" name="tpl" value="<?php echo $info['tpl']; ?>"> +<?php foreach ($extras as $k=>$v) { ?> + <input type="hidden" name="<?php echo $k; ?>" value="<?php echo $v; ?>" /> +<?php } ?> +<input type="hidden" name="id" value="<?php echo $id; ?>"> <input type="hidden" name="a" value="manage"> -<input type="hidden" name="do" value="updatetpl"> +<input type="hidden" name="do" value="<?php echo $action; ?>"> <table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2"> <thead> @@ -59,6 +83,7 @@ $info=array_merge($template->getMsgTemplate($info['tpl']),$info); <p style="padding-left:210px;"> <input class="button" type="submit" name="submit" value="Save Changes"> <input class="button" type="reset" name="reset" value="Reset Changes"> - <input class="button" type="button" name="cancel" value="Cancel Changes" onclick='window.location.href="templates.php?id=<?php echo $template->getId(); ?>"'> + <input class="button" type="button" name="cancel" value="Cancel Changes" + onclick='window.location.href="templates.php?tpl_id=<?php echo $tpl_id; ?>"'> </p> </form> diff --git a/include/upgrader/sql/852ca89e-740428f9.patch.sql b/include/upgrader/sql/852ca89e-740428f9.patch.sql new file mode 100644 index 0000000000000000000000000000000000000000..a122ae1bf08466e55702d9e3ca2aa2912f9299f7 --- /dev/null +++ b/include/upgrader/sql/852ca89e-740428f9.patch.sql @@ -0,0 +1,141 @@ +/** + * @version v1.7.1 + * @signature 740428f9986da6ad85f88ec841b57bfe + * + * - Migrates the email template table to two tables, groups and templates. + * Templates organized in a separate table by group will allow for a more + * extensible model for email templates. + * + * - Add site page table and default templates required by the system to function. + * + */ + +DROP TABLE IF EXISTS `%TABLE_PREFIX%email_template_group`; +CREATE TABLE `%TABLE_PREFIX%email_template_group` ( + `tpl_id` int(11) NOT NULL auto_increment, + `isactive` tinyint(1) unsigned NOT NULL default '0', + `name` varchar(32) NOT NULL default '', + `notes` text, + `created` datetime NOT NULL, + `updated` timestamp NOT NULL, + PRIMARY KEY (`tpl_id`) +) DEFAULT CHARSET=utf8; + +INSERT INTO `%TABLE_PREFIX%email_template_group` + SELECT `tpl_id`, `isactive`, `name`, `notes`, `created`, `updated` + FROM `%TABLE_PREFIX%email_template`; + +DROP TABLE IF EXISTS `%TABLE_PREFIX%_email_template`; +CREATE TABLE `%TABLE_PREFIX%_email_template` ( + `id` int(11) unsigned NOT NULL auto_increment, + `tpl_id` int(11) unsigned NOT NULL, + `code_name` varchar(32) NOT NULL, + `subject` varchar(255) NOT NULL default '', + `body` text NOT NULL, + `created` datetime NOT NULL, + `updated` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `template_lookup` (`tpl_id`, `code_name`) +) DEFAULT CHARSET=utf8; + +INSERT INTO `%TABLE_PREFIX%_email_template` + (`tpl_id`, `code_name`, `subject`, `body`, `created`, `updated`) + SELECT `tpl_id`, 'ticket.autoresp', ticket_autoresp_subj, ticket_autoresp_body, `created`, `updated` + FROM `%TABLE_PREFIX%email_template`; + +INSERT INTO `%TABLE_PREFIX%_email_template` + (`tpl_id`, `code_name`, `subject`, `body`, `created`, `updated`) + SELECT `tpl_id`, 'ticket.autoreply', ticket_autoreply_subj, ticket_autoreply_body, `created`, `updated` + FROM `%TABLE_PREFIX%email_template`; + +INSERT INTO `%TABLE_PREFIX%_email_template` + (`tpl_id`, `code_name`, `subject`, `body`, `created`, `updated`) + SELECT `tpl_id`, 'message.autoresp', message_autoresp_subj, message_autoresp_body, `created`, `updated` + FROM `%TABLE_PREFIX%email_template`; + +INSERT INTO `%TABLE_PREFIX%_email_template` + (`tpl_id`, `code_name`, `subject`, `body`, `created`, `updated`) + SELECT `tpl_id`, 'ticket.notice', ticket_notice_subj, ticket_notice_body, `created`, `updated` + FROM `%TABLE_PREFIX%email_template`; + +INSERT INTO `%TABLE_PREFIX%_email_template` + (`tpl_id`, `code_name`, `subject`, `body`, `created`, `updated`) + SELECT `tpl_id`, 'ticket.overlimit', ticket_overlimit_subj, ticket_overlimit_body, `created`, `updated` + FROM `%TABLE_PREFIX%email_template`; + +INSERT INTO `%TABLE_PREFIX%_email_template` + (`tpl_id`, `code_name`, `subject`, `body`, `created`, `updated`) + SELECT `tpl_id`, 'ticket.reply', ticket_reply_subj, ticket_reply_body, `created`, `updated` + FROM `%TABLE_PREFIX%email_template`; + +INSERT INTO `%TABLE_PREFIX%_email_template` + (`tpl_id`, `code_name`, `subject`, `body`, `created`, `updated`) + SELECT `tpl_id`, 'ticket.alert', ticket_alert_subj, ticket_alert_body, `created`, `updated` + FROM `%TABLE_PREFIX%email_template`; + +INSERT INTO `%TABLE_PREFIX%_email_template` + (`tpl_id`, `code_name`, `subject`, `body`, `created`, `updated`) + SELECT `tpl_id`, 'message.alert', message_alert_subj, message_alert_body, `created`, `updated` + FROM `%TABLE_PREFIX%email_template`; + +INSERT INTO `%TABLE_PREFIX%_email_template` + (`tpl_id`, `code_name`, `subject`, `body`, `created`, `updated`) + SELECT `tpl_id`, 'note.alert', note_alert_subj, note_alert_body, `created`, `updated` + FROM `%TABLE_PREFIX%email_template`; + +INSERT INTO `%TABLE_PREFIX%_email_template` + (`tpl_id`, `code_name`, `subject`, `body`, `created`, `updated`) + SELECT `tpl_id`, 'assigned.alert', assigned_alert_subj, assigned_alert_body, `created`, `updated` + FROM `%TABLE_PREFIX%email_template`; + +INSERT INTO `%TABLE_PREFIX%_email_template` + (`tpl_id`, `code_name`, `subject`, `body`, `created`, `updated`) + SELECT `tpl_id`, 'transfer.alert', transfer_alert_subj, transfer_alert_body, `created`, `updated` + FROM `%TABLE_PREFIX%email_template`; + +INSERT INTO `%TABLE_PREFIX%_email_template` + (`tpl_id`, `code_name`, `subject`, `body`, `created`, `updated`) + SELECT `tpl_id`, 'ticket.overdue', ticket_overdue_subj, ticket_overdue_body, `created`, `updated` + FROM `%TABLE_PREFIX%email_template`; + +DROP TABLE `%TABLE_PREFIX%email_template`; +ALTER TABLE `%TABLE_PREFIX%_email_template` + RENAME TO `%TABLE_PREFIX%email_template`; + +-- pages +CREATE TABLE IF NOT EXISTS `%TABLE_PREFIX%page` ( + `id` int(10) unsigned NOT NULL auto_increment, + `isactive` tinyint(1) unsigned NOT NULL default '0', + `type` enum('landing','offline','thank-you','other') NOT NULL default 'other', + `name` varchar(255) NOT NULL, + `body` text NOT NULL, + `notes` text, + `created` datetime NOT NULL, + `updated` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `name` (`name`) +) DEFAULT CHARSET=utf8; + + +INSERT INTO `%TABLE_PREFIX%page` (`isactive`, `type`, `name`, `body`, `notes`, `created`, `updated`) VALUES +(1, 'offline', 'Offline', '<div>\r\n<h1><span style="font-size: medium">Support Ticket System Offline</span></h1>\r\n<p>Thank you for your interest in contacting us.</p>\r\n<p>Our helpdesk is offline at the moment, please check back at a later time.</p>\r\n</div>', 'Default offline page', NOW(), NOW()), +(1, 'thank-you', 'Thank you', '<div>%{ticket.name},<br />\r\n \r\n<p>\r\nThank you for contacting us.</p><p> A support ticket request #%{ticket.number} has been created and a representative will be getting back to you shortly if necessary.</p>\r\n \r\n<p>Support Team </p>\r\n</div>', 'Default "thank you" page displayed after the end-user creates a web ticket.', NOW(), NOW()), +(1, 'landing', 'Landing', '<h1>Welcome to the Support Center</h1>\r\n<p>In order to streamline support requests and better serve you, we utilize a support ticket system. Every support request is assigned a unique ticket number which you can use to track the progress and responses online. For your reference we provide complete archives and history of all your support requests. A valid email address is required to submit a ticket.\r\n</p>\r\n', 'Introduction text on the landing page.', NOW(), NOW()); + +INSERT INTO `%TABLE_PREFIX%config` (`key`, `value`, `namespace`) VALUES + ('landing_page_id', (SELECT `id` FROM `%TABLE_PREFIX%page` WHERE `type` = 'landing'), 'core') +, ('offline_page_id', (SELECT `id` FROM `%TABLE_PREFIX%page` WHERE `type` = 'offline'), 'core') +, ('thank-you_page_id', (SELECT `id` FROM `%TABLE_PREFIX%page` WHERE `type` = 'thank-you'), 'core'); + +ALTER TABLE `%TABLE_PREFIX%help_topic` + ADD `page_id` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `sla_id` , + ADD INDEX ( `page_id` ); + +ALTER TABLE `%TABLE_PREFIX%file` + ADD `ft` CHAR( 1 ) NOT NULL DEFAULT 'T' AFTER `id`, + ADD INDEX ( `ft` ); + +-- Finished with patch +UPDATE `%TABLE_PREFIX%config` + SET `value` = '740428f9986da6ad85f88ec841b57bfe' + WHERE `key` = 'schema_signature' AND `namespace` = 'core'; diff --git a/index.php b/index.php index 0680a520d48df86ac572d36eead4f5b3dd6ec443..9a2ae35d32e47aee05ba40084ec256f840659c8e 100644 --- a/index.php +++ b/index.php @@ -17,13 +17,13 @@ require('client.inc.php'); $section = 'home'; require(CLIENTINC_DIR.'header.inc.php'); ?> - <div id="landing_page"> - <h1>Welcome to the Support Center</h1> - <p> - In order to streamline support requests and better serve you, we utilize a support ticket system. Every support request is assigned a unique ticket number which you can use to track the progress and responses online. For your reference we provide complete archives and history of all your support requests. A valid email address is required to submit a ticket. - </p> - + <?php + if($cfg && ($page = $cfg->getLandingPage())) + echo $page->getBody(); + else + echo '<h1>Welcome to the Support Center</h1>'; + ?> <div id="new_ticket"> <h3>Open A New Ticket</h3> <br> diff --git a/main.inc.php b/main.inc.php index d7f719c5da3ca5c9d45316157ad46f3ef33367d2..6f7c932045fa46099de9d707b69dc105bdfecfba 100644 --- a/main.inc.php +++ b/main.inc.php @@ -76,7 +76,7 @@ #Current version && schema signature (Changes from version to version) define('THIS_VERSION','1.7.0+'); //Shown on admin panel - define('SCHEMA_SIGNATURE', '852ca89e1440e736d763b3b87f039bd7'); //MD5 signature of the db schema. (used to trigger upgrades) + define('SCHEMA_SIGNATURE', '740428f9986da6ad85f88ec841b57bfe'); //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 @@ -120,6 +120,7 @@ require(INCLUDE_DIR.'class.http.php'); require(INCLUDE_DIR.'class.signal.php'); require(INCLUDE_DIR.'class.nav.php'); + require(INCLUDE_DIR.'class.page.php'); require(INCLUDE_DIR.'class.format.php'); //format helpers require(INCLUDE_DIR.'class.validator.php'); //Class to help with basic form input validation...please help improve it. require(INCLUDE_DIR.'class.mailer.php'); @@ -159,6 +160,8 @@ define('TEAM_TABLE',TABLE_PREFIX.'team'); define('TEAM_MEMBER_TABLE',TABLE_PREFIX.'team_member'); + define('PAGE_TABLE', TABLE_PREFIX.'page'); + define('FAQ_TABLE',TABLE_PREFIX.'faq'); define('FAQ_ATTACHMENT_TABLE',TABLE_PREFIX.'faq_attachment'); define('FAQ_TOPIC_TABLE',TABLE_PREFIX.'faq_topic'); @@ -176,6 +179,7 @@ define('TICKET_EMAIL_INFO_TABLE',TABLE_PREFIX.'ticket_email_info'); define('EMAIL_TABLE',TABLE_PREFIX.'email'); + define('EMAIL_TEMPLATE_GRP_TABLE',TABLE_PREFIX.'email_template_group'); define('EMAIL_TEMPLATE_TABLE',TABLE_PREFIX.'email_template'); define('FILTER_TABLE',TABLE_PREFIX.'filter'); diff --git a/offline.php b/offline.php index 4e73aff2a856c3529f423c9465d85c2fee804147..04323f9e0a86d6831b6e6149ed65f3933fa88ed1 100644 --- a/offline.php +++ b/offline.php @@ -1,30 +1,34 @@ -<?php -/********************************************************************* - offline.php - - Offline page...modify to fit your needs. - - Peter Rotich <peter@osticket.com> - Copyright (c) 2006-2013 osTicket - 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: -**********************************************************************/ -require_once('client.inc.php'); -if(is_object($ost) && $ost->isSystemOnline()) { - @header('Location: index.php'); //Redirect if the system is online. - include('index.php'); - exit; -} -$nav=null; -require(CLIENTINC_DIR.'header.inc.php'); -?> -<div id="landing_page"> - <h1>Support Ticket System Offline</h1> - <p>Thank you for your interest in contacting us.</p> - <p>Our helpdesk is offline at the moment, please check back at a later time.</p> -</div> -<?php require(CLIENTINC_DIR.'footer.inc.php'); ?> +<?php +/********************************************************************* + offline.php + + Offline page...modify to fit your needs. + + Peter Rotich <peter@osticket.com> + Copyright (c) 2006-2013 osTicket + 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: +**********************************************************************/ +require_once('client.inc.php'); +if(is_object($ost) && $ost->isSystemOnline()) { + @header('Location: index.php'); //Redirect if the system is online. + include('index.php'); + exit; +} +$nav=null; +require(CLIENTINC_DIR.'header.inc.php'); +?> +<div id="landing_page"> +<?php +if(($page=$cfg->getOfflinePage())) { + echo $page->getBody(); +} else { + echo '<h1>Support Ticket System Offline</h1>'; +} +?> +</div> +<?php require(CLIENTINC_DIR.'footer.inc.php'); ?> diff --git a/open.php b/open.php index 0ce680707f6930cc324d3c4952a7bdf550ff60e6..3292e8564900e9676784ca54dd0599e9e6f59d2c 100644 --- a/open.php +++ b/open.php @@ -15,7 +15,7 @@ **********************************************************************/ require('client.inc.php'); define('SOURCE','Web'); //Ticket source. -$inc='open.inc.php'; //default include. +$ticket = null; $errors=array(); if($_POST): $vars = $_POST; @@ -44,8 +44,6 @@ if($_POST): session_regenerate_id(); @header('Location: tickets.php?id='.$ticket->getExtId()); } - //Thank the user and promise speedy resolution! - $inc='thankyou.inc.php'; }else{ $errors['err']=$errors['err']?$errors['err']:'Unable to create a ticket. Please correct errors below and try again!'; } @@ -54,6 +52,19 @@ endif; //page $nav->setActiveNav('new'); require(CLIENTINC_DIR.'header.inc.php'); -require(CLIENTINC_DIR.$inc); +if($ticket + && ( + (($topic = $ticket->getTopic()) && ($page = $topic->getPage())) + || ($page = $cfg->getThankYouPage()) + )) { //Thank the user and promise speedy resolution! + //Hide ticket number - it should only be delivered via email for security reasons. + echo Format::safe_html($ticket->replaceVars(str_replace( + array('%{ticket.number}', '%{ticket.extId}', '%{ticket}'), //ticket number vars. + array_fill(0, 3, 'XXXXXX'), + $page->getBody() + ))); +} else { + require(CLIENTINC_DIR.'open.inc.php'); +} require(CLIENTINC_DIR.'footer.inc.php'); ?> diff --git a/scp/css/scp.css b/scp/css/scp.css index 8fd39dd21f6e539df9442f20006a8e8f8720ede1..27da30ce79989c3007dcf13bf1d50a30ead23dd0 100644 --- a/scp/css/scp.css +++ b/scp/css/scp.css @@ -292,6 +292,9 @@ a.departments { background:url(../images/icons/list_departments.gif) } a.newDepartment { background:url(../images/icons/new_department.gif) } +a.pages { background:url(../images/icons/pages.gif) } +a.newPage { background:url(../images/icons/new_page.gif) } + /* Generic CSS based Icons. use=> <tag class="Icon iconname">text</tag> */ .Icon { @@ -1378,27 +1381,27 @@ ul.progress li.no small {color:red;} #bar.error { background: #ffd; text-align: center; color: #a00; font-weight: bold; } /* Overlay */ -#overlay { - display: none; - position: fixed; +#overlay { + display: none; + position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: #000; z-index: 1000; - -webkit-transform: translate3d(0,0,0); + -webkit-transform: translate3d(0,0,0); } #loading, #upgrading { border:1px solid #2a67ac; - padding: 10px 10px 10px 60px; - width: 300px; - height: 100px; + padding: 10px 10px 10px 60px; + width: 300px; + height: 100px; background: rgb( 255, 255, 255) url('../images/FhHRx-Spinner.gif') 10px 50% no-repeat; - position: fixed; - display: none; - z-index: 3000; + position: fixed; + display: none; + z-index: 3000; } #loading h4, #upgrading h4 { margin: 3px 0 0 0; padding: 0; color: #d80; } diff --git a/scp/images/icons/new_page.gif b/scp/images/icons/new_page.gif new file mode 100644 index 0000000000000000000000000000000000000000..0a675850c713e6b6ea9eda5920c39e158c2f05f8 Binary files /dev/null and b/scp/images/icons/new_page.gif differ diff --git a/scp/images/icons/pages.gif b/scp/images/icons/pages.gif new file mode 100644 index 0000000000000000000000000000000000000000..10a29ef0490733aaeee4f9b658cd1bb4962f021f Binary files /dev/null and b/scp/images/icons/pages.gif differ diff --git a/scp/pages.php b/scp/pages.php new file mode 100644 index 0000000000000000000000000000000000000000..295852bafd112f2e4a1254e480862845a3cba558 --- /dev/null +++ b/scp/pages.php @@ -0,0 +1,108 @@ +<?php +/********************************************************************* + pages.php + + Site pages. + + Peter Rotich <peter@osticket.com> + Copyright (c) 2006-2013 osTicket + 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: +**********************************************************************/ +require('admin.inc.php'); +require_once(INCLUDE_DIR.'class.page.php'); + +$page = null; +if($_REQUEST['id'] && !($page=Page::lookup($_REQUEST['id']))) + $errors['err']='Unknown or invalid page'; + +if($_POST) { + switch(strtolower($_POST['do'])) { + case 'add': + if(($pageId=Page::create($_POST, $errors))) { + $_REQUEST['a'] = null; + $msg='Page added successfully'; + } elseif(!$errors['err']) + $errors['err'] = 'Unable to add page. Try again!'; + break; + case 'update': + if(!$page) + $errors['err'] = 'Invalid or unknown page'; + elseif($page->update($_POST, $errors)) { + $msg='Page updated successfully'; + $_REQUEST['a']=null; //Go back to view + } elseif(!$errors['err']) + $errors['err'] = 'Unable to update page. Try again!'; + break; + case 'mass_process': + if(!$_POST['ids'] || !is_array($_POST['ids']) || !count($_POST['ids'])) { + $errors['err'] = 'You must select at least one page.'; + } elseif(array_intersect($_POST['ids'], $cfg->getDefaultPages()) && strcasecmp($_POST['a'], 'enable')) { + $errors['err'] = 'One or more of the selected pages is in-use and CANNOT be disabled/deleted.'; + } else { + $count=count($_POST['ids']); + switch(strtolower($_POST['a'])) { + case 'enable': + $sql='UPDATE '.PAGE_TABLE.' SET isactive=1 ' + .' WHERE id IN ('.implode(',', db_input($_POST['ids'])).')'; + if(db_query($sql) && ($num=db_affected_rows())) { + if($num==$count) + $msg = 'Selected pages enabled'; + else + $warn = "$num of $count selected pages enabled"; + } else { + $errors['err'] = 'Unable to enable selected pages'; + } + break; + case 'disable': + $i = 0; + foreach($_POST['ids'] as $k=>$v) { + if(($p=Page::lookup($v)) && $p->disable()) + $i++; + } + + if($i && $i==$count) + $msg = 'Selected pages disabled'; + elseif($i>0) + $warn = "$num of $count selected pages disabled"; + elseif(!$errors['err']) + $errors['err'] = 'Unable to disable selected pages'; + break; + case 'delete': + $i=0; + foreach($_POST['ids'] as $k=>$v) { + if(($p=Page::lookup($v)) && $p->delete()) + $i++; + } + + if($i && $i==$count) + $msg = 'Selected pages deleted successfully'; + elseif($i>0) + $warn = "$i of $count selected pages deleted"; + elseif(!$errors['err']) + $errors['err'] = 'Unable to delete selected pages'; + break; + default: + $errors['err']='Unknown action - get technical help.'; + } + } + break; + default: + $errors['err']='Unknown action/command'; + break; + } +} + +$inc='pages.inc.php'; +if($page || $_REQUEST['a']=='add') + $inc='page.inc.php'; + +$nav->setTabActive('manage'); +require_once(STAFFINC_DIR.'header.inc.php'); +require_once(STAFFINC_DIR.$inc); +require_once(STAFFINC_DIR.'footer.inc.php'); +?> diff --git a/scp/settings.php b/scp/settings.php index 2b30ced16a154a9a6976206045a801f2ae5efe68..9c8f70ac43d5cfd2b158334f690fd21529bbecaa 100644 --- a/scp/settings.php +++ b/scp/settings.php @@ -19,6 +19,7 @@ $settingOptions=array( 'system' => 'System Settings', 'tickets' => 'Ticket Settings and Options', 'emails' => 'Email Settings', + 'pages' => 'Site Pages', 'kb' => 'Knowledgebase Settings', 'autoresp' => 'Autoresponder Settings', 'alerts' => 'Alerts and Notices Settings'); diff --git a/scp/templates.php b/scp/templates.php index a27d69b08a67ac1748ff7b2457d92b238bc390e3..fd0ed3dde61e306030d5ee5d89fc40d393526ea8 100644 --- a/scp/templates.php +++ b/scp/templates.php @@ -16,7 +16,11 @@ require('admin.inc.php'); include_once(INCLUDE_DIR.'class.template.php'); $template=null; -if($_REQUEST['id'] && !($template=Template::lookup($_REQUEST['id']))) +if($_REQUEST['tpl_id'] && + !($template=EmailTemplateGroup::lookup($_REQUEST['tpl_id']))) + $errors['err']='Unknown or invalid template group ID.'; +elseif($_REQUEST['id'] && + !($template=EmailTemplate::lookup($_REQUEST['id']))) $errors['err']='Unknown or invalid template ID.'; if($_POST){ @@ -24,13 +28,23 @@ if($_POST){ case 'updatetpl': if(!$template){ $errors['err']='Unknown or invalid template'; - }elseif($template->updateMsgTemplate($_POST,$errors)){ + }elseif($template->update($_POST,$errors)){ $template->reload(); $msg='Message template updated successfully'; }elseif(!$errors['err']){ $errors['err']='Error updating message template. Try again!'; } break; + case 'implement': + if(!$template){ + $errors['err']='Unknown or invalid template'; + }elseif($new = EmailTemplate::add($_POST,$errors)){ + $template = $new; + $msg='Message template updated successfully'; + }elseif(!$errors['err']){ + $errors['err']='Error updating message template. Try again!'; + } + break; case 'update': if(!$template){ $errors['err']='Unknown or invalid template'; @@ -41,7 +55,8 @@ if($_POST){ } break; case 'add': - if((Template::create($_POST,$errors))){ + if(($new=EmailTemplateGroup::add($_POST,$errors))){ + $template=$new; $msg='Template added successfully'; $_REQUEST['a']=null; }elseif(!$errors['err']){ @@ -55,7 +70,7 @@ if($_POST){ $count=count($_POST['ids']); switch(strtolower($_POST['a'])) { case 'enable': - $sql='UPDATE '.EMAIL_TEMPLATE_TABLE.' SET isactive=1 ' + $sql='UPDATE '.EMAIL_TEMPLATE_GRP_TABLE.' SET isactive=1 ' .' WHERE tpl_id IN ('.implode(',', db_input($_POST['ids'])).')'; if(db_query($sql) && ($num=db_affected_rows())){ if($num==$count) @@ -69,7 +84,7 @@ if($_POST){ case 'disable': $i=0; foreach($_POST['ids'] as $k=>$v) { - if(($t=Template::lookup($v)) && !$t->isInUse() && $t->disable()) + if(($t=EmailTemplateGroup::lookup($v)) && !$t->isInUse() && $t->disable()) $i++; } if($i && $i==$count) @@ -82,7 +97,7 @@ if($_POST){ case 'delete': $i=0; foreach($_POST['ids'] as $k=>$v) { - if(($t=Template::lookup($v)) && !$t->isInUse() && $t->delete()) + if(($t=EmailTemplateGroup::lookup($v)) && !$t->isInUse() && $t->delete()) $i++; } @@ -107,6 +122,8 @@ if($_POST){ $page='templates.inc.php'; if($template && !strcasecmp($_REQUEST['a'],'manage')){ $page='tpl.inc.php'; +}elseif($template && !strcasecmp($_REQUEST['a'],'implement')){ + $page='tpl.inc.php'; }elseif($template || !strcasecmp($_REQUEST['a'],'add')){ $page='template.inc.php'; } diff --git a/setup/inc/class.installer.php b/setup/inc/class.installer.php index 178f310e96ea1f4405a54f382b3d5ce2cdfb30e0..40d9137dc6ea723ea5c4cd9d357b4523bc234a43 100644 --- a/setup/inc/class.installer.php +++ b/setup/inc/class.installer.php @@ -134,7 +134,7 @@ class Installer extends SetupWizard { $sql='SELECT `dept_id` FROM '.PREFIX.'department ORDER BY `dept_id` LIMIT 1'; $dept_id_1 = db_result(db_query($sql, false), 0); - $sql='SELECT `tpl_id` FROM '.PREFIX.'email_template ORDER BY `tpl_id` LIMIT 1'; + $sql='SELECT `tpl_id` FROM '.PREFIX.'email_template_group ORDER BY `tpl_id` LIMIT 1'; $template_id_1 = db_result(db_query($sql, false), 0); $sql='SELECT `group_id` FROM '.PREFIX.'groups ORDER BY `group_id` LIMIT 1'; diff --git a/setup/inc/sql/osTicket-mysql.sql b/setup/inc/sql/osTicket-mysql.sql index 6ad1a1810f2248ac2c840a10c50e313c541e896b..54006366af4a2e5039777885c7ca66f6dd1dc831 100644 --- a/setup/inc/sql/osTicket-mysql.sql +++ b/setup/inc/sql/osTicket-mysql.sql @@ -301,59 +301,79 @@ INSERT INTO `%TABLE_PREFIX%filter_rule` ( `filter_id`, `isactive`, `what`,`how`,`val`,`created`) VALUES (LAST_INSERT_ID(), 1, 'email', 'equal', 'test@example.com',NOW()); -DROP TABLE IF EXISTS `%TABLE_PREFIX%email_template`; -CREATE TABLE `%TABLE_PREFIX%email_template` ( +DROP TABLE IF EXISTS `%TABLE_PREFIX%email_template_group`; +CREATE TABLE `%TABLE_PREFIX%email_template_group` ( `tpl_id` int(11) NOT NULL auto_increment, - `cfg_id` int(10) unsigned NOT NULL default '0', `isactive` tinyint(1) unsigned NOT NULL default '0', `name` varchar(32) NOT NULL default '', `notes` text, - `ticket_autoresp_subj` varchar(255) NOT NULL default '', - `ticket_autoresp_body` text NOT NULL, - `ticket_autoreply_subj` varchar(255) NOT NULL default '', - `ticket_autoreply_body` text NOT NULL, - `ticket_notice_subj` varchar(255) NOT NULL, - `ticket_notice_body` text NOT NULL, - `ticket_alert_subj` varchar(255) NOT NULL default '', - `ticket_alert_body` text NOT NULL, - `message_autoresp_subj` varchar(255) NOT NULL default '', - `message_autoresp_body` text NOT NULL, - `message_alert_subj` varchar(255) NOT NULL default '', - `message_alert_body` text NOT NULL, - `note_alert_subj` varchar(255) NOT NULL, - `note_alert_body` text NOT NULL, - `assigned_alert_subj` varchar(255) NOT NULL default '', - `assigned_alert_body` text NOT NULL, - `transfer_alert_subj` varchar(255) NOT NULL default '', - `transfer_alert_body` text NOT NULL, - `ticket_overdue_subj` varchar(255) NOT NULL default '', - `ticket_overdue_body` text NOT NULL, - `ticket_overlimit_subj` varchar(255) NOT NULL default '', - `ticket_overlimit_body` text NOT NULL, - `ticket_reply_subj` varchar(255) NOT NULL default '', - `ticket_reply_body` text NOT NULL, + `created` datetime NOT NULL, + `updated` timestamp NOT NULL, + PRIMARY KEY (`tpl_id`) +) DEFAULT CHARSET=utf8; + +INSERT INTO `%TABLE_PREFIX%email_template_group` SET + `isactive` = 1, `name` = 'osTicket Default Template', + `notes` = 'Default osTicket templates', `created` = NOW(), `updated` = NOW(); + +DROP TABLE IF EXISTS `%TABLE_PREFIX%email_template`; +CREATE TABLE `%TABLE_PREFIX%email_template` ( + `id` int(11) UNSIGNED NOT NULL auto_increment, + `tpl_id` int(11) UNSIGNED NOT NULL, + `code_name` varchar(32) NOT NULL, + `subject` varchar(255) NOT NULL default '', + `body` text NOT NULL, `created` datetime NOT NULL, `updated` datetime NOT NULL, - PRIMARY KEY (`tpl_id`), - KEY `cfg_id` (`cfg_id`) + PRIMARY KEY (`id`), + UNIQUE KEY `template_lookup` (`tpl_id`, `code_name`) ) DEFAULT CHARSET=utf8; -- TODO: Dump revised copy before release!!! -INSERT INTO `%TABLE_PREFIX%email_template` (`isactive`, `name`, `notes`, `ticket_autoresp_subj`, `ticket_autoresp_body`, `ticket_autoreply_subj`, `ticket_autoreply_body`, `ticket_notice_subj`, `ticket_notice_body`, `ticket_alert_subj`, `ticket_alert_body`, `message_autoresp_subj`, `message_autoresp_body`, `message_alert_subj`, `message_alert_body`, `note_alert_subj`, `note_alert_body`, `assigned_alert_subj`, `assigned_alert_body`, `transfer_alert_subj`, `transfer_alert_body`, `ticket_overdue_subj`, `ticket_overdue_body`, `ticket_overlimit_subj`, `ticket_overlimit_body`, `ticket_reply_subj`, `ticket_reply_body`, `created`, `updated`) VALUES -(1, 'osTicket Default Template', 'Default osTicket templates', 'Support Ticket Opened [#%{ticket.number}]', '%{ticket.name},\r\n\r\nA request for support has been created and assigned ticket #%{ticket.number}. A representative will follow-up with you as soon as possible.\r\n\r\nYou can view this ticket''s progress online here: %{ticket.client_link}.\r\n\r\nIf you wish to send additional comments or information regarding this issue, please don''t open a new ticket. Simply login using the link above and update the ticket.\r\n\r\n%{signature}', 'Support Ticket Opened [#%{ticket.number}]', '%{ticket.name},\r\n\r\nA request for support has been created and assigned ticket #%{ticket.number} with the following auto-reply:\r\n\r\n%{response}\r\n\r\n\r\nWe hope this response has sufficiently answered your questions. If not, please do not open another ticket. If need be, representative will follow-up with you as soon as possible.\r\n\r\nYou can view this ticket''s progress online here: %{ticket.client_link}.', '[#%{ticket.number}] %{ticket.subject}', '%{ticket.name},\r\n\r\nOur customer care team has created a ticket, #%{ticket.number} on your behalf, with the following message.\r\n\r\n%{message}\r\n\r\nIf you wish to provide additional comments or information regarding this issue, please don''t open a new ticket. You can update or view this ticket''s progress online here: %{ticket.client_link}.\r\n\r\n%{signature}', 'New Ticket Alert', '%{recipient},\r\n\r\nNew ticket #%{ticket.number} created.\r\n\r\n-----------------------\r\nName: %{ticket.name}\r\nEmail: %{ticket.email}\r\nDept: %{ticket.dept.name}\r\n\r\n%{message}\r\n-----------------------\r\n\r\nTo view/respond to the ticket, please login to the support ticket system.\r\n\r\n%{ticket.staff_link}\r\n\r\n- Your friendly Customer Support System - powered by osTicket.', '[#%{ticket.number}] Message Added', '%{ticket.name},\r\n\r\nYour reply to support request #%{ticket.number} has been noted.\r\n\r\nYou can view this support request progress online here: %{ticket.client_link}.\r\n\r\n%{signature}', 'New Message Alert', '%{recipient},\r\n\r\nNew message appended to ticket #%{ticket.number}\r\n\r\n----------------------\r\nName: %{ticket.name}\r\nEmail: %{ticket.email}\r\nDept: %{ticket.dept.name}\r\n\r\n%{message}\r\n----------------------\r\n\r\nTo view/respond to the ticket, please login to the support ticket system.\r\n\r\n%{ticket.staff_link}\r\n\r\n- Your friendly Customer Support System - powered by osTicket.', 'New Internal Note Alert', '%{recipient},\r\n\r\nInternal note appended to ticket #%{ticket.number}\r\n\r\n----------------------\r\n* %{note.title} *\r\n\r\n%{note.message}\r\n----------------------\r\n\r\nTo view/respond to the ticket, please login to the support ticket system.\r\n\r\n%{ticket.staff_link}\r\n\r\n- Your friendly Customer Support System - powered by osTicket.', 'Ticket #%{ticket.number} Assigned to you', '%{assignee},\r\n\r\nTicket #%{ticket.number} has been assigned to you by %{assigner}\r\n\r\n----------------------\r\n\r\n%{comments}\r\n\r\n----------------------\r\n\r\nTo view complete details, simply login to the support system.\r\n\r\n%{ticket.staff_link}\r\n\r\n- Your friendly Support Ticket System - powered by osTicket.', 'Ticket Transfer #%{ticket.number} - %{ticket.dept.name}', '%{recipient},\r\n\r\nTicket #%{ticket.number} has been transferred to %{ticket.dept.name} department by %{staff.name}\r\n\r\n----------------------\r\n\r\n%{comments}\r\n\r\n----------------------\r\n\r\nTo view/respond to the ticket, please login to the support ticket system.\r\n\r\n%{ticket.staff_link}\r\n\r\n- Your friendly Customer Support System - powered by osTicket.', 'Stale Ticket Alert', '%{recipient},\r\n\r\nA ticket, #%{ticket.number} assigned to you or in your department is seriously overdue.\r\n\r\n%{ticket.staff_link}\r\n\r\nWe should all work hard to guarantee that all tickets are being addressed in a timely manner.\r\n\r\n- Your friendly (although with limited patience) Support Ticket System - powered by osTicket.', 'Open Tickets Limit Reached', '%{ticket.name}\r\n\r\nYou have reached the maximum number of open tickets allowed.\r\n\r\nTo be able to open another ticket, one of your pending tickets must be closed. To update or add comments to an open ticket simply login using the link below.\r\n\r\n%{url}/tickets.php?e=%{ticket.email}\r\n\r\nThank you.\r\n\r\nSupport Ticket System', '[#%{ticket.number}] %{ticket.subject}', '%{ticket.name},\r\n\r\nA customer support staff member has replied to your support request, #%{ticket.number} with the following response:\r\n\r\n%{response}\r\n\r\nWe hope this response has sufficiently answered your questions. If not, please do not send another email. Instead, reply to this email or login to your account for a complete archive of all your support requests and responses.\r\n\r\n%{ticket.client_link}\r\n\r\n%{signature}', NOW(), NOW()); +INSERT INTO `%TABLE_PREFIX%email_template` (`code_name`, `subject`, `body`) + VALUES ( + 'ticket.autoresp', 'Support Ticket Opened [#%{ticket.number}]', '%{ticket.name}, \r\n\r\nA request for support has been created and assigned ticket #%{ticket.number}. A representative will follow-up with you as soon as possible.\r\n\r\nYou can view this ticket''s progress online here: %{ticket.client_link}.\r\n\r\nIf you wish to send additional comments or information regarding this issue, please don''t open a new ticket. Simply login using the link above and update the ticket.\r\n\r\n%{signature}' + ), ( + 'ticket.autoreply', 'Support Ticket Opened [#%{ticket.number}]', '%{ticket.name}, \r\n\r\nA request for support has been created and assigned ticket #%{ticket.number} with the following auto-reply:\r\n\r\n%{response}\r\n\r\n\r\nWe hope this response has sufficiently answered your questions. If not, please do not open another ticket. If need be, representative will follow-up with you as soon as possible.\r\n\r\nYou can view this ticket''s progress online here: %{ticket.client_link}.' + ), ( + 'ticket.notice', '[#%{ticket.number}] %{ticket.subject}', '%{ticket.name}, \r\n\r\nOur customer care team has created a ticket, #%{ticket.number} on your behalf, with the following message.\r\n\r\n%{message}\r\n\r\nIf you wish to provide additional comments or information regarding this issue, please don''t open a new ticket. You can update or view this ticket''s progress online here: %{ticket.client_link}.\r\n\r\n%{signature}' + ), ( + 'ticket.alert', 'New Ticket Alert', '%{recipient}, \r\n\r\nNew ticket #%{ticket.number} created.\r\n\r\n-----------------------\r\nName: %{ticket.name}\r\nEmail: %{ticket.email}\r\nDept: %{ticket.dept.name}\r\n\r\n%{message}\r\n-----------------------\r\n\r\nTo view/respond to the ticket, please login to the support ticket system.\r\n\r\n%{ticket.staff_link}\r\n\r\n- Your friendly Customer Support System - powered by osTicket.' + ), ( + 'message.autoresp', '[#%{ticket.number}] Message Added', '%{ticket.name}, \r\n\r\nYour reply to support request #%{ticket.number} has been noted.\r\n\r\nYou can view this support request progress online here: %{ticket.client_link}.\r\n\r\n%{signature}' + ), ( + 'message.alert', 'New Message Alert', '%{recipient}, \r\n\r\nNew message appended to ticket #%{ticket.number}\r\n\r\n----------------------\r\nName: %{ticket.name}\r\nEmail: %{ticket.email}\r\nDept: %{ticket.dept.name}\r\n\r\n%{message}\r\n----------------------\r\n\r\nTo view/respond to the ticket, please login to the support ticket system.\r\n\r\n%{ticket.staff_link}\r\n\r\n- Your friendly Customer Support System - powered by osTicket.' + ), ( + 'note.alert', 'New Internal Note Alert', '%{recipient}, \r\n\r\nInternal note appended to ticket #%{ticket.number}\r\n\r\n----------------------\r\n* %{note.title} *\r\n\r\n%{note.message}\r\n----------------------\r\n\r\nTo view/respond to the ticket, please login to the support ticket system.\r\n\r\n%{ticket.staff_link}\r\n\r\n- Your friendly Customer Support System - powered by osTicket.' + ), ( + 'assigned.alert', 'Ticket #%{ticket.number} Assigned to you', '%{assignee}, \r\n\r\nTicket #%{ticket.number} has been assigned to you by %{assigner}\r\n\r\n----------------------\r\n\r\n%{comments}\r\n\r\n----------------------\r\n\r\nTo view complete details, simply login to the support system.\r\n\r\n%{ticket.staff_link}\r\n\r\n- Your friendly Support Ticket System - powered by osTicket.' + ), ( + 'transfer.alert', 'Ticket Transfer #%{ticket.number} - %{ticket.dept.name}', '%{recipient}, \r\n\r\nTicket #%{ticket.number} has been transferred to %{ticket.dept.name} department by %{staff.name}\r\n\r\n----------------------\r\n\r\n%{comments}\r\n\r\n----------------------\r\n\r\nTo view/respond to the ticket, please login to the support ticket system.\r\n\r\n%{ticket.staff_link}\r\n\r\n- Your friendly Customer Support System - powered by osTicket.' + ), ( + 'ticket.overdue', 'Stale Ticket Alert', '%{recipient}, \r\n\r\nA ticket, #%{ticket.number} assigned to you or in your department is seriously overdue.\r\n\r\n%{ticket.staff_link}\r\n\r\nWe should all work hard to guarantee that all tickets are being addressed in a timely manner.\r\n\r\n- Your friendly (although with limited patience) Support Ticket System - powered by osTicket.' + ), ( + 'ticket.overlimit', 'Open Tickets Limit Reached', '%{ticket.name}\r\n\r\nYou have reached the maximum number of open tickets allowed.\r\n\r\nTo be able to open another ticket, one of your pending tickets must be closed. To update or add comments to an open ticket simply login using the link below.\r\n\r\n%{url}/tickets.php?e=%{ticket.email}\r\n\r\nThank you.\r\n\r\nSupport Ticket System' + ), ( + 'ticket.reply', '[#%{ticket.number}] %{ticket.subject}', '%{ticket.name}, \r\n\r\nA customer support staff member has replied to your support request, #%{ticket.number} with the following response:\r\n\r\n%{response}\r\n\r\nWe hope this response has sufficiently answered your questions. If not, please do not send another email. Instead, reply to this email or login to your account for a complete archive of all your support requests and responses.\r\n\r\n%{ticket.client_link}\r\n\r\n%{signature}' + ); +UPDATE `%TABLE_PREFIX%email_template` SET `created`=NOW(), `updated`=NOW(), + `tpl_id` = (SELECT `tpl_id` FROM `%TABLE_PREFIX%email_template_group`); DROP TABLE IF EXISTS `%TABLE_PREFIX%file`; CREATE TABLE `%TABLE_PREFIX%file` ( `id` int(11) NOT NULL auto_increment, + `ft` CHAR( 1 ) NOT NULL DEFAULT 'T', `type` varchar(255) NOT NULL default '', `size` varchar(25) NOT NULL default '', `hash` varchar(125) NOT NULL, `name` varchar(255) NOT NULL default '', `created` datetime NOT NULL, PRIMARY KEY (`id`), + KEY `ft` (`ft`), KEY `hash` (`hash`) ) DEFAULT CHARSET=utf8; + INSERT INTO `%TABLE_PREFIX%file` (`type`, `size`, `hash`, `name`, `created`) VALUES ('text/plain', '25', '670c6cc1d1dfc97fad20e5470251b255', 'osTicket.txt', NOW()); @@ -420,6 +440,7 @@ CREATE TABLE `%TABLE_PREFIX%help_topic` ( `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', + `page_id` int(10) unsigned NOT NULL default '0', `topic` varchar(32) NOT NULL default '', `notes` text, `created` datetime NOT NULL, @@ -430,7 +451,8 @@ CREATE TABLE `%TABLE_PREFIX%help_topic` ( KEY `priority_id` (`priority_id`), KEY `dept_id` (`dept_id`), KEY `staff_id` (`staff_id`,`team_id`), - KEY `sla_id` (`sla_id`) + KEY `sla_id` (`sla_id`), + KEY `page_id` (`page_id`) ) DEFAULT CHARSET=utf8; INSERT INTO `%TABLE_PREFIX%help_topic` (`isactive`, `ispublic`, `noautoresp`, `dept_id`, `sla_id`, `topic`, `notes`) VALUES @@ -731,3 +753,28 @@ INSERT INTO `%TABLE_PREFIX%timezone` (`offset`, `timezone`) VALUES (10.0, 'Eastern Australia, Guam, Vladivostok'), (11.0, 'Magadan, Solomon Islands, New Caledonia'), (12.0, 'Auckland, Wellington, Fiji, Kamchatka'); + +-- pages +CREATE TABLE IF NOT EXISTS `%TABLE_PREFIX%page` ( + `id` int(10) unsigned NOT NULL auto_increment, + `isactive` tinyint(1) unsigned NOT NULL default '0', + `type` enum('landing','offline','thank-you','other') NOT NULL default 'other', + `name` varchar(255) NOT NULL, + `body` text NOT NULL, + `notes` text, + `created` datetime NOT NULL, + `updated` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `name` (`name`) +) DEFAULT CHARSET=utf8; + + +INSERT INTO `%TABLE_PREFIX%page` (`id`, `isactive`, `type`, `name`, `body`, `notes`, `created`, `updated`) VALUES +('', 1, 'offline', 'Offline', '<div>\r\n<h1><span style="font-size: medium">Support Ticket System Offline</span></h1>\r\n<p>Thank you for your interest in contacting us.</p>\r\n<p>Our helpdesk is offline at the moment, please check back at a later time.</p>\r\n</div>', 'Default offline page', NOW(), NOW()), +('', 1, 'thank-you', 'Thank you', '<div>%{ticket.name},<br />\r\n \r\n<p>\r\nThank you for contacting us.</p><p> A support ticket request #%{ticket.number} has been created and a representative will be getting back to you shortly if necessary.</p>\r\n \r\n<p>Support Team </p>\r\n</div>', 'Default "thank you" page displayed after the end-user creates a web ticket.', NOW(), NOW()), +('', 1, 'landing', 'Landing', '<h1>Welcome to the Support Center</h1>\r\n<p>In order to streamline support requests and better serve you, we utilize a support ticket system. Every support request is assigned a unique ticket number which you can use to track the progress and responses online. For your reference we provide complete archives and history of all your support requests. A valid email address is required to submit a ticket.\r\n</p>\r\n', 'Introduction text on the landing page.', NOW(), NOW()); + +INSERT INTO `%TABLE_PREFIX%config` (`key`, `value`, `namespace`) VALUES + ('landing_page_id', (SELECT `id` FROM `%TABLE_PREFIX%page` WHERE `type` = 'landing'), 'core'), + ('offline_page_id', (SELECT `id` FROM `%TABLE_PREFIX%page` WHERE `type` = 'offline'), 'core'), + ('thank-you_page_id', (SELECT `id` FROM `%TABLE_PREFIX%page` WHERE `type` = 'thank-you'), 'core'); diff --git a/setup/inc/sql/osTicket-mysql.sql.md5 b/setup/inc/sql/osTicket-mysql.sql.md5 index d55c64b4a73863e0de3bb0b52805535251c07dfe..12c25dcccc83eb603a0367e9d41b434cfadd5617 100644 --- a/setup/inc/sql/osTicket-mysql.sql.md5 +++ b/setup/inc/sql/osTicket-mysql.sql.md5 @@ -1 +1 @@ -852ca89e1440e736d763b3b87f039bd7 +740428f9986da6ad85f88ec841b57bfe