Example #1
0
 function getRequestStructure($format, $data = null)
 {
     $supported = array("alert", "autorespond", "source", "topicId", "attachments" => array("*" => array("name", "type", "data", "encoding", "size")), "message", "ip", "priorityId");
     # Fetch dynamic form field names for the given help topic and add
     # the names to the supported request structure
     if (isset($data['topicId']) && ($topic = Topic::lookup($data['topicId'])) && ($form = $topic->getForm())) {
         foreach ($form->getDynamicFields() as $field) {
             $supported[] = $field->get('name');
         }
     }
     # Ticket form fields
     # TODO: Support userId for existing user
     if ($form = TicketForm::getInstance()) {
         foreach ($form->getFields() as $field) {
             $supported[] = $field->get('name');
         }
     }
     # User form fields
     if ($form = UserForm::getInstance()) {
         foreach ($form->getFields() as $field) {
             $supported[] = $field->get('name');
         }
     }
     if (!strcasecmp($format, 'email')) {
         $supported = array_merge($supported, array('header', 'mid', 'emailId', 'to-email-id', 'ticketId', 'reply-to', 'reply-to-name', 'in-reply-to', 'references', 'thread-type', 'flags' => array('bounce', 'auto-reply', 'spam', 'viral'), 'recipients' => array('*' => array('name', 'email', 'source'))));
         $supported['attachments']['*'][] = 'cid';
     }
     return $supported;
 }
Example #2
0
 static function dumpTickets($sql, $how = 'csv')
 {
     // Add custom fields to the $sql statement
     $cdata = $fields = $select = array();
     foreach (TicketForm::getInstance()->getFields() as $f) {
         // Ignore core fields
         if (in_array($f->get('name'), array('subject', 'priority'))) {
             continue;
         } elseif (!$f->hasData() || $f->isPresentationOnly()) {
             continue;
         }
         $name = $f->get('name') ? $f->get('name') : 'field_' . $f->get('id');
         $key = '__field_' . $f->get('id');
         // Fetch ID values for ID-based data
         if ($f->hasIdValue()) {
             $name .= '_id';
         }
         $cdata[$key] = $f->get('label');
         $fields[$key] = $f;
         $select[] = "cdata.`{$name}` AS __field_" . $f->get('id');
     }
     if ($select) {
         $sql = str_replace(' FROM ', ',' . implode(',', $select) . ' FROM ', $sql);
     }
     return self::dumpQuery($sql, array('number' => 'Ticket Number', 'created' => 'Date', 'subject' => 'Subject', 'name' => 'From', 'email' => 'From Email', 'priority_desc' => 'Priority', 'dept_name' => 'Department', 'helptopic' => 'Help Topic', 'source' => 'Source', 'status' => 'Current Status', 'effective_date' => 'Last Updated', 'duedate' => 'Due Date', 'isoverdue' => 'Overdue', 'isanswered' => 'Answered', 'assigned' => 'Assigned To', 'staff' => 'Staff Assigned', 'team' => 'Team Assigned', 'thread_count' => 'Thread Count', 'attachments' => 'Attachment Count') + $cdata, $how, array('modify' => function (&$record, $keys) use($fields) {
         foreach ($fields as $k => $f) {
             if (($i = array_search($k, $keys)) !== false) {
                 $record[$i] = $f->export($f->to_php($record[$i]));
             }
         }
         return $record;
     }));
 }
Example #3
0
 function validate(&$data, $format, $strict = true)
 {
     global $ost;
     //Call parent to Validate the structure
     if (!parent::validate($data, $format, $strict) && $strict) {
         $this->exerr(400, __('Unexpected or invalid data received'));
     }
     // Use the settings on the thread entry on the ticket details
     // form to validate the attachments in the email
     $tform = TicketForm::objects()->one()->getForm();
     $messageField = $tform->getField('message');
     $fileField = $messageField->getWidget()->getAttachments();
     // Nuke attachments IF API files are not allowed.
     if (!$messageField->isAttachmentsEnabled()) {
         $data['attachments'] = array();
     }
     //Validate attachments: Do error checking... soft fail - set the error and pass on the request.
     if ($data['attachments'] && is_array($data['attachments'])) {
         foreach ($data['attachments'] as &$file) {
             if ($file['encoding'] && !strcasecmp($file['encoding'], 'base64')) {
                 if (!($file['data'] = base64_decode($file['data'], true))) {
                     $file['error'] = sprintf(__('%s: Poorly encoded base64 data'), Format::htmlchars($file['name']));
                 }
             }
             // Validate and save immediately
             try {
                 $file['id'] = $fileField->uploadAttachment($file);
             } catch (FileUploadError $ex) {
                 $file['error'] = $file['name'] . ': ' . $ex->getMessage();
             }
         }
         unset($file);
     }
     return true;
 }
             }
             ?>
         </select>&nbsp;<span class='error'>&nbsp;<?php echo $errors['assignId']; ?></span>
     </td>
 </tr>
 <?php } ?>
 </tbody>
 <tbody id="dynamic-form">
 <?php
     if ($form) {
         include(STAFFINC_DIR .  'templates/dynamic-form.tmpl.php');
     }
 ?>
 </tbody>
 <tbody> <?php
 $tform = TicketForm::getInstance()->getForm($_POST);
 if ($_POST) $tform->isValid();
 $tform->render(true);
 ?>
 </tbody>
 <tbody>
 <?php
 //is the user allowed to post replies??
 if($thisstaff->canPostReply()) { ?>
 <tr>
     <th colspan="2">
         <em><strong>Response</strong>: Optional response to the above issue.</em>
     </th>
 </tr>
 <tr>
     <td colspan=2>
        $name = $f->get('name') ? $f->get('name') : 'field_' . $f->get('id');
        $ids = $f->hasIdValue();
        $fields = sprintf('`%s`=', $name) . db_input($answer->get('value'));
        if ($f->hasIdValue()) {
            $fields .= sprintf(',`%s_id`=', $name) . db_input($answer->getIdValue());
        }
        $sql = 'INSERT INTO `' . TABLE_PREFIX . 'ticket__cdata` SET ' . $fields . ', `ticket_id`=' . db_input($answer->getEntry()->get('object_id')) . ' ON DUPLICATE KEY UPDATE ' . $fields;
        if (!db_query($sql) || !db_affected_rows()) {
            return self::dropDynamicDataView();
        }
    }
}
// Add fields from the standard ticket form to the ticket filterable fields
Filter::addSupportedMatches('Ticket Data', function () {
    $matches = array();
    foreach (TicketForm::getInstance()->getFields() as $f) {
        if (!$f->hasData()) {
            continue;
        }
        $matches['field.' . $f->get('id')] = 'Ticket / ' . $f->getLabel();
        if (($fi = $f->getImpl()) instanceof SelectionField) {
            foreach ($fi->getList()->getProperties() as $p) {
                $matches['field.' . $f->get('id') . '.' . $p->get('id')] = 'Ticket / ' . $f->getLabel() . ' / ' . $p->getLabel();
            }
        }
    }
    return $matches;
}, 30);
// Manage materialized view on custom data updates
Signal::connect('model.created', array('TicketForm', 'updateDynamicDataView'), 'DynamicFormEntryAnswer');
Signal::connect('model.updated', array('TicketForm', 'updateDynamicDataView'), 'DynamicFormEntryAnswer');
Example #6
0
         <?php
         if(($users=Staff::getStaffMembers())) {
             foreach($users as $id => $name)
                 echo sprintf('<option value="%d">%s</option>', $id, $name);
         }
         ?>
     </select>
 </fieldset>
 <fieldset class="date_range">
     <label><?php echo __('Date Range').' &mdash; '.__('Create Date');?>:</label>
     <input class="dp" type="input" size="20" name="startDate">
     <span class="between"><?php echo __('TO');?></span>
     <input class="dp" type="input" size="20" name="endDate">
 </fieldset>
 <?php
 $tform = TicketForm::objects()->one();
 echo $tform->getForm()->getMedia();
 foreach ($tform->getInstance()->getFields() as $f) {
     if (!$f->hasData())
         continue;
     elseif (!$f->getImpl()->hasSpecialSearch())
         continue;
     ?><fieldset class="span6">
     <label><?php echo $f->getLabel(); ?>:</label><div><?php
              $f->render('search'); ?></div>
     </fieldset>
 <?php } ?>
 <hr/>
 <div id="result-count" class="clear"></div>
 <p>
     <span class="buttons pull-right">
