function getForm() { if (!isset($this->form)) { // Look for the entry first if ($this->form = DynamicFormEntry::lookup(array('object_type' => 'C'))) { return $this->form; } elseif (!($this->form = DynamicForm::lookup(array('type' => 'C')))) { $this->__loadDefaultForm(); return $this->getForm(); } // Create an entry to be saved later $this->form = $this->form->instanciate(); $this->form->object_type = 'C'; } return $this->form; }
?> :</th> <td><?php echo Format::db_datetime($ticket->getLastRespDate()); ?> </td> </tr> </table> </td> </tr> </table> <br> <table class="ticket_info" cellspacing="0" cellpadding="0" width="940" border="0"> <?php $idx = 0; foreach (DynamicFormEntry::forTicket($ticket->getId()) as $form) { // Skip core fields shown earlier in the ticket view // TODO: Rewrite getAnswers() so that one could write // ->getAnswers()->filter(not(array('field__name__in'=> // array('email', ...)))); $answers = array_filter($form->getAnswers(), function ($a) { return !in_array($a->getField()->get('name'), array('email', 'subject', 'name', 'priority')); }); if (count($answers) == 0) { continue; } ?> <tr> <td colspan="2"> <table cellspacing="0" cellpadding="4" width="100%" border="0"> <?php
function forOrganization($org_id) { return DynamicFormEntry::objects()->filter(array('object_id' => $org_id, 'object_type' => 'O')); }
$nav->addSubMenu(array('desc' => __('Closed') . ' (' . number_format($stats['closed']) . ')', 'title' => __('Closed Tickets'), 'href' => 'tickets.php?status=closed', 'iconclass' => 'closedTickets'), $_REQUEST['status'] == 'closed'); } if ($thisstaff->canCreateTickets()) { $nav->addSubMenu(array('desc' => __('New Ticket'), 'title' => __('Open a New Ticket'), 'href' => 'tickets.php?a=open', 'iconclass' => 'newTicket', 'id' => 'new-ticket'), $_REQUEST['a'] == 'open'); } $ost->addExtraHeader('<script type="text/javascript" src="js/ticket.js"></script>'); $ost->addExtraHeader('<meta name="tip-namespace" content="tickets.queue" />', "\$('#content').data('tipNamespace', 'tickets.queue');"); $inc = 'tickets.inc.php'; if ($ticket) { $ost->setPageTitle(sprintf(__('Ticket #%s'), $ticket->getNumber())); $nav->setActiveSubMenu(-1); $inc = 'ticket-view.inc.php'; if ($_REQUEST['a'] == 'edit' && $thisstaff->canEditTickets()) { $inc = 'ticket-edit.inc.php'; if (!$forms) { $forms = DynamicFormEntry::forTicket($ticket->getId()); } // Auto add new fields to the entries foreach ($forms as $f) { $f->addMissingFields(); } } elseif ($_REQUEST['a'] == 'print' && !$ticket->pdfExport($_REQUEST['psize'], $_REQUEST['notes'])) { $errors['err'] = __('Internal error: Unable to export the ticket to PDF for print.'); } } else { $inc = 'tickets.inc.php'; if ($_REQUEST['a'] == 'open' && $thisstaff->canCreateTickets()) { $inc = 'ticket-open.inc.php'; } elseif ($_REQUEST['a'] == 'export') { $ts = strftime('%Y%m%d'); if (!($token = $_REQUEST['h'])) {
function updateForms($user_id) { global $thisstaff; if (!$thisstaff) { Http::response(403, "Login required"); } elseif (!($user = User::lookup($user_id))) { Http::response(404, "No such customer"); } elseif (!isset($_POST['forms'])) { Http::response(422, "Send updated forms list"); } // Add new forms $forms = DynamicFormEntry::forUser($user_id); foreach ($_POST['forms'] as $sort => $id) { $found = false; foreach ($forms as $e) { if ($e->get('form_id') == $id) { $e->set('sort', $sort); $e->save(); $found = true; break; } } // New form added if (!$found && ($new = DynamicForm::lookup($id))) { $user->addForm($new, $sort); } } // Deleted forms foreach ($forms as $idx => $e) { if (!in_array($e->get('form_id'), $_POST['forms'])) { $e->delete(); } } Http::response(201, 'Successfully managed'); }
function updateForms($ticket_id) { global $thisstaff; if (!$thisstaff) { Http::response(403, "Login required"); } elseif (!($ticket = Ticket::lookup($ticket_id))) { Http::response(404, "No such ticket"); } elseif (!$ticket->checkStaffAccess($thisstaff)) { Http::response(403, "Access Denied"); } elseif (!isset($_POST['forms'])) { Http::response(422, "Send updated forms list"); } // Add new forms $forms = DynamicFormEntry::forTicket($ticket_id); foreach ($_POST['forms'] as $sort => $id) { $found = false; foreach ($forms as $e) { if ($e->get('form_id') == $id) { $e->set('sort', $sort); $e->save(); $found = true; break; } } // New form added if (!$found && ($new = DynamicForm::lookup($id))) { $f = $new->instanciate(); $f->set('sort', $sort); $f->setTicketId($ticket_id); $f->save(); } } // Deleted forms foreach ($forms as $idx => $e) { if (!in_array($e->get('form_id'), $_POST['forms'])) { $e->delete(); } } Http::response(201, 'Successfully managed'); }
function update($vars, &$errors) { global $cfg, $thisstaff; if (!$cfg || !$thisstaff || !$thisstaff->canEditTickets()) { return false; } $fields = array(); $fields['topicId'] = array('type' => 'int', 'required' => 1, 'error' => __('Help topic selection is required')); $fields['slaId'] = array('type' => 'int', 'required' => 0, 'error' => __('Select a valid SLA')); $fields['duedate'] = array('type' => 'date', 'required' => 0, 'error' => __('Invalid date format - must be MM/DD/YY')); $fields['note'] = array('type' => 'text', 'required' => 1, 'error' => __('A reason for the update is required')); $fields['user_id'] = array('type' => 'int', 'required' => 0, 'error' => __('Invalid user-id')); if (!Validator::process($fields, $vars, $errors) && !$errors['err']) { $errors['err'] = __('Missing or invalid data - check the errors and try again'); } if ($vars['duedate']) { if ($this->isClosed()) { $errors['duedate'] = __('Due date can NOT be set on a closed ticket'); } elseif (!$vars['time'] || strpos($vars['time'], ':') === false) { $errors['time'] = __('Select a time from the list'); } elseif (strtotime($vars['duedate'] . ' ' . $vars['time']) === false) { $errors['duedate'] = __('Invalid due date'); } elseif (strtotime($vars['duedate'] . ' ' . $vars['time']) <= time()) { $errors['duedate'] = __('Due date must be in the future'); } } // Validate dynamic meta-data $forms = DynamicFormEntry::forTicket($this->getId()); foreach ($forms as $form) { // Don't validate deleted forms if (!in_array($form->getId(), $vars['forms'])) { continue; } $form->setSource($_POST); if (!$form->isValid()) { $errors = array_merge($errors, $form->errors()); } } if ($errors) { return false; } $sql = 'UPDATE ' . TICKET_TABLE . ' SET updated=NOW() ' . ' ,topic_id=' . db_input($vars['topicId']) . ' ,sla_id=' . db_input($vars['slaId']) . ' ,source=' . db_input($vars['source']) . ' ,duedate=' . ($vars['duedate'] ? db_input(date('Y-m-d G:i', Misc::dbtime($vars['duedate'] . ' ' . $vars['time']))) : 'NULL'); if ($vars['user_id']) { $sql .= ', user_id=' . db_input($vars['user_id']); } if ($vars['duedate']) { //We are setting new duedate... $sql .= ' ,isoverdue=0'; } $sql .= ' WHERE ticket_id=' . db_input($this->getId()); if (!db_query($sql) || !db_affected_rows()) { return false; } if (!$vars['note']) { $vars['note'] = sprintf(_S('Ticket details updated by %s'), $thisstaff->getName()); } $this->logNote(_S('Ticket Updated'), $vars['note'], $thisstaff); // Decide if we need to keep the just selected SLA $keepSLA = $this->getSLAId() != $vars['slaId']; // Update dynamic meta-data foreach ($forms as $f) { // Drop deleted forms $idx = array_search($f->getId(), $vars['forms']); if ($idx === false) { $f->delete(); } else { $f->set('sort', $idx); $f->save(); } } // Reload the ticket so we can do further checking $this->reload(); // Reselect SLA if transient if (!$keepSLA && (!$this->getSLA() || $this->getSLA()->isTransient())) { $this->selectSLAId(); } // Clear overdue flag if duedate or SLA changes and the ticket is no longer overdue. if ($this->isOverdue() && (!$this->getEstDueDate() || Misc::db2gmtime($this->getEstDueDate()) > Misc::gmtime())) { $this->clearOverdue(); } Signal::send('model.updated', $this); return true; }
function getDynamicData() { if (!isset($this->_entries)) { $this->_entries = DynamicFormEntry::forOrganization($this->id)->all(); if (!$this->_entries) { $g = OrganizationForm::getInstance($this->id, true); $g->save(); $this->_entries[] = $g; } } return $this->_entries; }
function delete() { //delete just orphaned ticket thread & associated attachments. // Fetch thread prior to removing ticket entry $t = $this->getThread(); $sql = 'DELETE FROM ' . TICKET_TABLE . ' WHERE ticket_id=' . $this->getId() . ' LIMIT 1'; if (!db_query($sql) || !db_affected_rows()) { return false; } $t->delete(); foreach (DynamicFormEntry::forTicket($this->getId()) as $form) { $form->delete(); } $this->deleteDrafts(); return true; }
function getDynamicData($create = true) { if (!isset($this->_entries)) { $this->_entries = DynamicFormEntry::forClient($this->id)->all(); if (!$this->_entries && $create) { $g = UserForm::getNewInstance(); $g->setClientId($this->id); $g->save(); $this->_entries[] = $g; } } return $this->_entries ?: array(); }
function _print() { if (!($ticket = $this->getTicket())) { return; } $w = $this->w / 2 - $this->lMargin; $l = 35; $c = $w - $l; // Setup HTML writing and load default thread stylesheet $this->WriteHtml('<style>' . file_get_contents(ROOT_DIR . 'css/thread.css') . '</style>', 1, true, false); $this->SetFont('Arial', 'B', 11); $this->cMargin = 0; $this->SetFont('Arial', 'B', 11); $this->SetTextColor(10, 86, 142); $this->WriteCell($w, 7, sprintf(__('Ticket #%s'), $ticket->getNumber()), 0, 0, 'L'); $this->Ln(7); $this->cMargin = 3; $this->SetTextColor(0); $this->SetDrawColor(220, 220, 220); $this->SetFillColor(244, 250, 255); $this->SetX($this->lMargin); $this->SetFont('Arial', 'B', 11); $this->WriteCell($l, 7, __('Status'), 1, 0, 'L', true); $this->SetFont(''); $this->WriteCell($c, 7, (string) $ticket->getStatus(), 1, 0, 'L', true); $this->SetFont('Arial', 'B', 11); $this->WriteCell($l, 7, __('Name'), 1, 0, 'L', true); $this->SetFont(''); $this->WriteCell($c, 7, (string) $ticket->getName(), 1, 1, 'L', true); $this->SetFont('Arial', 'B', 11); $this->WriteCell($l, 7, __('Priority'), 1, 0, 'L', true); $this->SetFont(''); $this->WriteCell($c, 7, $ticket->getPriority(), 1, 0, 'L', true); $this->SetFont('Arial', 'B', 11); $this->WriteCell($l, 7, __('Email'), 1, 0, 'L', true); $this->SetFont(''); $this->WriteCell($c, 7, $ticket->getEmail(), 1, 1, 'L', true); $this->SetFont('Arial', 'B', 11); $this->WriteCell($l, 7, __('Department'), 1, 0, 'L', true); $this->SetFont(''); $this->WriteCell($c, 7, $ticket->getDeptName(), 1, 0, 'L', true); $this->SetFont('Arial', 'B', 11); $this->WriteCell($l, 7, __('Phone'), 1, 0, 'L', true); $this->SetFont(''); $this->WriteCell($c, 7, $ticket->getPhoneNumber(), 1, 1, 'L', true); $this->SetFont('Arial', 'B', 11); $this->WriteCell($l, 7, __('Create Date'), 1, 0, 'L', true); $this->SetFont(''); $this->WriteCell($c, 7, Format::db_datetime($ticket->getCreateDate()), 1, 0, 'L', true); $this->SetFont('Arial', 'B', 11); $this->WriteCell($l, 7, __('Source'), 1, 0, 'L', true); $this->SetFont(''); $source = ucfirst($ticket->getSource()); if ($ticket->getIP()) { $source .= ' (' . $ticket->getIP() . ')'; } $this->WriteCell($c, 7, $source, 1, 0, 'L', true); $this->Ln(12); $this->SetFont('Arial', 'B', 11); if ($ticket->isOpen()) { $this->WriteCell($l, 7, __('Assigned To'), 1, 0, 'L', true); $this->SetFont(''); $this->WriteCell($c, 7, $ticket->isAssigned() ? $ticket->getAssigned() : ' -- ', 1, 0, 'L', true); } else { $closedby = __('unknown'); if ($staff = $ticket->getStaff()) { $closedby = (string) $staff->getName(); } $this->WriteCell($l, 7, __('Closed By'), 1, 0, 'L', true); $this->SetFont(''); $this->WriteCell($c, 7, $closedby, 1, 0, 'L', true); } $this->SetFont('Arial', 'B', 11); $this->WriteCell($l, 7, __('Help Topic'), 1, 0, 'L', true); $this->SetFont(''); $this->WriteCell($c, 7, $ticket->getHelpTopic(), 1, 1, 'L', true); $this->SetFont('Arial', 'B', 11); $this->WriteCell($l, 7, __('SLA Plan'), 1, 0, 'L', true); $this->SetFont(''); $sla = $ticket->getSLA(); $this->WriteCell($c, 7, $sla ? $sla->getName() : ' -- ', 1, 0, 'L', true); $this->SetFont('Arial', 'B', 11); $this->WriteCell($l, 7, __('Last Response'), 1, 0, 'L', true); $this->SetFont(''); $this->WriteCell($c, 7, Format::db_datetime($ticket->getLastRespDate()), 1, 1, 'L', true); $this->SetFont('Arial', 'B', 11); if ($ticket->isOpen()) { $this->WriteCell($l, 7, __('Due Date'), 1, 0, 'L', true); $this->SetFont(''); $this->WriteCell($c, 7, Format::db_datetime($ticket->getEstDueDate()), 1, 0, 'L', true); } else { $this->WriteCell($l, 7, __('Close Date'), 1, 0, 'L', true); $this->SetFont(''); $this->WriteCell($c, 7, Format::db_datetime($ticket->getCloseDate()), 1, 0, 'L', true); } $this->SetFont('Arial', 'B', 11); $this->WriteCell($l, 7, __('Last Message'), 1, 0, 'L', true); $this->SetFont(''); $this->WriteCell($c, 7, Format::db_datetime($ticket->getLastMsgDate()), 1, 1, 'L', true); $this->SetFillColor(255, 255, 255); foreach (DynamicFormEntry::forTicket($ticket->getId()) as $form) { $idx = 0; foreach ($form->getAnswers() as $a) { if (in_array($a->getField()->get('name'), array('email', 'name', 'subject', 'phone', 'priority'))) { continue; } $this->SetFont('Arial', 'B', 11); if ($idx++ === 0) { $this->Ln(5); $this->SetFillColor(244, 250, 255); $this->WriteCell(($l + $c) * 2, 7, $a->getForm()->get('title'), 1, 0, 'L', true); $this->SetFillColor(255, 255, 255); } if ($val = $a->toString()) { $this->Ln(7); $this->WriteCell($l * 2, 7, $a->getField()->get('label'), 1, 0, 'L', true); $this->SetFont(''); $this->WriteCell($c * 2, 7, $val, 1, 0, 'L', true); } } } $this->SetFillColor(244, 250, 255); $this->Ln(10); $this->SetFont('Arial', 'B', 11); $this->cMargin = 0; $this->SetTextColor(10, 86, 142); $this->WriteCell($w, 7, trim($ticket->getSubject()), 0, 0, 'L'); $this->Ln(7); $this->SetTextColor(0); $this->cMargin = 3; //Table header colors (RGB) $colors = array('M' => array(195, 217, 255), 'R' => array(255, 224, 179), 'N' => array(250, 250, 210)); //Get ticket thread $types = array('M', 'R'); if ($this->includenotes) { $types[] = 'N'; } if ($entries = $ticket->getThreadEntries($types)) { foreach ($entries as $entry) { $color = $colors[$entry['thread_type']]; $this->SetFillColor($color[0], $color[1], $color[2]); $this->SetFont('Arial', 'B', 11); $this->WriteCell($w / 2, 7, Format::db_datetime($entry['created']), 'LTB', 0, 'L', true); $this->SetFont('Arial', '', 10); $this->WriteCell($w, 7, Format::truncate($entry['title'], 50), 'TB', 0, 'L', true); $this->WriteCell($w / 2, 7, $entry['name'] ?: $entry['poster'], 'TBR', 1, 'L', true); $this->SetFont(''); $text = $entry['body']->display('pdf'); if ($entry['attachments'] && ($tentry = $ticket->getThreadEntry($entry['id'])) && ($attachments = $tentry->getAttachments())) { $files = array(); foreach ($attachments as $attachment) { if (!$attachment['inline']) { $files[] = $attachment['name']; } } if ($files) { $text .= "<div>Files Attached: [" . implode(', ', $files) . "]</div>"; } $text .= "<div>" . sprintf(__('Files Attached: [%s]'), implode(', ', $files)) . "</div>"; } $this->WriteHtml('<div class="thread-body">' . $text . '</div>', 2, false, false); $this->Ln(5); } } $this->WriteHtml('', 2, false, true); }
public static function getDynamicData($id) { return \DynamicFormEntry::objects()->filter(array('object_id' => $id, 'object_type' => 'E')); }