Example #7
0
define('SOURCE','Web'); //Ticket source.
$ticket = null;
$errors=array();
if ($_POST) {
    $vars = $_POST;
    $vars['deptId']=$vars['emailId']=0; //Just Making sure we don't accept crap...only topicId is expected.
    if ($thisclient) {
        $vars['uid']=$thisclient->getId();
    } elseif($cfg->isCaptchaEnabled()) {
        if(!$_POST['captcha'])
            $errors['captcha']=__('Enter text shown on the image');
        elseif(strcmp($_SESSION['captcha'], md5(strtoupper($_POST['captcha']))))
            $errors['captcha']=__('Invalid - try again!');
    }

    $tform = TicketForm::objects()->one()->getForm($vars);
    $messageField = $tform->getField('message');
    $attachments = $messageField->getWidget()->getAttachments();
    if (!$errors && $messageField->isAttachmentsEnabled())
        $vars['cannedattachments'] = $attachments->getClean();

    // Drop the draft.. If there are validation errors, the content
    // submitted will be displayed back to the user
    Draft::deleteForNamespace('ticket.client.'.substr(session_id(), -12));
    //Ticket::create...checks for errors..
    if(($ticket=Ticket::create($vars, $errors, SOURCE))){
        $msg=__('Support ticket request created');
        // Drop session-backed form data
        unset($_SESSION[':form-data']);
        //Logged in...simply view the newly created ticket.
        if($thisclient && $thisclient->isValid()) {
Example #8
0
 function _search($req)
 {
     global $thisstaff, $cfg;
     $result = array();
     $select = 'SELECT ticket.ticket_id';
     $from = ' FROM ' . TICKET_TABLE . ' ticket ';
     //Access control.
     $where = ' WHERE ( (ticket.staff_id=' . db_input($thisstaff->getId()) . ' AND ticket.status="open" )';
     if (($teams = $thisstaff->getTeams()) && count(array_filter($teams))) {
         $where .= ' OR (ticket.team_id IN (' . implode(',', db_input(array_filter($teams))) . ' ) AND ticket.status="open")';
     }
     if (!$thisstaff->showAssignedOnly() && ($depts = $thisstaff->getDepts())) {
         $where .= ' OR ticket.dept_id IN (' . implode(',', db_input($depts)) . ')';
     }
     $where .= ' ) ';
     //Department
     if ($req['deptId']) {
         $where .= ' AND ticket.dept_id=' . db_input($req['deptId']);
     }
     //Help topic
     if ($req['topicId']) {
         $where .= ' AND ticket.topic_id=' . db_input($req['topicId']);
     }
     //Status
     switch (strtolower($req['status'])) {
         case 'open':
             $where .= ' AND ticket.status="open" ';
             break;
         case 'answered':
             $where .= ' AND ticket.status="open" AND ticket.isanswered=1 ';
             break;
         case 'overdue':
             $where .= ' AND ticket.status="open" AND ticket.isoverdue=1 ';
             break;
         case 'closed':
             $where .= ' AND ticket.status="closed" ';
             break;
     }
     //Assignee
     if (isset($req['assignee']) && strcasecmp($req['status'], 'closed')) {
         $id = preg_replace("/[^0-9]/", "", $req['assignee']);
         $assignee = $req['assignee'];
         $where .= ' AND ( ( ticket.status="open" ';
         if ($assignee[0] == 't') {
             $where .= ' AND ticket.team_id=' . db_input($id);
         } elseif ($assignee[0] == 's') {
             $where .= ' AND ticket.staff_id=' . db_input($id);
         } elseif (is_numeric($id)) {
             $where .= ' AND ticket.staff_id=' . db_input($id);
         }
         $where .= ')';
         if ($req['staffId'] && !$req['status']) {
             //Assigned TO + Closed By
             $where .= ' OR (ticket.staff_id=' . db_input($req['staffId']) . ' AND ticket.status="closed") ';
         } elseif (isset($req['staffId'])) {
             // closed by any
             $where .= ' OR ticket.status="closed" ';
         }
         $where .= ' ) ';
     } elseif ($req['staffId']) {
         $where .= ' AND (ticket.staff_id=' . db_input($req['staffId']) . ' AND ticket.status="closed") ';
     }
     //dates
     $startTime = $req['startDate'] && strlen($req['startDate']) >= 8 ? strtotime($req['startDate']) : 0;
     $endTime = $req['endDate'] && strlen($req['endDate']) >= 8 ? strtotime($req['endDate']) : 0;
     if ($startTime && $startTime > time() or $startTime > $endTime && $endTime > 0) {
         $startTime = $endTime = 0;
     }
     if ($startTime) {
         $where .= ' AND ticket.created>=FROM_UNIXTIME(' . $startTime . ')';
     }
     if ($endTime) {
         $where .= ' AND ticket.created<=FROM_UNIXTIME(' . $endTime . ')';
     }
     //Query
     $joins = array();
     if ($req['query']) {
         $queryterm = db_real_escape($req['query'], false);
         // Setup sets of joins and queries
         $joins[] = array('from' => 'LEFT JOIN ' . TICKET_THREAD_TABLE . ' thread ON (ticket.ticket_id=thread.ticket_id )', 'where' => "thread.title LIKE '%{$queryterm}%' OR thread.body LIKE '%{$queryterm}%'");
         $joins[] = array('from' => 'LEFT JOIN ' . FORM_ENTRY_TABLE . ' tentry ON (tentry.object_id = ticket.ticket_id AND tentry.object_type="T")
                 LEFT JOIN ' . FORM_ANSWER_TABLE . ' tans ON (tans.entry_id = tentry.id AND tans.value_id IS NULL)', 'where' => "tans.value LIKE '%{$queryterm}%'");
         $joins[] = array('from' => 'LEFT JOIN ' . FORM_ENTRY_TABLE . ' uentry ON (uentry.object_id = ticket.user_id
                AND uentry.object_type="U")
                LEFT JOIN ' . FORM_ANSWER_TABLE . ' uans ON (uans.entry_id = uentry.id
                AND uans.value_id IS NULL)
                LEFT JOIN ' . USER_TABLE . ' user ON (ticket.user_id = user.id)
                LEFT JOIN ' . USER_EMAIL_TABLE . ' uemail ON (user.id = uemail.user_id)', 'where' => "uemail.address LIKE '%{$queryterm}%' OR user.name LIKE '%{$queryterm}%' OR uans.value LIKE '%{$queryterm}%'");
     }
     // Dynamic fields
     $cdata_search = false;
     foreach (TicketForm::getInstance()->getFields() as $f) {
         if (isset($req[$f->getFormName()]) && ($val = $req[$f->getFormName()])) {
             $name = $f->get('name') ? $f->get('name') : 'field_' . $f->get('id');
             if ($f->getImpl()->hasIdValue() && is_numeric($val)) {
                 $cwhere = "cdata.`{$name}_id` = " . db_input($val);
             } else {
                 $cwhere = "cdata.`{$name}` LIKE '%" . db_real_escape($val) . "%'";
             }
             $where .= ' AND (' . $cwhere . ')';
             $cdata_search = true;
         }
     }
     if ($cdata_search) {
         $from .= 'LEFT JOIN ' . TABLE_PREFIX . 'ticket__cdata ' . " cdata ON (cdata.ticket_id = ticket.ticket_id)";
     }
     $sections = array();
     foreach ($joins as $j) {
         $sections[] = "{$select} {$from} {$j['from']} {$where} AND ({$j['where']})";
     }
     if (!$joins) {
         $sections[] = "{$select} {$from} {$where}";
     }
     $sql = implode(' union ', $sections);
     if (!($res = db_query($sql))) {
         return TicketForm::dropDynamicDataView();
     }
     $tickets = array();
     while ($row = db_fetch_row($res)) {
         $tickets[] = $row[0];
     }
     return $tickets;
 }
Example #9
0
    echo $thisclient->getName();
    ?>
</td></tr>-->
        <?php 
}
?>
    </tbody>
    <tbody id="dynamic-form">
        <?php 
if ($form) {
    include CLIENTINC_DIR . 'templates/dynamic-form.tmpl.php';
}
?>
    </tbody>
    <tbody id="fm"><?php 
$tform = TicketForm::getInstance();
if ($_POST) {
    $tform->isValidForClient();
}
$tform->render(false);
?>
    </tbody>
    <tbody>
    <?php 
if ($cfg && $cfg->isCaptchaEnabled() && (!$thisclient || !$thisclient->isValid())) {
    if ($_POST && $errors && !$errors['captcha']) {
        $errors['captcha'] = __('Please re-enter the text again');
    }
    ?>
    <tr class="captchaRow">
        <td class="required"><?php 
Example #10
0
 static function open($vars, &$errors)
 {
     global $thisstaff, $cfg;
     if (!$thisstaff || !$thisstaff->canCreateTickets()) {
         return false;
     }
     if ($vars['source'] && !in_array(strtolower($vars['source']), array('email', 'phone', 'other'))) {
         $errors['source'] = sprintf(__('Invalid source given - %s'), Format::htmlchars($vars['source']));
     }
     if (!$vars['uid']) {
         //Special validation required here
         if (!$vars['email'] || !Validator::is_email($vars['email'])) {
             $errors['email'] = __('Valid email address is required');
         }
         if (!$vars['name']) {
             $errors['name'] = __('Name is required');
         }
     }
     if (!$thisstaff->canAssignTickets()) {
         unset($vars['assignId']);
     }
     $create_vars = $vars;
     $tform = TicketForm::objects()->one()->getForm($create_vars);
     $create_vars['cannedattachments'] = $tform->getField('message')->getWidget()->getAttachments()->getClean();
     if (!($ticket = Ticket::create($create_vars, $errors, 'staff', false))) {
         return false;
     }
     $vars['msgId'] = $ticket->getLastMsgId();
     // post response - if any
     $response = null;
     if ($vars['response'] && $thisstaff->canPostReply()) {
         $vars['response'] = $ticket->replaceVars($vars['response']);
         // $vars['cannedatachments'] contains the attachments placed on
         // the response form.
         $response = $ticket->postReply($vars, $errors, false);
     }
     // Not assigned...save optional note if any
     if (!$vars['assignId'] && $vars['note']) {
         if (!$cfg->isHtmlThreadEnabled()) {
             $vars['note'] = new TextThreadBody($vars['note']);
         }
         $ticket->logNote(_S('New Ticket'), $vars['note'], $thisstaff, false);
     } else {
         // Not assignment and no internal note - log activity
         $ticket->logActivity(_S('New Ticket by Agent'), sprintf(_S('Ticket created by agent - %s'), $thisstaff->getName()));
     }
     $ticket->reload();
     if (!$cfg->notifyONNewStaffTicket() || !isset($vars['alertuser']) || !($dept = $ticket->getDept())) {
         return $ticket;
     }
     //No alerts.
     //Send Notice to user --- if requested AND enabled!!
     if (($tpl = $dept->getTemplate()) && ($msg = $tpl->getNewTicketNoticeMsgTemplate()) && ($email = $dept->getEmail())) {
         $message = (string) $ticket->getLastMessage();
         if ($response) {
             $message .= $cfg->isHtmlThreadEnabled() ? "<br><br>" : "\n\n";
             $message .= $response->getBody();
         }
         if ($vars['signature'] == 'mine') {
             $signature = $thisstaff->getSignature();
         } elseif ($vars['signature'] == 'dept' && $dept && $dept->isPublic()) {
             $signature = $dept->getSignature();
         } else {
             $signature = '';
         }
         $attachments = $cfg->emailAttachments() && $response ? $response->getAttachments() : array();
         $msg = $ticket->replaceVars($msg->asArray(), array('message' => $message, 'signature' => $signature, 'response' => $response ? $response->getBody() : '', 'recipient' => $ticket->getOwner(), 'staff' => $thisstaff));
         $references = $ticket->getLastMessage()->getEmailMessageId();
         if (isset($response)) {
             $references = array($response->getEmailMessageId(), $references);
         }
         $options = array('references' => $references, 'thread' => $ticket->getLastMessage());
         $email->send($ticket->getOwner(), $msg['subj'], $msg['body'], $attachments, $options);
     }
     return $ticket;
 }
Example #11
0
 static function create($vars, &$errors, $origin, $autorespond = true, $alertstaff = true)
 {
     global $ost, $cfg, $thisclient, $_FILES;
     // Don't enforce form validation for email
     $field_filter = function ($type) use($origin) {
         return function ($f) use($origin, $type) {
             // Ultimately, only offer validation errors for web for
             // non-internal fields. For email, no validation can be
             // performed. For other origins, validate as usual
             switch (strtolower($origin)) {
                 case 'email':
                     return false;
                 case 'staff':
                     // Required 'Contact Information' fields aren't required
                     // when staff open tickets
                     return $type != 'user' || in_array($f->get('name'), array('name', 'email'));
                 case 'web':
                     return !$f->get('private');
                 default:
                     return true;
             }
         };
     };
     $reject_ticket = function ($message) use(&$errors) {
         global $ost;
         $errors = array('errno' => 403, 'err' => 'This help desk is for use by authorized users only');
         $ost->logWarning('Ticket Denied', $message, false);
         return 0;
     };
     // Create and verify the dynamic form entry for the new ticket
     $form = TicketForm::getNewInstance();
     // If submitting via email, ensure we have a subject and such
     foreach ($form->getFields() as $field) {
         $fname = $field->get('name');
         if ($fname && isset($vars[$fname]) && !$field->value) {
             $field->value = $field->parse($vars[$fname]);
         }
     }
     if (!$form->isValid($field_filter('ticket'))) {
         $errors += $form->errors();
     }
     // Unpack dynamic variables into $vars for filter application
     $vars += $form->getFilterData();
     // Unpack the basic user information
     if ($vars['uid'] && ($user = User::lookup($vars['uid']))) {
         $vars['email'] = $user->getEmail();
         $vars['name'] = $user->getName();
         // Add in user and organization data for filtering
         $vars += $user->getFilterData();
         if ($org = $user->getOrganization()) {
             $vars += $org->getFilterData();
         }
     } else {
         $interesting = array('name', 'email');
         $user_form = UserForm::getUserForm()->getForm($vars);
         // Add all the user-entered info for filtering
         foreach ($user_form->getFields() as $f) {
             $vars['field.' . $f->get('id')] = $f->toString($f->getClean());
             if (in_array($f->get('name'), $interesting)) {
                 $vars[$f->get('name')] = $vars['field.' . $f->get('id')];
             }
         }
         // Add in organization data if one exists for this email domain
         list($mailbox, $domain) = explode('@', $vars['email'], 2);
         if ($org = Organization::forDomain($domain)) {
             $vars += $org->getFilterData();
         }
     }
     //Check for 403
     if ($vars['email'] && Validator::is_email($vars['email'])) {
         //Make sure the email address is not banned
         if (TicketFilter::isBanned($vars['email'])) {
             return $reject_ticket('Banned email - ' . $vars['email']);
         }
         //Make sure the open ticket limit hasn't been reached. (LOOP CONTROL)
         if ($cfg->getMaxOpenTickets() > 0 && strcasecmp($origin, 'staff') && ($_user = TicketUser::lookupByEmail($vars['email'])) && ($openTickets = $_user->getNumOpenTickets()) && $openTickets >= $cfg->getMaxOpenTickets()) {
             $errors = array('err' => "You've reached the maximum open tickets allowed.");
             $ost->logWarning('Ticket denied -' . $vars['email'], sprintf('Max open tickets (%d) reached for %s ', $cfg->getMaxOpenTickets(), $vars['email']), false);
             return 0;
         }
     }
     //Init ticket filters...
     $ticket_filter = new TicketFilter($origin, $vars);
     // Make sure email contents should not be rejected
     if ($ticket_filter && ($filter = $ticket_filter->shouldReject())) {
         return $reject_ticket(sprintf('Ticket rejected ( %s) by filter "%s"', $vars['email'], $filter->getName()));
     }
     if ($vars['topicId'] && ($topic = Topic::lookup($vars['topicId']))) {
         if ($topic_form = $topic->getForm()) {
             $TF = $topic_form->getForm($vars);
             $topic_form = $topic_form->instanciate();
             $topic_form->setSource($vars);
             if (!$TF->isValid($field_filter('topic'))) {
                 $errors = array_merge($errors, $TF->errors());
             }
         }
     }
     $id = 0;
     $fields = array();
     $fields['message'] = array('type' => '*', 'required' => 1, 'error' => 'Message required');
     switch (strtolower($origin)) {
         case 'web':
             $fields['topicId'] = array('type' => 'int', 'required' => 1, 'error' => 'Select help topic');
             break;
         case 'staff':
             $fields['deptId'] = array('type' => 'int', 'required' => 0, 'error' => 'Dept. required');
             $fields['topicId'] = array('type' => 'int', 'required' => 1, 'error' => 'Topic required');
             $fields['duedate'] = array('type' => 'date', 'required' => 0, 'error' => 'Invalid date - must be MM/DD/YY');
         case 'api':
             $fields['source'] = array('type' => 'string', 'required' => 1, 'error' => 'Indicate source');
             break;
         case 'email':
             $fields['emailId'] = array('type' => 'int', 'required' => 1, 'error' => 'Email unknown');
             break;
         default:
             # TODO: Return error message
             $errors['err'] = $errors['origin'] = 'Invalid origin given';
     }
     if (!Validator::process($fields, $vars, $errors) && !$errors['err']) {
         $errors['err'] = 'Missing or invalid data - check the errors and try again';
     }
     if ($vars['topicId'] && !$topic) {
         $errors['topicId'] = 'Invalid help topic selected';
     }
     //Make sure the due date is valid
     if ($vars['duedate']) {
         if (!$vars['time'] || strpos($vars['time'], ':') === false) {
             $errors['time'] = 'Select time';
         } 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';
         }
     }
     if (!$errors) {
         # Perform ticket filter actions on the new ticket arguments
         if ($ticket_filter) {
             $ticket_filter->apply($vars);
         }
         // Allow vars to be changed in ticket filter and applied to the user
         // account created or detected
         if (!$user && $vars['email']) {
             $user = User::lookupByEmail($vars['email']);
         }
         if (!$user) {
             // Reject emails if not from registered clients (if
             // configured)
             if (strcasecmp($origin, 'email') === 0 && !$cfg->acceptUnregisteredEmail()) {
                 list($mailbox, $domain) = explode('@', $vars['email'], 2);
                 // Users not yet created but linked to an organization
                 // are still acceptable
                 if (!Organization::forDomain($domain)) {
                     return $reject_ticket(sprintf('Ticket rejected (%s) (unregistered client)', $vars['email']));
                 }
             }
             $user_form = UserForm::getUserForm()->getForm($vars);
             if (!$user_form->isValid($field_filter('user')) || !($user = User::fromVars($user_form->getClean()))) {
                 $errors['user'] = '******';
             }
         }
     }
     // Any error above is fatal.
     if ($errors) {
         return 0;
     }
     # Some things will need to be unpacked back into the scope of this
     # function
     if (isset($vars['autorespond'])) {
         $autorespond = $vars['autorespond'];
     }
     # Apply filter-specific priority
     if ($vars['priorityId']) {
         $form->setAnswer('priority', null, $vars['priorityId']);
     }
     // If the filter specifies a help topic which has a form associated,
     // and there was previously either no help topic set or the help
     // topic did not have a form, there's no need to add it now as (1)
     // validation is closed, (2) there may be a form already associated
     // and filled out from the original  help topic, and (3) staff
     // members can always add more forms now
     // OK...just do it.
     $deptId = $vars['deptId'];
     //pre-selected Dept if any.
     $source = ucfirst($vars['source']);
     // Apply email settings for emailed tickets. Email settings should
     // trump help topic settins if the email has an associated help
     // topic
     if ($vars['emailId'] && ($email = Email::lookup($vars['emailId']))) {
         $deptId = $deptId ?: $email->getDeptId();
         $priority = $form->getAnswer('priority');
         if (!$priority || !$priority->getIdValue()) {
             $form->setAnswer('priority', null, $email->getPriorityId());
         }
         if ($autorespond) {
             $autorespond = $email->autoRespond();
         }
         if (!isset($topic) && ($T = $email->getTopic()) && $T->isActive()) {
             $topic = $T;
         }
         $email = null;
         $source = 'Email';
     }
     if (!isset($topic)) {
         // This may return NULL, no big deal
         $topic = $cfg->getDefaultTopic();
     }
     // Intenal mapping magic...see if we need to override anything
     if (isset($topic)) {
         $deptId = $deptId ?: $topic->getDeptId();
         $priority = $form->getAnswer('priority');
         if (!$priority || !$priority->getIdValue()) {
             $form->setAnswer('priority', null, $topic->getPriorityId());
         }
         if ($autorespond) {
             $autorespond = $topic->autoRespond();
         }
         //Auto assignment.
         if (!isset($vars['staffId']) && $topic->getStaffId()) {
             $vars['staffId'] = $topic->getStaffId();
         } elseif (!isset($vars['teamId']) && $topic->getTeamId()) {
             $vars['teamId'] = $topic->getTeamId();
         }
         //set default sla.
         if (isset($vars['slaId'])) {
             $vars['slaId'] = $vars['slaId'] ?: $cfg->getDefaultSLAId();
         } elseif ($topic && $topic->getSLAId()) {
             $vars['slaId'] = $topic->getSLAId();
         }
     }
     // Auto assignment to organization account manager
     if (($org = $user->getOrganization()) && $org->autoAssignAccountManager() && ($code = $org->getAccountManagerId())) {
         if (!isset($vars['staffId']) && $code[0] == 's') {
             $vars['staffId'] = substr($code, 1);
         } elseif (!isset($vars['teamId']) && $code[0] == 't') {
             $vars['teamId'] = substr($code, 1);
         }
     }
     // Last minute checks
     $priority = $form->getAnswer('priority');
     if (!$priority || !$priority->getIdValue()) {
         $form->setAnswer('priority', null, $cfg->getDefaultPriorityId());
     }
     $deptId = $deptId ?: $cfg->getDefaultDeptId();
     $topicId = isset($topic) ? $topic->getId() : 0;
     $ipaddress = $vars['ip'] ?: $_SERVER['REMOTE_ADDR'];
     $source = $source ?: 'Web';
     //We are ready son...hold on to the rails.
     $number = Ticket::genRandTicketNumber();
     $sql = 'INSERT INTO ' . TICKET_TABLE . ' SET created=NOW() ' . ' ,lastmessage= NOW()' . ' ,user_id=' . db_input($user->getId()) . ' ,`number`=' . db_input($number) . ' ,dept_id=' . db_input($deptId) . ' ,topic_id=' . db_input($topicId) . ' ,ip_address=' . db_input($ipaddress) . ' ,source=' . db_input($source);
     if (isset($vars['emailId']) && $vars['emailId']) {
         $sql .= ', email_id=' . db_input($vars['emailId']);
     }
     //Make sure the origin is staff - avoid firebug hack!
     if ($vars['duedate'] && !strcasecmp($origin, 'staff')) {
         $sql .= ' ,duedate=' . db_input(date('Y-m-d G:i', Misc::dbtime($vars['duedate'] . ' ' . $vars['time'])));
     }
     if (!db_query($sql) || !($id = db_insert_id()) || !($ticket = Ticket::lookup($id))) {
         return null;
     }
     /* -------------------- POST CREATE ------------------------ */
     if (!$cfg->useRandomIds()) {
         //Sequential ticket number support really..really suck arse.
         //To make things really easy we are going to use autoincrement ticket_id.
         db_query('UPDATE ' . TICKET_TABLE . ' SET `number`=' . db_input($id) . ' WHERE ticket_id=' . $id . ' LIMIT 1');
         //TODO: RETHING what happens if this fails?? [At the moment on failure random ID is used...making stuff usable]
     }
     // Save the (common) dynamic form
     $form->setTicketId($id);
     $form->save();
     // Save the form data from the help-topic form, if any
     if ($topic_form) {
         $topic_form->setTicketId($id);
         $topic_form->save();
     }
     $ticket->loadDynamicData();
     $dept = $ticket->getDept();
     // Add organizational collaborators
     if ($org && $org->autoAddCollabs()) {
         $pris = $org->autoAddPrimaryContactsAsCollabs();
         $members = $org->autoAddMembersAsCollabs();
         $settings = array('isactive' => true);
         $collabs = array();
         foreach ($org->allMembers() as $u) {
             if ($members || $pris && $u->isPrimaryContact()) {
                 if ($c = $ticket->addCollaborator($u, $settings, $errors)) {
                     $collabs[] = (string) $c;
                 }
             }
         }
         //TODO: Can collaborators add others?
         if ($collabs) {
             //TODO: Change EndUser to name of  user.
             $ticket->logNote(sprintf('Collaborators for %s organization added', $org->getName()), implode("<br>", $collabs), $org->getName(), false);
         }
     }
     //post the message.
     unset($vars['cannedattachments']);
     //Ticket::open() might have it set as part of  open & respond.
     $vars['title'] = $vars['subject'];
     //Use the initial subject as title of the post.
     $vars['userId'] = $ticket->getUserId();
     $message = $ticket->postMessage($vars, $origin, false);
     // Configure service-level-agreement for this ticket
     $ticket->selectSLAId($vars['slaId']);
     // Assign ticket to staff or team (new ticket by staff)
     if ($vars['assignId']) {
         $ticket->assign($vars['assignId'], $vars['note']);
     } else {
         // Auto assign staff or team - auto assignment based on filter
         // rules. Both team and staff can be assigned
         if ($vars['staffId']) {
             $ticket->assignToStaff($vars['staffId'], 'Auto Assignment');
         }
         if ($vars['teamId']) {
             $ticket->assignToTeam($vars['teamId'], 'Auto Assignment');
         }
     }
     /**********   double check auto-response  ************/
     //Override auto responder if the FROM email is one of the internal emails...loop control.
     if ($autorespond && Email::getIdByEmail($ticket->getEmail())) {
         $autorespond = false;
     }
     # Messages that are clearly auto-responses from email systems should
     # not have a return 'ping' message
     if (isset($vars['flags']) && $vars['flags']['bounce']) {
         $autorespond = false;
     }
     if ($autorespond && $message->isAutoReply()) {
         $autorespond = false;
     }
     //post canned auto-response IF any (disables new ticket auto-response).
     if ($vars['cannedResponseId'] && $ticket->postCannedReply($vars['cannedResponseId'], $message->getId(), $autorespond)) {
         $ticket->markUnAnswered();
         //Leave the ticket as unanswred.
         $autorespond = false;
     }
     //Check department's auto response settings
     // XXX: Dept. setting doesn't affect canned responses.
     if ($autorespond && $dept && !$dept->autoRespONNewTicket()) {
         $autorespond = false;
     }
     //Don't send alerts to staff when the message is a bounce
     //  this is necessary to avoid possible loop (especially on new ticket)
     if ($alertstaff && $message->isBounce()) {
         $alertstaff = false;
     }
     /***** See if we need to send some alerts ****/
     $ticket->onNewTicket($message, $autorespond, $alertstaff);
     /************ check if the user JUST reached the max. open tickets limit **********/
     if ($cfg->getMaxOpenTickets() > 0 && ($user = $ticket->getOwner()) && $user->getNumOpenTickets() == $cfg->getMaxOpenTickets()) {
         $ticket->onOpenLimit($autorespond && strcasecmp($origin, 'staff'));
     }
     /* Start tracking ticket lifecycle events */
     $ticket->logEvent('created');
     /* Phew! ... time for tea (KETEPA) */
     return $ticket;
 }
Example #12
0
function createTicketByWebService($xml)
{
    global $logFilePath;
    try {
        if (!empty($xml)) {
            $nodes = $xml->xpath('/contacts/contact');
        } else {
            logErrors("The xml file can not be loaded ");
        }
        for ($i = 0; $i < count($nodes); $i++) {
            // echo json_encode($nodes[$i]);
            $data = array();
            // $data['recipients'] = array();
            $data['subject'] = removeLineBreaker($nodes[$i]->title);
            if (empty(removeLineBreaker($nodes[$i]->title))) {
                if (!empty(removeLineBreaker($nodes[$i]->crmsubject2_text))) {
                    $data['subject'] = removeLineBreaker($nodes[$i]->crmsubject2_text);
                } else {
                    $data['subject'] = "no title";
                }
            }
            $data['header'] = "";
            // $data['mid'] = 1;
            $data['source'] = "Web";
            $data['topicId'] = 2;
            $data['priorityId'] = 2;
            $data['crm_contact_id'] = $nodes[$i]->attributes()->id;
            // $data['flags'] = new ArrayObject();
            $data['email'] = trim(removeLineBreaker($nodes[$i]->email));
            if (empty($data['email'])) {
                $data['email'] = "*****@*****.**";
            }
            $data['phone'] = removeLineBreaker($nodes[$i]->phone);
            if (empty($data['phone'])) {
                $data['phone'] = "";
            }
            $data['name'] = trim(removeLineBreaker($nodes[$i]->name));
            if (empty($data['name'])) {
                $data['name'] = "Anonymous User";
            }
            $data['orderNumber'] = trim(removeLineBreaker($nodes[$i]->ordernumber));
            $data['ordernumber'] = trim(removeLineBreaker($nodes[$i]->ordernumber));
            $data['filenumber'] = trim(removeLineBreaker($nodes[$i]->filenumber));
            $data['cvr'] = trim(removeLineBreaker($nodes[$i]->cvr));
            $data['CVR'] = trim(removeLineBreaker($nodes[$i]->cvr));
            $data['message'] = removeLineBreaker($nodes[$i]->content);
            $data['companyName'] = removeLineBreaker($nodes[$i]->companyname);
            $data['company'] = removeLineBreaker($nodes[$i]->companyname);
            $data['business_form_id'] = removeLineBreaker($nodes[$i]->business_form_id);
            $data['activityCode'] = removeLineBreaker($nodes[$i]->activitycode);
            $data['activityDescription'] = removeLineBreaker($nodes[$i]->activitydescription);
            $data['useragent'] = removeLineBreaker($nodes[$i]->useragent);
            $crmsubject1_id = trim(removeLineBreaker($nodes[$i]->crmsubject_id));
            if (is_numeric($crmsubject1_id)) {
                $data['CRM_filter_subject1'] = removeLineBreaker($nodes[$i]->crmsubject_text);
                $data['crmsubject1_id'] = intval($crmsubject1_id);
                $data['crmsubject1_text'] = removeLineBreaker($nodes[$i]->crmsubject_text);
            } else {
                die("crmsubject1_id is not numeric");
            }
            $crmsubject2_id = trim(removeLineBreaker($nodes[$i]->crmsubject2_id));
            if (is_numeric($crmsubject2_id)) {
                $data['CRM_filter_subject2'] = removeLineBreaker($nodes[$i]->crmsubject2_text);
                $data['crmsubject2_id'] = intval($crmsubject2_id);
                $data['crmsubject2_text'] = removeLineBreaker($nodes[$i]->crmsubject2_text);
            } else {
                die("crmsubject2_id is not numeric");
            }
            // $data['flags']['bounce'] = true;
            $user = null;
            $acct = null;
            if (!$user && $data['email']) {
                $user = User::lookupByEmail($data['email']);
            }
            if (!$user) {
                $user_form = UserForm::getUserForm()->getForm($data);
                if (!($user = User::fromVars($user_form->getClean()))) {
                    echo 'Unable to register account.';
                }
                if (!($acct = ClientAccount::createForUser($user))) {
                    echo 'Internal error. Unable to create new account';
                }
            }
            $fileContent = $nodes[$i]->files->file;
            $data['fileContent'] = $fileContent;
            $tform = TicketForm::objects()->one()->getForm();
            $messageField = $tform->getField('message');
            $fileField = $messageField->getWidget()->getAttachments();
            for ($j = 0; $j < count($fileContent); $j++) {
                $fileId = $fileContent[$j]->attributes()->id;
                $file['name'] = $fileContent[$j]->name;
                $file['type'] = $fileContent[$j]->mime;
                $file['encoding'] = 'base64';
                // $file['cid'] = false;
                $url = "https://w2l.dk" . $fileContent[$j]->url;
                // logErrors("A test");
                // $url = $fileContent[$j]->url;
                // $file['data'] = base64_encode(file_get_contents($url));
                if ($file['data'] = getFileContentsSSL($url)) {
                    $timestamp = date("Y-m-d_H:i:s");
                    // if(!file_put_contents(CLIENTINC_DIR.'erstFile/'.$timestamp.$file['name'], $file['data']))
                    //     logErrors("not able to store the file");
                    try {
                        $storeCRMFile = "/var/www/html/erstFile/" . $timestamp . $file['name'];
                        echo $storeCRMFile;
                        file_put_contents("/var/www/html/erstFile/" . $timestamp . $file['name'], $file['data']);
                    } catch (Exception $e) {
                        logErrors('Caught exception: ', $e->getMessage(), "\n");
                    }
                } else {
                    logErrors("The file url is not valid");
                }
                // try {
                //     $file['id'] = $fileField->uploadAttachment($file);
                // }
                // catch (FileUploadError $ex) {
                //     $file['error'] = $file['name'] . ': ' . $ex->getMessage();
                //     echo $file['error'];
                // }
                $data['attachments'][] = $file;
                // echo $file['data'];
                // echo "<br/>";
            }
            // echo "22222";
            // echo json_encode($data);
            if (Ticket::lookupForContactId($data['crm_contact_id'])) {
                $api = new TicketApiController();
                $api->createTicket($data);
                echo "ticket has been generated successfully <br/>";
                if (DELETE_ERST_SERVICE_QUEUE) {
                    deleteContactsFromQueue($data['crm_contact_id']);
                } else {
                    logErrors("please go to include/ost-config to make the DELETE_ERST_SERVICE_QUEUE to true");
                }
            } else {
                logErrors("ticket with id " . $data['crm_contact_id'] . " has already exists");
            }
        }
    } catch (Exception $e) {
        echo 'Caught exception: ', $e->getMessage(), "\n";
    }
}
Example #13
0
<?php

$select = 'SELECT ticket.ticket_id,ticket.`number`,ticket.dept_id,ticket.staff_id,ticket.team_id, ticket.user_id ' . ' ,dept.dept_name,status.name as status,ticket.source,ticket.isoverdue,ticket.isanswered,ticket.created ' . ' ,CAST(GREATEST(IFNULL(ticket.lastmessage, 0), IFNULL(ticket.reopened, 0), ticket.created) as datetime) as effective_date ' . ' ,CONCAT_WS(" ", staff.firstname, staff.lastname) as staff, team.name as team ' . ' ,IF(staff.staff_id IS NULL,team.name,CONCAT_WS(" ", staff.lastname, staff.firstname)) as assigned ' . ' ,IF(ptopic.topic_pid IS NULL, topic.topic, CONCAT_WS(" / ", ptopic.topic, topic.topic)) as helptopic ' . ' ,cdata.priority as priority_id, cdata.subject, user.name, email.address as email';
$from = ' FROM ' . TICKET_TABLE . ' ticket ' . ' LEFT JOIN ' . TICKET_STATUS_TABLE . ' status
        ON status.id = ticket.status_id ' . ' LEFT JOIN ' . USER_TABLE . ' user ON user.id = ticket.user_id ' . ' LEFT JOIN ' . USER_EMAIL_TABLE . ' email ON user.id = email.user_id ' . ' LEFT JOIN ' . USER_ACCOUNT_TABLE . ' account ON (ticket.user_id=account.user_id) ' . ' LEFT JOIN ' . DEPT_TABLE . ' dept ON ticket.dept_id=dept.dept_id ' . ' LEFT JOIN ' . STAFF_TABLE . ' staff ON (ticket.staff_id=staff.staff_id) ' . ' LEFT JOIN ' . TEAM_TABLE . ' team ON (ticket.team_id=team.team_id) ' . ' LEFT JOIN ' . TOPIC_TABLE . ' topic ON (ticket.topic_id=topic.topic_id) ' . ' LEFT JOIN ' . TOPIC_TABLE . ' ptopic ON (ptopic.topic_id=topic.topic_pid) ' . ' LEFT JOIN ' . TABLE_PREFIX . 'ticket__cdata cdata ON (cdata.ticket_id = ticket.ticket_id) ' . ' LEFT JOIN ' . PRIORITY_TABLE . ' pri ON (pri.priority_id = cdata.priority)';
if ($user) {
    $where = 'WHERE ticket.user_id = ' . db_input($user->getId());
} elseif ($org) {
    $where = 'WHERE user.org_id = ' . db_input($org->getId());
}
TicketForm::ensureDynamicDataView();
$query = "{$select} {$from} {$where} ORDER BY ticket.created DESC";
// Fetch the results
$results = array();
$res = db_query($query);
while ($row = db_fetch_array($res)) {
    $results[$row['ticket_id']] = $row;
}
if ($results) {
    $counts_sql = 'SELECT ticket.ticket_id,
        count(DISTINCT attach.attach_id) as attachments,
        count(DISTINCT thread.id) as thread_count,
        count(DISTINCT collab.id) as collaborators
        FROM ' . TICKET_TABLE . ' ticket
        LEFT JOIN ' . TICKET_ATTACHMENT_TABLE . ' attach ON (ticket.ticket_id=attach.ticket_id) ' . ' LEFT JOIN ' . TICKET_THREAD_TABLE . ' thread ON ( ticket.ticket_id=thread.ticket_id) ' . ' LEFT JOIN ' . TICKET_COLLABORATOR_TABLE . ' collab
            ON ( ticket.ticket_id=collab.ticket_id) ' . ' WHERE ticket.ticket_id IN (' . implode(',', db_input(array_keys($results))) . ')
        GROUP BY ticket.ticket_id';
    $ids_res = db_query($counts_sql);
    while ($row = db_fetch_array($ids_res)) {
        $results[$row['ticket_id']] += $row;
    }
Example #14
0
 function _search($req)
 {
     global $thisstaff, $cfg, $ost;
     $result = array();
     $criteria = array();
     $select = 'SELECT ticket.ticket_id';
     $from = ' FROM ' . TICKET_TABLE . ' ticket
               LEFT JOIN ' . TICKET_STATUS_TABLE . ' status
                 ON (status.id = ticket.status_id) ';
     //Access control.
     $where = ' WHERE ( (ticket.staff_id=' . db_input($thisstaff->getId()) . ' AND status.state="open" )';
     if (($teams = $thisstaff->getTeams()) && count(array_filter($teams))) {
         $where .= ' OR (ticket.team_id IN (' . implode(',', db_input(array_filter($teams))) . ' ) AND status.state="open" )';
     }
     if (!$thisstaff->showAssignedOnly() && ($depts = $thisstaff->getDepts())) {
         $where .= ' OR ticket.dept_id IN (' . implode(',', db_input($depts)) . ')';
     }
     $where .= ' ) ';
     //Department
     if ($req['deptId']) {
         $where .= ' AND ticket.dept_id=' . db_input($req['deptId']);
         $criteria['dept_id'] = $req['deptId'];
     }
     //Help topic
     if ($req['topicId']) {
         $where .= ' AND ticket.topic_id=' . db_input($req['topicId']);
         $criteria['topic_id'] = $req['topicId'];
     }
     // Status
     if ($req['statusId'] && ($status = TicketStatus::lookup($req['statusId']))) {
         $where .= sprintf(' AND status.id="%d" ', $status->getId());
         $criteria['status_id'] = $status->getId();
     }
     // Flags
     if ($req['flag']) {
         switch (strtolower($req['flag'])) {
             case 'answered':
                 $where .= ' AND ticket.isanswered =1 ';
                 $criteria['isanswered'] = 1;
                 $criteria['state'] = 'open';
                 $where .= ' AND status.state="open" ';
                 break;
             case 'overdue':
                 $where .= ' AND ticket.isoverdue =1 ';
                 $criteria['isoverdue'] = 1;
                 $criteria['state'] = 'open';
                 $where .= ' AND status.state="open" ';
                 break;
         }
     }
     //Assignee
     if ($req['assignee'] && strcasecmp($req['status'], 'closed')) {
         # assigned-to
         $id = preg_replace("/[^0-9]/", "", $req['assignee']);
         $assignee = $req['assignee'];
         $where .= ' AND ( ( status.state="open" ';
         if ($assignee[0] == 't') {
             $where .= ' AND ticket.team_id=' . db_input($id);
             $criteria['team_id'] = $id;
         } elseif ($assignee[0] == 's' || is_numeric($id)) {
             $where .= ' AND ticket.staff_id=' . db_input($id);
             $criteria['staff_id'] = $id;
         }
         $where .= ')';
         if ($req['staffId'] && !$req['status']) {
             //Assigned TO + Closed By
             $where .= ' OR (ticket.staff_id=' . db_input($req['staffId']) . ' AND status.state IN("closed")) ';
         } elseif ($req['staffId']) {
             // closed by any
             $where .= ' OR status.state IN("closed") ';
         }
         $where .= ' ) ';
     } elseif ($req['staffId']) {
         # closed-by
         $where .= ' AND (ticket.staff_id=' . db_input($req['staffId']) . ' AND
             status.state IN("closed")) ';
         $criteria['state__in'] = array('closed');
         $criteria['staff_id'] = $req['staffId'];
     }
     //dates
     $startTime = $req['startDate'] && strlen($req['startDate']) >= 8 ? strtotime($req['startDate']) : 0;
     $endTime = $req['endDate'] && strlen($req['endDate']) >= 8 ? strtotime($req['endDate']) : 0;
     if ($endTime) {
         // $endTime should be the last second of the day, not the first like $startTime
         $endTime += 60 * 60 * 24 - 1;
     }
     if ($startTime && $startTime > time() or $startTime > $endTime && $endTime > 0) {
         $startTime = $endTime = 0;
     }
     if ($startTime) {
         $where .= ' AND ticket.created>=FROM_UNIXTIME(' . $startTime . ')';
         $criteria['created__gte'] = $startTime;
     }
     if ($endTime) {
         $where .= ' AND ticket.created<=FROM_UNIXTIME(' . $endTime . ')';
         $criteria['created__lte'] = $startTime;
     }
     // Dynamic fields
     $cdata_search = false;
     foreach (TicketForm::getInstance()->getFields() as $f) {
         if (isset($req[$f->getFormName()]) && ($val = $req[$f->getFormName()])) {
             $name = $f->get('name') ? $f->get('name') : 'field_' . $f->get('id');
             if (is_array($val)) {
                 $cwhere = '(' . implode(' OR ', array_map(function ($k) use($name) {
                     return sprintf('FIND_IN_SET(%s, `%s`)', db_input($k), $name);
                 }, $val)) . ')';
                 $criteria["cdata.{$name}"] = $val;
             } else {
                 $cwhere = "cdata.`{$name}` LIKE '%" . db_real_escape($val) . "%'";
                 $criteria["cdata.{$name}"] = $val;
             }
             $where .= ' AND (' . $cwhere . ')';
             $cdata_search = true;
         }
     }
     if ($cdata_search) {
         $from .= 'LEFT JOIN ' . TABLE_PREFIX . 'ticket__cdata ' . " cdata ON (cdata.ticket_id = ticket.ticket_id)";
     }
     //Query
     $joins = array();
     if ($req['query']) {
         // Setup sets of joins and queries
         if ($s = $ost->searcher) {
             return $s->find($req['query'], $criteria, 'Ticket');
         }
     }
     $sections = array();
     foreach ($joins as $j) {
         $sections[] = "{$select} {$from} {$j['from']} {$where} AND ({$j['where']})";
     }
     if (!$joins) {
         $sections[] = "{$select} {$from} {$where}";
     }
     $sql = implode(' union ', $sections);
     if (!($res = db_query($sql))) {
         return TicketForm::dropDynamicDataView();
     }
     $tickets = array();
     while ($row = db_fetch_row($res)) {
         $tickets[] = $row[0];
     }
     return $tickets;
 }
Example #15
0
 static function dumpTickets($sql, $how = 'csv')
 {
     // Add custom fields to the $sql statement
     $cdata = $fields = $select = array();
     foreach (TicketForm::getInstance()->getFields() as $f) {
         // Ignore core fields
         if (in_array($f->get('name'), array('subject', 'priority'))) {
             continue;
         } elseif (!$f->hasData() || $f->isPresentationOnly()) {
             continue;
         }
         $name = $f->get('name') ? $f->get('name') : 'field_' . $f->get('id');
         $key = '__field_' . $f->get('id');
         $cdata[$key] = $f->get('label');
         $fields[$key] = $f;
         $select[] = "cdata.`{$name}` AS __field_" . $f->get('id');
     }
     //Inicio 13/04/2016 Se agrego el campo tiempo a cdata para mostrarlo en el archivo junto con el tiempo de duracion del ticket
     $cdata['tiempo'] = 'Tiempo de Respuesta';
     $select[] = "'Tiempo de Respuesta' AS tiempo";
     //Fin 13/04/2016 Se agrego el campo tiempo a cdata para mostrarlo en el archivo junto con el tiempo de duracion del ticket
     if ($select) {
         $sql = str_replace(' FROM ', ',' . implode(',', $select) . ' FROM ', $sql);
     }
     return self::dumpQuery($sql, array('number' => __('Ticket Number'), 'ticket_created' => __('Date'), 'subject' => __('Subject'), 'name' => __('From'), 'email' => __('From Email'), 'priority_desc' => __('Priority'), 'dept_name' => __('Department'), 'helptopic' => __('Help Topic'), 'source' => __('Source'), 'status' => __('Current Status'), 'effective_date' => __('Last Updated'), 'duedate' => __('Due Date'), 'isoverdue' => __('Overdue'), 'isanswered' => __('Answered'), 'assigned' => __('Assigned To'), 'staff' => __('Agent Assigned'), 'team' => __('Team Assigned'), 'thread_count' => __('Thread Count'), 'attachments' => __('Attachment Count')) + $cdata, $how, array('modify' => function (&$record, $keys) use($fields) {
         foreach ($fields as $k => $f) {
             if (($i = array_search($k, $keys)) !== false) {
                 $record[$i] = $f->export($f->to_php($record[$i]));
             }
         }
         //Inicio 13/04/2016 Se llena la comlumna tiempo del archivo con la duracion de cada ticket
         $fecha1 = new DateTime($record[1]);
         if ($_REQUEST["status"] == "open" || $_REQUEST["status"] == "assigned") {
             $fecha2 = new DateTime(date("Y-m-d H:i:s"));
         } else {
             $fecha2 = new DateTime($record[10]);
         }
         $fecha = $fecha1->diff($fecha2);
         if ($fecha->y > 0) {
             $record[$i + 1] = $fecha->y . "A " . $fecha->m . "M " . $fecha->d . "d " . $fecha->h . "h " . $fecha->i . "m ";
         } else {
             if ($fecha->m > 0) {
                 $record[$i + 1] = $fecha->m . "M " . $fecha->d . "d " . $fecha->h . "h " . $fecha->i . "m ";
             } else {
                 if ($fecha->d > 0) {
                     $record[$i + 1] = $fecha->d . "d " . $fecha->h . "h " . $fecha->i . "m ";
                 } else {
                     if ($fecha->h > 0) {
                         $record[$i + 1] = $fecha->h . "h " . $fecha->i . "m ";
                     } else {
                         if ($fecha->i > 0) {
                             $record[$i + 1] = $fecha->i . "m ";
                         } else {
                             $record[$i + 1] = '0m';
                         }
                     }
                 }
             }
         }
         return $record;
         //Inicio 13/04/2016 Se llena la comlumna tiempo del archivo con la duracion de cada ticket
     }));
 }
Example #16
0
 function createTicket($mid)
 {
     global $ost;
     if (!($mailinfo = $this->getHeaderInfo($mid))) {
         return false;
     }
     // TODO: If the content-type of the message is 'message/rfc822',
     // then this is a message with the forwarded message as the
     // attachment. Download the body and pass it along to the mail
     // parsing engine.
     $info = Mail_Parse::splitHeaders($mailinfo['header']);
     if (strtolower($info['Content-Type']) == 'message/rfc822') {
         if ($wrapped = $this->getPart($mid, 'message/rfc822')) {
             require_once INCLUDE_DIR . 'api.tickets.php';
             // Simulate piping the contents into the system
             $api = new TicketApiController();
             $parser = new EmailDataParser();
             if ($data = $parser->parse($wrapped)) {
                 return $api->processEmail($data);
             }
         }
         // If any of this fails, create the ticket as usual
     }
     //Is the email address banned?
     if ($mailinfo['email'] && TicketFilter::isBanned($mailinfo['email'])) {
         //We need to let admin know...
         $ost->logWarning(_S('Ticket denied'), sprintf(_S('Banned email โ€” %s'), $mailinfo['email']), false);
         return true;
         //Report success (moved or delete)
     }
     // Parse MS TNEF emails
     if (($struct = imap_fetchstructure($this->mbox, $mid)) && ($attachments = $this->getAttachments($struct))) {
         foreach ($attachments as $i => $info) {
             if (0 === strcasecmp('application/ms-tnef', $info['type'])) {
                 try {
                     $data = $this->decode(imap_fetchbody($this->mbox, $mid, $info['index']), $info['encoding']);
                     $tnef = new TnefStreamParser($data);
                     $this->tnef = $tnef->getMessage();
                     // No longer considered an attachment
                     unset($attachments[$i]);
                     // There should only be one of these
                     break;
                 } catch (TnefException $ex) {
                     // Noop -- winmail.dat remains an attachment
                 }
             }
         }
     }
     $vars = $mailinfo;
     $vars['name'] = $mailinfo['name'];
     $vars['subject'] = $mailinfo['subject'] ?: '[No Subject]';
     $vars['emailId'] = $mailinfo['emailId'] ?: $this->getEmailId();
     $vars['to-email-id'] = $mailinfo['emailId'] ?: 0;
     $vars['flags'] = new ArrayObject();
     if ($this->isBounceNotice($mid)) {
         // Fetch the original References and assign to 'references'
         if ($headers = $this->getOriginalMessageHeaders($mid)) {
             $vars['references'] = $headers['references'];
             $vars['in-reply-to'] = @$headers['in-reply-to'] ?: null;
         }
         // Fetch deliver status report
         $vars['message'] = $this->getDeliveryStatusMessage($mid) ?: $this->getBody($mid);
         $vars['thread-type'] = 'N';
         $vars['flags']['bounce'] = true;
     } else {
         $vars['message'] = $this->getBody($mid);
         $vars['flags']['bounce'] = TicketFilter::isBounce($info);
     }
     //Missing FROM name  - use email address.
     if (!$vars['name']) {
         list($vars['name']) = explode('@', $vars['email']);
     }
     if ($ost->getConfig()->useEmailPriority()) {
         $vars['priorityId'] = $this->getPriority($mid);
     }
     $ticket = null;
     $newticket = true;
     $errors = array();
     $seen = false;
     // Use the settings on the thread entry on the ticket details
     // form to validate the attachments in the email
     $tform = TicketForm::objects()->one()->getForm();
     $messageField = $tform->getField('message');
     $fileField = $messageField->getWidget()->getAttachments();
     // Fetch attachments if any.
     if ($messageField->isAttachmentsEnabled()) {
         // Include TNEF attachments in the attachments list
         if ($this->tnef) {
             foreach ($this->tnef->attachments as $at) {
                 $attachments[] = array('cid' => @$at->AttachContentId ?: false, 'data' => $at, 'size' => @$at->DataSize ?: null, 'type' => @$at->AttachMimeTag ?: false, 'name' => $at->getName());
             }
         }
         $vars['attachments'] = array();
         foreach ($attachments as $a) {
             $file = array('name' => $a['name'], 'type' => $a['type']);
             if (@$a['data'] instanceof TnefAttachment) {
                 $file['data'] = $a['data']->getData();
             } else {
                 // only fetch the body if necessary
                 $self = $this;
                 $file['data'] = function () use($self, $mid, $a) {
                     return $self->decode(imap_fetchbody($self->mbox, $mid, $a['index']), $a['encoding']);
                 };
             }
             // Include the Content-Id if specified (for inline images)
             $file['cid'] = isset($a['cid']) ? $a['cid'] : false;
             // Validate and save immediately
             try {
                 $file['id'] = $fileField->uploadAttachment($file);
             } catch (FileUploadError $ex) {
                 $file['error'] = $file['name'] . ': ' . $ex->getMessage();
             }
             $vars['attachments'][] = $file;
         }
     }
     // Allow signal handlers to interact with the message decoding
     Signal::send('mail.processed', $this, $vars);
     $seen = false;
     if (($thread = ThreadEntry::lookupByEmailHeaders($vars, $seen)) && ($t = $thread->getTicket()) && ($vars['staffId'] || !$t->isClosed() || $t->isReopenable()) && ($message = $thread->postEmail($vars))) {
         if (!$message instanceof ThreadEntry) {
             // Email has been processed previously
             return $message;
         }
         $ticket = $message->getTicket();
     } elseif ($seen) {
         // Already processed, but for some reason (like rejection), no
         // thread item was created. Ignore the email
         return true;
     } elseif ($ticket = Ticket::create($vars, $errors, 'Email')) {
         $message = $ticket->getLastMessage();
     } else {
         //Report success if the email was absolutely rejected.
         if (isset($errors['errno']) && $errors['errno'] == 403) {
             // Never process this email again!
             ThreadEntry::logEmailHeaders(0, $vars['mid']);
             return true;
         }
         // Log an error to the system logs
         $mailbox = Email::lookup($vars['emailId']);
         $ost->logError(_S('Mail Processing Exception'), sprintf(_S("Mailbox: %s | Error(s): %s"), $mailbox->getEmail(), print_r($errors, true)), false);
         // Indicate failure of mail processing
         return null;
     }
     return $ticket;
 }
" title="Sort By Department"><?php 
echo __('Department');
?>
</a>
            </th>
            <th width="120">
                Localizador
            </th>
            <th width="120">
                Status
            </th>
        </tr>
    </thead>
    <tbody>
    <?php 
$subject_field = TicketForm::objects()->one()->getField('subject');
if ($res && ($num = db_num_rows($res))) {
    $defaultDept = Dept::getDefaultDeptName();
    //Default public dept.
    while ($row = db_fetch_array($res)) {
        $dept = $row['ispublic'] ? $row['dept_name'] : $defaultDept;
        $subject = Format::truncate($subject_field->display($subject_field->to_php($row['subject']) ?: $row['subject']), 40);
        if ($row['attachments']) {
            $subject .= '  &nbsp;&nbsp;<span class="Icon file"></span>';
        }
        $ticketNumber = $row['number'];
        if ($row['isanswered'] && !strcasecmp($row['state'], 'open')) {
            $subject = "<b>{$subject}</b>";
            $ticketNumber = "<b>{$ticketNumber}</b>";
        }
        ?>
?>

<table width="800" cellpadding="1" cellspacing="0" border="0" id="ticketInfo">
    <tr>
        <td colspan="2" width="100%">
            <h1>
                <a href="tickets.php?id=<?php 
echo $ticket->getId();
?>
" title="<?php 
echo __('Reload');
?>
"><i class="refresh icon-refresh"></i></a>
                <b>
                <?php 
$subject_field = TicketForm::getInstance()->getField('subject');
echo $subject_field->display($ticket->getSubject());
?>
                </b>
                <small>#<?php 
echo $ticket->getNumber();
?>
</small>
<div class="pull-right">
    <a class="action-button" href="tickets.php?a=print&id=<?php 
echo $ticket->getId();
?>
"><i class="icon-print"></i> <?php 
echo __('Print');
?>
</a>