1394 lines
76 KiB
PHP
1394 lines
76 KiB
PHP
<?php
|
|
|
|
use app\services\MergeTickets;
|
|
|
|
defined('BASEPATH') or exit('No direct script access allowed');
|
|
|
|
class Tickets_model extends App_Model {
|
|
private $piping = false;
|
|
|
|
public function __construct() {
|
|
parent::__construct();
|
|
}
|
|
|
|
public function ticket_count($status = null, $playground = false) {
|
|
$where = 'AND merged_ticket_id is NULL';
|
|
if (!is_admin()) {
|
|
$this->load->model('departments_model');
|
|
$staff_deparments_ids = $this->departments_model->get_staff_departments(get_staff_user_id(), true, $playground);
|
|
if (get_option('staff_access_only_assigned_departments') == 1) {
|
|
$departments_ids = [];
|
|
if (count($staff_deparments_ids) == 0) {
|
|
$departments = $this->departments_model->get();
|
|
foreach ($departments as $department) {
|
|
array_push($departments_ids, $department['departmentid']);
|
|
}
|
|
} else {
|
|
$departments_ids = $staff_deparments_ids;
|
|
}
|
|
if (count($departments_ids) > 0) {
|
|
$where = 'AND department IN (SELECT departmentid FROM ' . db_prefix() . ($playground ? 'playground_' : '') . 'staff_departments WHERE departmentid IN (' . implode(',', $departments_ids) . ') AND staffid="' . get_staff_user_id() . '")';
|
|
}
|
|
}
|
|
}
|
|
$_where = '';
|
|
if (!is_null($status)) {
|
|
if ($where == '') {
|
|
$_where = 'status=' . $status;
|
|
} else {
|
|
$_where = 'status=' . $status . ' ' . $where;
|
|
}
|
|
}
|
|
return total_rows(db_prefix() . ($playground ? 'playground_' : '') . 'tickets', $_where);
|
|
}
|
|
|
|
public function insert_piped_ticket($data, $playground = false) {
|
|
$data = hooks()->apply_filters('piped_ticket_data', $data);
|
|
$this->piping = true;
|
|
$attachments = $data['attachments'];
|
|
$subject = $data['subject'];
|
|
// Prevent insert ticket to database if mail delivery error happen
|
|
// This will stop createing a thousand tickets
|
|
$system_blocked_subjects = ['Mail delivery failed', 'failure notice', 'Returned mail: see transcript for details', 'Undelivered Mail Returned to Sender', ];
|
|
$subject_blocked = false;
|
|
foreach ($system_blocked_subjects as $sb) {
|
|
if (strpos('x' . $subject, $sb) !== false) {
|
|
$subject_blocked = true;
|
|
break;
|
|
}
|
|
}
|
|
if ($subject_blocked == true) {
|
|
return;
|
|
}
|
|
$message = $data['body'];
|
|
$name = $data['fromname'];
|
|
$email = $data['email'];
|
|
$to = $data['to'];
|
|
$cc = $data['cc'] ?? [];
|
|
$subject = $subject;
|
|
$message = $message;
|
|
$this->load->model('spam_filters_model');
|
|
$mailstatus = $this->spam_filters_model->check($email, $subject, $message, 'tickets', $playground);
|
|
// No spam found
|
|
if (!$mailstatus) {
|
|
$pos = strpos($subject, '[Ticket ID: ');
|
|
if ($pos === false) {
|
|
} else {
|
|
$tid = substr($subject, $pos + 12);
|
|
$tid = substr($tid, 0, strpos($tid, ']'));
|
|
$this->db->where('ticketid', $tid);
|
|
$data = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'tickets')->row();
|
|
$tid = $data->ticketid;
|
|
}
|
|
$to = trim($to);
|
|
$toemails = explode(',', $to);
|
|
$department_id = false;
|
|
$userid = false;
|
|
foreach ($toemails as $toemail) {
|
|
if (!$department_id) {
|
|
$this->db->where('email', trim($toemail));
|
|
$data = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'departments')->row();
|
|
if ($data) {
|
|
$department_id = $data->departmentid;
|
|
$to = $data->email;
|
|
}
|
|
}
|
|
}
|
|
if (!$department_id) {
|
|
$mailstatus = 'Department Not Found';
|
|
} else {
|
|
if ($to == $email) {
|
|
$mailstatus = 'Blocked Potential Email Loop';
|
|
} else {
|
|
$message = trim($message);
|
|
$this->db->where('active', 1);
|
|
$this->db->where('email', $email);
|
|
$result = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'staff')->row();
|
|
if ($result) {
|
|
if ($tid) {
|
|
$data = [];
|
|
$data['message'] = $message;
|
|
$data['status'] = get_option('default_ticket_reply_status');
|
|
if (!$data['status']) {
|
|
$data['status'] = 3; // Answered
|
|
|
|
}
|
|
if ($userid == false) {
|
|
$data['name'] = $name;
|
|
$data['email'] = $email;
|
|
}
|
|
if (count($cc) > 0) {
|
|
$data['cc'] = $cc;
|
|
}
|
|
$reply_id = $this->add_reply($data, $tid, $result->staffid, $attachments, $playground);
|
|
if ($reply_id) {
|
|
$mailstatus = 'Ticket Reply Imported Successfully';
|
|
}
|
|
} else {
|
|
$mailstatus = 'Ticket ID Not Found';
|
|
}
|
|
} else {
|
|
$this->db->where('email', $email);
|
|
$result = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'contacts')->row();
|
|
if ($result) {
|
|
$userid = $result->userid;
|
|
$contactid = $result->id;
|
|
}
|
|
if ($userid == false && get_option('email_piping_only_registered') == '1') {
|
|
$mailstatus = 'Unregistered Email Address';
|
|
} else {
|
|
$filterdate = date('Y-m-d H:i:s', strtotime('-15 minutes'));
|
|
$query = 'SELECT count(*) as total FROM ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets WHERE date > "' . $filterdate . '" AND (email="' . $this->db->escape($email) . '"';
|
|
if ($userid) {
|
|
$query.= ' OR userid=' . (int)$userid;
|
|
}
|
|
$query.= ')';
|
|
$result = $this->db->query($query)->row();
|
|
if (10 < $result->total) {
|
|
$mailstatus = 'Exceeded Limit of 10 Tickets within 15 Minutes';
|
|
} else {
|
|
if (isset($tid)) {
|
|
$data = [];
|
|
$data['message'] = $message;
|
|
$data['status'] = 1;
|
|
if ($userid == false) {
|
|
$data['name'] = $name;
|
|
$data['email'] = $email;
|
|
} else {
|
|
$data['userid'] = $userid;
|
|
$data['contactid'] = $contactid;
|
|
$this->db->where('ticketid', $tid);
|
|
$this->db->group_start();
|
|
$this->db->where('userid', $userid);
|
|
// Allow CC'ed user to reply to the ticket
|
|
$this->db->or_like('cc', $email);
|
|
$this->db->group_end();
|
|
$t = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'tickets')->row();
|
|
if (!$t) {
|
|
$abuse = true;
|
|
}
|
|
}
|
|
if (!isset($abuse)) {
|
|
if (count($cc) > 0) {
|
|
$data['cc'] = $cc;
|
|
}
|
|
$reply_id = $this->add_reply($data, $tid, null, $attachments, $playground);
|
|
if ($reply_id) {
|
|
// Dont change this line
|
|
$mailstatus = 'Ticket Reply Imported Successfully';
|
|
}
|
|
} else {
|
|
$mailstatus = 'Ticket ID Not Found For User';
|
|
}
|
|
} else {
|
|
if (get_option('email_piping_only_registered') == 1 && !$userid) {
|
|
$mailstatus = 'Blocked Ticket Opening from Unregistered User';
|
|
} else {
|
|
if (get_option('email_piping_only_replies') == '1') {
|
|
$mailstatus = 'Only Replies Allowed by Email';
|
|
} else {
|
|
$data = [];
|
|
$data['department'] = $department_id;
|
|
$data['subject'] = $subject;
|
|
$data['message'] = $message;
|
|
$data['contactid'] = $contactid;
|
|
$data['priority'] = get_option('email_piping_default_priority');
|
|
if ($userid == false) {
|
|
$data['name'] = $name;
|
|
$data['email'] = $email;
|
|
} else {
|
|
$data['userid'] = $userid;
|
|
}
|
|
$tid = $this->add($data, null, $attachments, $playground);
|
|
if ($tid && count($cc) > 0) {
|
|
// A customer opens a ticket by mail to "support@example".com, with one or many 'Cc'
|
|
// Remember those 'Cc'.
|
|
$this->db->where('ticketid', $tid);
|
|
$this->db->update(($playground ? 'playground_' : '') . 'tickets', ['cc' => implode(',', $cc) ]);
|
|
}
|
|
// Dont change this line
|
|
$mailstatus = 'Ticket Imported Successfully';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ($mailstatus == '') {
|
|
$mailstatus = 'Ticket Import Failed';
|
|
}
|
|
$this->db->insert(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_pipe_log', ['date' => date('Y-m-d H:i:s'), 'email_to' => $to, 'name' => $name ? : 'Unknown', 'email' => $email ? : 'N/A', 'subject' => $subject ? : 'N/A', 'message' => $message, 'status' => $mailstatus, ]);
|
|
return $mailstatus;
|
|
}
|
|
|
|
private function process_pipe_attachments($attachments, $ticket_id, $reply_id = '', $playground = false) {
|
|
if (!empty($attachments)) {
|
|
$ticket_attachments = [];
|
|
$allowed_extensions = array_map(function ($ext) {
|
|
return strtolower(trim($ext));
|
|
}, explode(',', get_option('ticket_attachments_file_extensions')));
|
|
$path = FCPATH . 'uploads/' . ($playground ? 'playground_' : '') . 'ticket_attachments' . '/' . $ticket_id . '/';
|
|
foreach ($attachments as $attachment) {
|
|
$filename = $attachment['filename'];
|
|
$filenameparts = explode('.', $filename);
|
|
$extension = end($filenameparts);
|
|
$extension = strtolower($extension);
|
|
if (in_array('.' . $extension, $allowed_extensions)) {
|
|
$filename = implode(array_slice($filenameparts, 0, 0 - 1));
|
|
$filename = trim(preg_replace('/[^a-zA-Z0-9-_ ]/', '', $filename));
|
|
if (!$filename) {
|
|
$filename = 'attachment';
|
|
}
|
|
if (!file_exists($path)) {
|
|
mkdir($path, 0755);
|
|
$fp = fopen($path . 'index.html', 'w');
|
|
fclose($fp);
|
|
}
|
|
$filename = unique_filename($path, $filename . '.' . $extension);
|
|
file_put_contents($path . $filename, $attachment['data']);
|
|
array_push($ticket_attachments, ['file_name' => $filename, 'filetype' => get_mime_by_extension($filename), ]);
|
|
}
|
|
}
|
|
$this->insert_ticket_attachments_to_database($ticket_attachments, $ticket_id, $reply_id, $playground);
|
|
}
|
|
}
|
|
|
|
public function get($id = '', $where = [], $playground = false) {
|
|
$this->db->select('*,' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.userid,' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.name as from_name,' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.email as ticket_email, ' . db_prefix() . ($playground ? 'playground_' : '') . 'departments.name as department_name, ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets_priorities.name as priority_name, statuscolor, ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.admin, ' . db_prefix() . ($playground ? 'playground_' : '') . 'services.name as service_name, service, ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets_status.name as status_name,' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.ticketid, ' . db_prefix() . ($playground ? 'playground_' : '') . 'contacts.firstname as user_firstname, ' . db_prefix() . ($playground ? 'playground_' : '') . 'contacts.lastname as user_lastname,' . db_prefix() . ($playground ? 'playground_' : '') . 'staff.firstname as staff_firstname, ' . db_prefix() . ($playground ? 'playground_' : '') . 'staff.lastname as staff_lastname,lastreply,message,' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.status,subject,department,priority,' . db_prefix() . ($playground ? 'playground_' : '') . 'contacts.email,adminread,clientread,date');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'departments', db_prefix() . ($playground ? 'playground_' : '') . 'departments.departmentid = ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.department', 'left');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_status', db_prefix() . ($playground ? 'playground_' : '') . 'tickets_status.ticketstatusid = ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.status', 'left');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'services', db_prefix() . ($playground ? 'playground_' : '') . 'services.serviceid = ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.service', 'left');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'clients', db_prefix() . ($playground ? 'playground_' : '') . 'clients.userid = ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.userid', 'left');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', db_prefix() . ($playground ? 'playground_' : '') . 'contacts.id = ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.contactid', 'left');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'staff', db_prefix() . ($playground ? 'playground_' : '') . 'staff.staffid = ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.admin', 'left');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_priorities', db_prefix() . ($playground ? 'playground_' : '') . 'tickets_priorities.priorityid = ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.priority', 'left');
|
|
$this->db->where($where);
|
|
if (is_numeric($id)) {
|
|
$this->db->where(db_prefix() . ($playground ? 'playground_' : '') . 'tickets.ticketid', $id);
|
|
return $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'tickets')->row();
|
|
}
|
|
$this->db->order_by('lastreply', 'asc');
|
|
if (is_client_logged_in()) {
|
|
$this->db->where(db_prefix() . ($playground ? 'playground_' : '') . 'tickets.merged_ticket_id IS NULL', null, false);
|
|
}
|
|
return $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'tickets')->result_array();
|
|
}
|
|
|
|
/**
|
|
* Get ticket by id and all data
|
|
* @param mixed $id ticket id
|
|
* @param mixed $userid Optional - Tickets from USER ID
|
|
* @return object
|
|
*/
|
|
public function get_ticket_by_id($id, $userid = '', $playground = false) {
|
|
$this->db->select('*, ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.userid, ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.name as from_name, ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.email as ticket_email, ' . db_prefix() . ($playground ? 'playground_' : '') . 'departments.name as department_name, ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets_priorities.name as priority_name, statuscolor, ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.admin, ' . db_prefix() . ($playground ? 'playground_' : '') . 'services.name as service_name, service, ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets_status.name as status_name, ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.ticketid, ' . db_prefix() . ($playground ? 'playground_' : '') . 'contacts.firstname as user_firstname, ' . db_prefix() . ($playground ? 'playground_' : '') . 'contacts.lastname as user_lastname, ' . db_prefix() . ($playground ? 'playground_' : '') . 'staff.firstname as staff_firstname, ' . db_prefix() . ($playground ? 'playground_' : '') . 'staff.lastname as staff_lastname, lastreply, message, ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.status, subject, department, priority, ' . db_prefix() . ($playground ? 'playground_' : '') . 'contacts.email, adminread, clientread, date');
|
|
$this->db->from(db_prefix() . ($playground ? 'playground_' : '') . 'tickets');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'departments', db_prefix() . ($playground ? 'playground_' : '') . 'departments.departmentid = ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.department', 'left');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_status', db_prefix() . ($playground ? 'playground_' : '') . 'tickets_status.ticketstatusid = ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.status', 'left');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'services', db_prefix() . ($playground ? 'playground_' : '') . 'services.serviceid = ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.service', 'left');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'clients', db_prefix() . ($playground ? 'playground_' : '') . 'clients.userid = ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.userid', 'left');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'staff', db_prefix() . ($playground ? 'playground_' : '') . 'staff.staffid = ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.admin', 'left');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', db_prefix() . ($playground ? 'playground_' : '') . 'contacts.id = ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.contactid', 'left');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_priorities', db_prefix() . ($playground ? 'playground_' : '') . 'tickets_priorities.priorityid = ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.priority', 'left');
|
|
if (strlen($id) === 32) {
|
|
$this->db->where(db_prefix() . ($playground ? 'playground_' : '') . 'tickets.ticketkey', $id);
|
|
} else {
|
|
$this->db->where(db_prefix() . ($playground ? 'playground_' : '') . 'tickets.ticketid', $id);
|
|
}
|
|
if (is_numeric($userid)) {
|
|
$this->db->where(db_prefix() . ($playground ? 'playground_' : '') . 'tickets.userid', $userid);
|
|
}
|
|
$ticket = $this->db->get()->row();
|
|
if ($ticket) {
|
|
$ticket->submitter = $ticket->contactid != 0 ? ($ticket->user_firstname . ' ' . $ticket->user_lastname) : $ticket->from_name;
|
|
if (!($ticket->admin == null || $ticket->admin == 0)) {
|
|
$ticket->opened_by = $ticket->staff_firstname . ' ' . $ticket->staff_lastname;
|
|
}
|
|
$ticket->attachments = $this->get_ticket_attachments($ticket->ticketid, '', $playground);
|
|
}
|
|
return $ticket;
|
|
}
|
|
|
|
/**
|
|
* Insert ticket attachments to database
|
|
* @param array $attachments array of attachment
|
|
* @param mixed $ticketid
|
|
* @param boolean $replyid If is from reply
|
|
*/
|
|
public function insert_ticket_attachments_to_database($attachments, $ticketid, $replyid = false, $playground = false) {
|
|
foreach ($attachments as $attachment) {
|
|
$attachment['ticketid'] = $ticketid;
|
|
$attachment['dateadded'] = date('Y-m-d H:i:s');
|
|
if ($replyid !== false && is_int($replyid)) {
|
|
$attachment['replyid'] = $replyid;
|
|
}
|
|
$this->db->insert(db_prefix() . ($playground ? 'playground_' : '') . 'ticket_attachments', $attachment);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get ticket attachments from database
|
|
* @param mixed $id ticket id
|
|
* @param mixed $replyid Optional - reply id if is from from reply
|
|
* @return array
|
|
*/
|
|
public function get_ticket_attachments($id, $replyid = '', $playground = false) {
|
|
$this->db->where('ticketid', $id);
|
|
$this->db->where('replyid', is_numeric($replyid) ? $replyid : null);
|
|
return $this->db->get(($playground ? 'playground_' : '') . 'ticket_attachments')->result_array();
|
|
}
|
|
|
|
/**
|
|
* Add new reply to ticket
|
|
* @param mixed $data reply $_POST data
|
|
* @param mixed $id ticket id
|
|
* @param boolean $admin staff id if is staff making reply
|
|
*/
|
|
public function add_reply($data, $id, $admin = null, $pipe_attachments = false, $playground = false) {
|
|
if (isset($data['assign_to_current_user'])) {
|
|
$assigned = get_staff_user_id();
|
|
unset($data['assign_to_current_user']);
|
|
}
|
|
$unsetters = ['note_description', 'department', 'priority', 'subject', 'assigned', 'project_id', 'service', 'status_top', 'attachments', 'DataTables_Table_0_length', 'DataTables_Table_1_length', 'custom_fields', ];
|
|
foreach ($unsetters as $unset) {
|
|
if (isset($data[$unset])) {
|
|
unset($data[$unset]);
|
|
}
|
|
}
|
|
if ($admin !== null) {
|
|
$data['admin'] = $admin;
|
|
$status = $data['status'];
|
|
} else {
|
|
$status = 1;
|
|
}
|
|
if (isset($data['status'])) {
|
|
unset($data['status']);
|
|
}
|
|
$cc = '';
|
|
if (isset($data['cc'])) {
|
|
$cc = $data['cc'];
|
|
unset($data['cc']);
|
|
}
|
|
// if ticket is merged
|
|
$ticket = $this->get($id, [], $playground);
|
|
$data['ticketid'] = ($ticket && $ticket->merged_ticket_id != null) ? $ticket->merged_ticket_id : $id;
|
|
$data['date'] = date('Y-m-d H:i:s');
|
|
$data['message'] = trim($data['message']);
|
|
if ($this->piping == true) {
|
|
// $data['message'] = preg_replace('/\v+/u', '<br>', $data['message']);
|
|
|
|
}
|
|
$is_html_stripped = $this->piping === true;
|
|
// admin can have html
|
|
if (!$is_html_stripped && $admin == null && hooks()->apply_filters('ticket_message_without_html_for_non_admin', true)) {
|
|
$data['message'] = _strip_tags($data['message']);
|
|
$data['message'] = nl2br_save_html($data['message']);
|
|
}
|
|
if (!isset($data['userid'])) {
|
|
$data['userid'] = 0;
|
|
}
|
|
// $data['message'] = remove_emojis($data['message']);
|
|
$data = hooks()->apply_filters('before_ticket_reply_add', $data, $id, $admin);
|
|
$this->db->insert(db_prefix() . ($playground ? 'playground_' : '') . 'ticket_replies', $data);
|
|
$insert_id = $this->db->insert_id();
|
|
if ($insert_id) {
|
|
/**
|
|
* When a ticket is in status "In progress" and the customer reply to the ticket
|
|
* it changes the status to "Open" which is not normal.
|
|
*
|
|
* The ticket should keep the status "In progress"
|
|
*/
|
|
$this->db->select('status');
|
|
$this->db->where('ticketid', $id);
|
|
$old_ticket_status = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'tickets')->row()->status;
|
|
$newStatus = hooks()->apply_filters('ticket_reply_status', ($old_ticket_status == 2 && $admin == null ? $old_ticket_status : $status), ['ticket_id' => $id, 'reply_id' => $insert_id, 'admin' => $admin, 'old_status' => $old_ticket_status]);
|
|
if (isset($assigned)) {
|
|
$this->db->where('ticketid', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'tickets', ['assigned' => $assigned, ]);
|
|
}
|
|
if ($pipe_attachments != false) {
|
|
$this->process_pipe_attachments($pipe_attachments, $id, $insert_id, $playground);
|
|
} else {
|
|
$attachments = $this->handle_ticket_attachments($id, 'attachments', $playground);
|
|
if ($attachments) {
|
|
$this->insert_ticket_attachments_to_database($attachments, $id, $insert_id, $playground);
|
|
}
|
|
}
|
|
$_attachments = $this->get_ticket_attachments($id, $insert_id, $playground);
|
|
log_activity('New Ticket Reply [ReplyID: ' . $insert_id . ']');
|
|
$this->db->where('ticketid', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'tickets', ['lastreply' => date('Y-m-d H:i:s'), 'status' => $newStatus, 'adminread' => 0, 'clientread' => 0, ]);
|
|
if ($old_ticket_status != $newStatus) {
|
|
hooks()->do_action('after_ticket_status_changed', ['id' => $id, 'status' => $newStatus, ]);
|
|
}
|
|
$ticket = $this->get_ticket_by_id($id, '', $playground);
|
|
$userid = $ticket->userid;
|
|
$isContact = false;
|
|
$this->load->model('cilents_model');
|
|
if ($ticket->userid != 0 && $ticket->contactid != 0) {
|
|
$email = $cilents_model->get_contact($ticket->contactid, $playground)->email;
|
|
$isContact = true;
|
|
} else {
|
|
$email = $ticket->ticket_email;
|
|
}
|
|
if ($admin == null) {
|
|
$this->load->model('departments_model');
|
|
$notifiedUsers = [];
|
|
$staff = $this->getStaffMembersForTicketNotification($ticket->department, $ticket->assigned, $playground);
|
|
foreach ($staff as $staff_key => $member) {
|
|
send_mail_template('ticket_new_reply_to_staff', $ticket, $member, $_attachments);
|
|
if (get_option('receive_notification_on_new_ticket_replies') == 1) {
|
|
$notified = add_notification(['description' => 'not_new_ticket_reply', 'touserid' => $member['staffid'], 'fromcompany' => 1, 'fromuserid' => 0, 'link' => 'tickets/ticket/' . $id, 'additional_data' => serialize([$ticket->subject, ]), ]);
|
|
if ($notified) {
|
|
array_push($notifiedUsers, $member['staffid']);
|
|
}
|
|
}
|
|
}
|
|
pusher_trigger_notification($notifiedUsers);
|
|
} else {
|
|
$this->update_staff_replying($id, '', $playground);
|
|
$total_staff_replies = total_rows(db_prefix() . ($playground ? 'playground_' : '') . 'ticket_replies', ['admin is NOT NULL', 'ticketid' => $ticket->ticketid]);
|
|
if ($ticket->assigned == 0 && get_option('automatically_assign_ticket_to_first_staff_responding') == '1' && $total_staff_replies == 1) {
|
|
$this->db->where('ticketid', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'tickets', ['assigned' => $admin]);
|
|
}
|
|
$sendEmail = true;
|
|
if ($isContact && total_rows(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', ['ticket_emails' => 1, 'id' => $ticket->contactid]) == 0) {
|
|
$sendEmail = false;
|
|
}
|
|
if ($sendEmail) {
|
|
send_mail_template('ticket_new_reply_to_customer', $ticket, $email, $_attachments, $cc);
|
|
}
|
|
}
|
|
if ($cc) {
|
|
// imported reply
|
|
if (is_array($cc)) {
|
|
if ($ticket->cc) {
|
|
$currentCC = explode(',', $ticket->cc);
|
|
$cc = array_unique([$cc, $currentCC]);
|
|
}
|
|
$cc = implode(',', $cc);
|
|
}
|
|
$this->db->where('ticketid', $id);
|
|
$this->db->update(($playground ? 'playground_' : '') . 'tickets', ['cc' => $cc]);
|
|
}
|
|
hooks()->do_action('after_ticket_reply_added', ['data' => $data, 'id' => $id, 'admin' => $admin, 'replyid' => $insert_id, ]);
|
|
return $insert_id;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Delete ticket reply
|
|
* @param mixed $ticket_id ticket id
|
|
* @param mixed $reply_id reply id
|
|
* @return boolean
|
|
*/
|
|
public function delete_ticket_reply($ticket_id, $reply_id, $playground = false) {
|
|
hooks()->do_action('before_delete_ticket_reply', ['ticket_id' => $ticket_id, 'reply_id' => $reply_id]);
|
|
$this->db->where('id', $reply_id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'ticket_replies');
|
|
if ($this->db->affected_rows() > 0) {
|
|
// Get the reply attachments by passing the reply_id to get_ticket_attachments method
|
|
$attachments = $this->get_ticket_attachments($ticket_id, $reply_id, $playground);
|
|
if (count($attachments) > 0) {
|
|
foreach ($attachments as $attachment) {
|
|
$this->delete_ticket_attachment($attachment['id'], $playground);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Remove ticket attachment by id
|
|
* @param mixed $id attachment id
|
|
* @return boolean
|
|
*/
|
|
public function delete_ticket_attachment($id, $playground = false) {
|
|
$deleted = false;
|
|
$this->db->where('id', $id);
|
|
$attachment = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'ticket_attachments')->row();
|
|
$this->load->model('misc_model');
|
|
if ($attachment) {
|
|
if (unlink($this->misc_model->get_upload_path_by_type('ticket', $playground) . $attachment->ticketid . '/' . $attachment->file_name)) {
|
|
$this->db->where('id', $attachment->id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'ticket_attachments');
|
|
$deleted = true;
|
|
}
|
|
// Check if no attachments left, so we can delete the folder also
|
|
$other_attachments = list_files($this->misc_model->get_upload_path_by_type('ticket', $playground) . $attachment->ticketid);
|
|
if (count($other_attachments) == 0) {
|
|
delete_dir($this->misc_model->get_upload_path_by_type('ticket', $playground) . $attachment->ticketid);
|
|
}
|
|
}
|
|
return $deleted;
|
|
}
|
|
|
|
/**
|
|
* Get ticket attachment by id
|
|
* @param mixed $id attachment id
|
|
* @return mixed
|
|
*/
|
|
public function get_ticket_attachment($id, $playground = false) {
|
|
$this->db->where('id', $id);
|
|
return $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'ticket_attachments')->row();
|
|
}
|
|
|
|
/**
|
|
* This functions is used when staff open client ticket
|
|
* @param mixed $userid client id
|
|
* @param mixed $id ticketid
|
|
* @return array
|
|
*/
|
|
public function get_user_other_tickets($userid, $id, $playground = false) {
|
|
$this->db->select(db_prefix() . ($playground ? 'playground_' : '') . 'departments.name as department_name, ' . db_prefix() . ($playground ? 'playground_' : '') . 'services.name as service_name,' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets_status.name as status_name,' . db_prefix() . ($playground ? 'playground_' : '') . 'staff.firstname as staff_firstname, ' . db_prefix() . ($playground ? 'playground_' : '') . 'clients.lastname as staff_lastname,ticketid,subject,firstname,lastname,lastreply');
|
|
$this->db->from(db_prefix() . ($playground ? 'playground_' : '') . 'tickets');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'departments', db_prefix() . ($playground ? 'playground_' : '') . 'departments.departmentid = ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.department', 'left');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_status', db_prefix() . ($playground ? 'playground_' : '') . 'tickets_status.ticketstatusid = ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.status', 'left');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'services', db_prefix() . ($playground ? 'playground_' : '') . 'services.serviceid = ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.service', 'left');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'clients', db_prefix() . ($playground ? 'playground_' : '') . 'clients.userid = ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.userid', 'left');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'staff', db_prefix() . ($playground ? 'playground_' : '') . 'staff.staffid = ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.admin', 'left');
|
|
$this->db->where(db_prefix() . ($playground ? 'playground_' : '') . 'tickets.userid', $userid);
|
|
$this->db->where(db_prefix() . ($playground ? 'playground_' : '') . 'tickets.ticketid !=', $id);
|
|
$tickets = $this->db->get()->result_array();
|
|
$i = 0;
|
|
foreach ($tickets as $ticket) {
|
|
$tickets[$i]['submitter'] = $ticket['firstname'] . ' ' . $ticket['lastname'];
|
|
unset($ticket['firstname']);
|
|
unset($ticket['lastname']);
|
|
$i++;
|
|
}
|
|
return $tickets;
|
|
}
|
|
|
|
/**
|
|
* Get all ticket replies
|
|
* @param mixed $id ticketid
|
|
* @param mixed $userid specific client id
|
|
* @return array
|
|
*/
|
|
public function get_ticket_replies($id, $playground = false) {
|
|
$ticket_replies_order = get_option('ticket_replies_order');
|
|
// backward compatibility for the action hook
|
|
$ticket_replies_order = hooks()->apply_filters('ticket_replies_order', $ticket_replies_order);
|
|
$this->db->select(db_prefix() . ($playground ? 'playground_' : '') . 'ticket_replies.id,' . db_prefix() . ($playground ? 'playground_' : '') . 'ticket_replies.name as from_name,' . db_prefix() . ($playground ? 'playground_' : '') . 'ticket_replies.email as reply_email, ' . db_prefix() . ($playground ? 'playground_' : '') . 'ticket_replies.admin, ' . db_prefix() . ($playground ? 'playground_' : '') . 'ticket_replies.userid,' . db_prefix() . ($playground ? 'playground_' : '') . 'staff.firstname as staff_firstname, ' . db_prefix() . ($playground ? 'playground_' : '') . 'staff.lastname as staff_lastname,' . db_prefix() . ($playground ? 'playground_' : '') . 'contacts.firstname as user_firstname,' . db_prefix() . ($playground ? 'playground_' : '') . 'contacts.lastname as user_lastname,message,date,contactid');
|
|
$this->db->from(db_prefix() . ($playground ? 'playground_' : '') . 'ticket_replies');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'clients', db_prefix() . ($playground ? 'playground_' : '') . 'clients.userid = ' . db_prefix() . ($playground ? 'playground_' : '') . 'ticket_replies.userid', 'left');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'staff', db_prefix() . ($playground ? 'playground_' : '') . 'staff.staffid = ' . db_prefix() . ($playground ? 'playground_' : '') . 'ticket_replies.admin', 'left');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', db_prefix() . ($playground ? 'playground_' : '') . 'contacts.id = ' . db_prefix() . ($playground ? 'playground_' : '') . 'ticket_replies.contactid', 'left');
|
|
$this->db->where('ticketid', $id);
|
|
$this->db->order_by('date', $ticket_replies_order);
|
|
$replies = $this->db->get()->result_array();
|
|
$i = 0;
|
|
foreach ($replies as $reply) {
|
|
if ($reply['admin'] !== null || $reply['admin'] != 0) {
|
|
// staff reply
|
|
$replies[$i]['submitter'] = $reply['staff_firstname'] . ' ' . $reply['staff_lastname'];
|
|
} else {
|
|
if ($reply['contactid'] != 0) {
|
|
$replies[$i]['submitter'] = $reply['user_firstname'] . ' ' . $reply['user_lastname'];
|
|
} else {
|
|
$replies[$i]['submitter'] = $reply['from_name'];
|
|
}
|
|
}
|
|
unset($replies[$i]['staff_firstname']);
|
|
unset($replies[$i]['staff_lastname']);
|
|
unset($replies[$i]['user_firstname']);
|
|
unset($replies[$i]['user_lastname']);
|
|
$replies[$i]['attachments'] = $this->get_ticket_attachments($id, $reply['id'], $playground);
|
|
$i++;
|
|
}
|
|
return $replies;
|
|
}
|
|
|
|
/**
|
|
* Add new ticket to database
|
|
* @param mixed $data ticket $_POST data
|
|
* @param mixed $admin If admin adding the ticket passed staff id
|
|
*/
|
|
public function add($data, $admin = null, $pipe_attachments = false, $playground = false) {
|
|
if ($admin !== null) {
|
|
$data['admin'] = $admin;
|
|
unset($data['ticket_client_search']);
|
|
}
|
|
if (isset($data['assigned']) && $data['assigned'] == '') {
|
|
$data['assigned'] = 0;
|
|
}
|
|
if (isset($data['project_id']) && $data['project_id'] == '') {
|
|
$data['project_id'] = 0;
|
|
}
|
|
if ($admin == null) {
|
|
if (isset($data['email'])) {
|
|
$data['userid'] = 0;
|
|
$data['contactid'] = 0;
|
|
} else {
|
|
// Opened from customer portal otherwise is passed from pipe or admin area
|
|
if (!isset($data['userid']) && !isset($data['contactid'])) {
|
|
$data['userid'] = get_client_user_id();
|
|
$data['contactid'] = get_contact_user_id();
|
|
}
|
|
}
|
|
$data['status'] = 1;
|
|
}
|
|
if (isset($data['custom_fields'])) {
|
|
$custom_fields = $data['custom_fields'];
|
|
unset($data['custom_fields']);
|
|
}
|
|
// CC is only from admin area
|
|
$cc = '';
|
|
if (isset($data['cc'])) {
|
|
$cc = $data['cc'];
|
|
unset($data['cc']);
|
|
}
|
|
$data['date'] = date('Y-m-d H:i:s');
|
|
$data['ticketkey'] = app_generate_hash();
|
|
$data['status'] = 1;
|
|
$data['message'] = trim($data['message']);
|
|
$data['subject'] = trim($data['subject']);
|
|
// if ($this->piping == true) {
|
|
// $data['message'] = preg_replace('/\v+/u', '<br>', $data['message']);
|
|
// }
|
|
$is_html_stripped = $this->piping === true;
|
|
// Admin can have html
|
|
if (!$is_html_stripped && $admin == null && hooks()->apply_filters('ticket_message_without_html_for_non_admin', true)) {
|
|
$data['message'] = _strip_tags($data['message']);
|
|
$data['subject'] = _strip_tags($data['subject']);
|
|
$data['message'] = nl2br_save_html($data['message']);
|
|
}
|
|
if (!isset($data['userid'])) {
|
|
$data['userid'] = 0;
|
|
}
|
|
if (isset($data['priority']) && $data['priority'] == '' || !isset($data['priority'])) {
|
|
$data['priority'] = 0;
|
|
}
|
|
$tags = '';
|
|
if (isset($data['tags'])) {
|
|
$tags = $data['tags'];
|
|
unset($data['tags']);
|
|
}
|
|
// $data['message'] = remove_emojis($data['message']);
|
|
$data = hooks()->apply_filters('before_ticket_created', $data, $admin);
|
|
$this->db->insert(db_prefix() . ($playground ? 'playground_' : '') . 'tickets', $data);
|
|
$ticketid = $this->db->insert_id();
|
|
if ($ticketid) {
|
|
$this->load->model('misc_model');
|
|
$this->misc_model->handle_tags_save($tags, $ticketid, 'ticket');
|
|
if (isset($custom_fields)) {
|
|
$this->load->model('custom_fields_model');
|
|
$this->custom_fields_model->handle_custom_fields_post($ticketid, $custom_fields, $playground);
|
|
}
|
|
if (isset($data['assigned']) && $data['assigned'] != 0) {
|
|
if ($data['assigned'] != get_staff_user_id()) {
|
|
$notified = add_notification(['description' => 'not_ticket_assigned_to_you', 'touserid' => $data['assigned'], 'fromcompany' => 1, 'fromuserid' => 0, 'link' => 'tickets/ticket/' . $ticketid, 'additional_data' => serialize([$data['subject'], ]), ]);
|
|
if ($notified) {
|
|
pusher_trigger_notification([$data['assigned']]);
|
|
}
|
|
send_mail_template('ticket_assigned_to_staff', get_staff($data['assigned'])->email, $data['assigned'], $ticketid, $data['userid'], $data['contactid']);
|
|
}
|
|
}
|
|
if ($pipe_attachments != false) {
|
|
$this->process_pipe_attachments($pipe_attachments, $ticketid, $playground);
|
|
} else {
|
|
$attachments = $this->handle_ticket_attachments($ticketid, 'attachments', $playground);
|
|
if ($attachments) {
|
|
$this->insert_ticket_attachments_to_database($attachments, $ticketid, false, $playground);
|
|
}
|
|
}
|
|
$_attachments = $this->get_ticket_attachments($ticketid, '', $playground);
|
|
$isContact = false;
|
|
if (isset($data['userid']) && $data['userid'] != false) {
|
|
$this->load->model('cilents_model');
|
|
$email = $this->clients_model->get_contact($data['contactid'], ['active' => 1], [], $playground)->email;
|
|
$isContact = true;
|
|
} else {
|
|
$email = $data['email'];
|
|
}
|
|
$template = 'ticket_created_to_customer';
|
|
if ($admin == null) {
|
|
$template = 'ticket_autoresponse';
|
|
$notifiedUsers = [];
|
|
$staffToNotify = $this->getStaffMembersForTicketNotification($data['department'], $data['assigned'] ?? 0, $playground);
|
|
foreach ($staffToNotify as $member) {
|
|
send_mail_template('ticket_created_to_staff', $ticketid, $data['userid'], $data['contactid'], $member, $_attachments);
|
|
if (get_option('receive_notification_on_new_ticket') == 1) {
|
|
$notified = add_notification(['description' => 'not_new_ticket_created', 'touserid' => $member['staffid'], 'fromcompany' => 1, 'fromuserid' => 0, 'link' => 'tickets/ticket/' . $ticketid, 'additional_data' => serialize([$data['subject'], ]), ]);
|
|
if ($notified) {
|
|
$notifiedUsers[] = $member['staffid'];
|
|
}
|
|
}
|
|
}
|
|
pusher_trigger_notification($notifiedUsers);
|
|
} else {
|
|
if ($cc) {
|
|
$this->db->where('ticketid', $ticketid);
|
|
$this->db->update(($playground ? 'playground_' : '') . 'tickets', ['cc' => is_array($cc) ? implode(',', $cc) : $cc]);
|
|
}
|
|
}
|
|
$sendEmail = true;
|
|
if ($isContact && total_rows(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', ['ticket_emails' => 1, 'id' => $data['contactid']]) == 0) {
|
|
$sendEmail = false;
|
|
}
|
|
if ($sendEmail) {
|
|
$ticket = $this->get_ticket_by_id($ticketid, '', $playground);
|
|
// $admin == null ? [] : $_attachments - Admin opened ticket from admin area add the attachments to the email
|
|
send_mail_template($template, $ticket, $email, $admin == null ? [] : $_attachments, $cc);
|
|
}
|
|
hooks()->do_action('ticket_created', $ticketid);
|
|
log_activity('New Ticket Created [ID: ' . $ticketid . ']');
|
|
return $ticketid;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Get latest 5 client tickets
|
|
* @param integer $limit Optional limit tickets
|
|
* @param mixed $userid client id
|
|
* @return array
|
|
*/
|
|
public function get_client_latests_ticket($limit = 5, $userid = '', $playground = false) {
|
|
$this->db->select(db_prefix() . ($playground ? 'playground_' : '') . 'tickets.userid, ticketstatusid, statuscolor, ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets_status.name as status_name,' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.ticketid, subject, date');
|
|
$this->db->from(db_prefix() . ($playground ? 'playground_' : '') . 'tickets');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_status', db_prefix() . ($playground ? 'playground_' : '') . 'tickets_status.ticketstatusid = ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets.status', 'left');
|
|
if (is_numeric($userid)) {
|
|
$this->db->where(db_prefix() . ($playground ? 'playground_' : '') . 'tickets.userid', $userid);
|
|
} else {
|
|
$this->db->where(db_prefix() . ($playground ? 'playground_' : '') . 'tickets.userid', get_client_user_id());
|
|
}
|
|
$this->db->limit($limit);
|
|
$this->db->where(db_prefix() . ($playground ? 'playground_' : '') . 'tickets.merged_ticket_id IS NULL', null, false);
|
|
return $this->db->get()->result_array();
|
|
}
|
|
|
|
/**
|
|
* Delete ticket from database and all connections
|
|
* @param mixed $ticketid ticketid
|
|
* @return boolean
|
|
*/
|
|
public function delete($ticketid, $playground = false) {
|
|
$affectedRows = 0;
|
|
hooks()->do_action('before_ticket_deleted', $ticketid);
|
|
// final delete ticket
|
|
$this->db->where('ticketid', $ticketid);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'tickets');
|
|
if ($this->db->affected_rows() > 0) {
|
|
$affectedRows++;
|
|
}
|
|
$this->load->model('misc_model');
|
|
if ($this->db->affected_rows() > 0) {
|
|
$affectedRows++;
|
|
$this->db->where('merged_ticket_id', $ticketid);
|
|
$this->db->set('merged_ticket_id', null);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'tickets');
|
|
$this->db->where('ticketid', $ticketid);
|
|
$attachments = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'ticket_attachments')->result_array();
|
|
if (count($attachments) > 0) {
|
|
if (is_dir($this->misc_model->get_upload_path_by_type('ticket', $playground) . $ticketid)) {
|
|
if (delete_dir($this->misc_model->get_upload_path_by_type('ticket', $playground) . $ticketid)) {
|
|
foreach ($attachments as $attachment) {
|
|
$this->db->where('id', $attachment['id']);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'ticket_attachments');
|
|
if ($this->db->affected_rows() > 0) {
|
|
$affectedRows++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
$this->db->where('relid', $ticketid);
|
|
$this->db->where('fieldto', 'tickets');
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'customfieldsvalues');
|
|
// Delete replies
|
|
$this->db->where('ticketid', $ticketid);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'ticket_replies');
|
|
$this->db->where('rel_id', $ticketid);
|
|
$this->db->where('rel_type', 'ticket');
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'notes');
|
|
$this->db->where('rel_id', $ticketid);
|
|
$this->db->where('rel_type', 'ticket');
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'taggables');
|
|
$this->db->where('rel_type', 'ticket');
|
|
$this->db->where('rel_id', $ticketid);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'reminders');
|
|
// Get related tasks
|
|
$this->db->where('rel_type', 'ticket');
|
|
$this->db->where('rel_id', $ticketid);
|
|
$tasks = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'tasks')->result_array();
|
|
$this->load->model('tasks_model');
|
|
foreach ($tasks as $task) {
|
|
$this->tasks_model->delete_task($task['id'], true, $playground);
|
|
}
|
|
}
|
|
if ($affectedRows > 0) {
|
|
log_activity('Ticket Deleted [ID: ' . $ticketid . ']');
|
|
hooks()->do_action('after_ticket_deleted', $ticketid);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Update ticket data / admin use
|
|
* @param mixed $data ticket $_POST data
|
|
* @return boolean
|
|
*/
|
|
public function update_single_ticket_settings($data, $playground = false) {
|
|
$affectedRows = 0;
|
|
$data = hooks()->apply_filters('before_ticket_settings_updated', $data);
|
|
$ticketBeforeUpdate = $this->get_ticket_by_id($data['ticketid'], '', $playground);
|
|
if (isset($data['merge_ticket_ids'])) {
|
|
$tickets = explode(',', $data['merge_ticket_ids']);
|
|
if ($this->merge($data['ticketid'], $ticketBeforeUpdate->status, $tickets)) {
|
|
$affectedRows++;
|
|
}
|
|
unset($data['merge_ticket_ids']);
|
|
}
|
|
if (isset($data['custom_fields']) && count($data['custom_fields']) > 0) {
|
|
$this->load->model('custom_fields_model');
|
|
if ($this->custom_fields_model->handle_custom_fields_post($data['ticketid'], $data['custom_fields'])) {
|
|
$affectedRows++;
|
|
}
|
|
unset($data['custom_fields']);
|
|
}
|
|
$tags = '';
|
|
if (isset($data['tags'])) {
|
|
$tags = $data['tags'];
|
|
unset($data['tags']);
|
|
}
|
|
$this->load->model('misc_model');
|
|
if ($this->misc_model->handle_tags_save($tags, $data['ticketid'], 'ticket')) {
|
|
$affectedRows++;
|
|
}
|
|
if (isset($data['priority']) && $data['priority'] == '' || !isset($data['priority'])) {
|
|
$data['priority'] = 0;
|
|
}
|
|
if ($data['assigned'] == '') {
|
|
$data['assigned'] = 0;
|
|
}
|
|
if (isset($data['project_id']) && $data['project_id'] == '') {
|
|
$data['project_id'] = 0;
|
|
}
|
|
if (isset($data['contactid']) && $data['contactid'] != '') {
|
|
$data['name'] = null;
|
|
$data['email'] = null;
|
|
}
|
|
$this->db->where('ticketid', $data['ticketid']);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'tickets', $data);
|
|
if ($this->db->affected_rows() > 0) {
|
|
hooks()->do_action('ticket_settings_updated', ['ticket_id' => $data['ticketid'], 'original_ticket' => $ticketBeforeUpdate, 'data' => $data, ]);
|
|
$affectedRows++;
|
|
}
|
|
$sendAssignedEmail = false;
|
|
$current_assigned = $ticketBeforeUpdate->assigned;
|
|
if ($current_assigned != 0) {
|
|
if ($current_assigned != $data['assigned']) {
|
|
if ($data['assigned'] != 0 && $data['assigned'] != get_staff_user_id()) {
|
|
$sendAssignedEmail = true;
|
|
$notified = add_notification(['description' => 'not_ticket_reassigned_to_you', 'touserid' => $data['assigned'], 'fromcompany' => 1, 'fromuserid' => 0, 'link' => 'tickets/ticket/' . $data['ticketid'], 'additional_data' => serialize([$data['subject'], ]), ]);
|
|
if ($notified) {
|
|
pusher_trigger_notification([$data['assigned']]);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if ($data['assigned'] != 0 && $data['assigned'] != get_staff_user_id()) {
|
|
$sendAssignedEmail = true;
|
|
$notified = add_notification(['description' => 'not_ticket_assigned_to_you', 'touserid' => $data['assigned'], 'fromcompany' => 1, 'fromuserid' => 0, 'link' => 'tickets/ticket/' . $data['ticketid'], 'additional_data' => serialize([$data['subject'], ]), ]);
|
|
if ($notified) {
|
|
pusher_trigger_notification([$data['assigned']]);
|
|
}
|
|
}
|
|
}
|
|
if ($sendAssignedEmail === true) {
|
|
$this->db->where('staffid', $data['assigned']);
|
|
$assignedEmail = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'staff')->row()->email;
|
|
send_mail_template('ticket_assigned_to_staff', $assignedEmail, $data['assigned'], $data['ticketid'], $data['userid'], $data['contactid']);
|
|
}
|
|
if ($affectedRows > 0) {
|
|
log_activity('Ticket Updated [ID: ' . $data['ticketid'] . ']');
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* C<ha></ha>nge ticket status
|
|
* @param mixed $id ticketid
|
|
* @param mixed $status status id
|
|
* @return array
|
|
*/
|
|
public function change_ticket_status($id, $status, $playground = false) {
|
|
$this->db->where('ticketid', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'tickets', ['status' => $status, ]);
|
|
$alert = 'warning';
|
|
$message = _l('ticket_status_changed_fail');
|
|
if ($this->db->affected_rows() > 0) {
|
|
$alert = 'success';
|
|
$message = _l('ticket_status_changed_successfully');
|
|
hooks()->do_action('after_ticket_status_changed', ['id' => $id, 'status' => $status, ]);
|
|
}
|
|
return ['alert' => $alert, 'message' => $message, ];
|
|
}
|
|
|
|
// Priorities
|
|
|
|
/**
|
|
* Get ticket priority by id
|
|
* @param mixed $id priority id
|
|
* @return mixed if id passed return object else array
|
|
*/
|
|
public function get_priority($id = '', $playground = false) {
|
|
if (is_numeric($id)) {
|
|
$this->db->where('priorityid', $id);
|
|
return $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_priorities')->row();
|
|
}
|
|
return $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_priorities')->result_array();
|
|
}
|
|
|
|
/**
|
|
* Add new ticket priority
|
|
* @param array $data ticket priority data
|
|
*/
|
|
public function add_priority($data, $playground = false) {
|
|
$this->db->insert(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_priorities', $data);
|
|
$insert_id = $this->db->insert_id();
|
|
if ($insert_id) {
|
|
log_activity('New Ticket Priority Added [ID: ' . $insert_id . ', Name: ' . $data['name'] . ']');
|
|
}
|
|
return $insert_id;
|
|
}
|
|
|
|
/**
|
|
* Update ticket priority
|
|
* @param array $data ticket priority $_POST data
|
|
* @param mixed $id ticket priority id
|
|
* @return boolean
|
|
*/
|
|
public function update_priority($data, $id, $playground = false) {
|
|
$this->db->where('priorityid', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_priorities', $data);
|
|
if ($this->db->affected_rows() > 0) {
|
|
log_activity('Ticket Priority Updated [ID: ' . $id . ' Name: ' . $data['name'] . ']');
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Delete ticket priorit
|
|
* @param mixed $id ticket priority id
|
|
* @return mixed
|
|
*/
|
|
public function delete_priority($id, $playground = false) {
|
|
$current = $this->get($id, [], $playground);
|
|
// Check if the priority id is used in tickets table
|
|
if (is_reference_in_table('priority', db_prefix() . ($playground ? 'playground_' : '') . 'tickets', $id)) {
|
|
return ['referenced' => true, ];
|
|
}
|
|
$this->db->where('priorityid', $id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_priorities');
|
|
if ($this->db->affected_rows() > 0) {
|
|
if (get_option('email_piping_default_priority') == $id) {
|
|
update_option('email_piping_default_priority', '');
|
|
}
|
|
log_activity('Ticket Priority Deleted [ID: ' . $id . ']');
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Predefined replies
|
|
|
|
/**
|
|
* Get predefined reply by id
|
|
* @param mixed $id predefined reply id
|
|
* @return mixed if id passed return object else array
|
|
*/
|
|
public function get_predefined_reply($id = '', $playground = false) {
|
|
if (is_numeric($id)) {
|
|
$this->db->where('id', $id);
|
|
return $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_predefined_replies')->row();
|
|
}
|
|
return $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_predefined_replies')->result_array();
|
|
}
|
|
|
|
/**
|
|
* Add new predefined reply
|
|
* @param array $data predefined reply $_POST data
|
|
*/
|
|
public function add_predefined_reply($data, $playground = false) {
|
|
$this->db->insert(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_predefined_replies', $data);
|
|
$insertid = $this->db->insert_id();
|
|
log_activity('New Predefined Reply Added [ID: ' . $insertid . ', ' . $data['name'] . ']');
|
|
return $insertid;
|
|
}
|
|
|
|
/**
|
|
* Update predefined reply
|
|
* @param array $data predefined $_POST data
|
|
* @param mixed $id predefined reply id
|
|
* @return boolean
|
|
*/
|
|
public function update_predefined_reply($data, $id, $playground = false) {
|
|
$this->db->where('id', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_predefined_replies', $data);
|
|
if ($this->db->affected_rows() > 0) {
|
|
log_activity('Predefined Reply Updated [ID: ' . $id . ', ' . $data['name'] . ']');
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Delete predefined reply
|
|
* @param mixed $id predefined reply id
|
|
* @return boolean
|
|
*/
|
|
public function delete_predefined_reply($id, $playground = false) {
|
|
$this->db->where('id', $id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_predefined_replies');
|
|
if ($this->db->affected_rows() > 0) {
|
|
log_activity('Predefined Reply Deleted [' . $id . ']');
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Ticket statuses
|
|
|
|
/**
|
|
* Get ticket status by id
|
|
* @param mixed $id status id
|
|
* @return mixed if id passed return object else array
|
|
*/
|
|
public function get_ticket_status($id = '', $playground = false) {
|
|
if (is_numeric($id)) {
|
|
$this->db->where('ticketstatusid', $id);
|
|
return $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_status')->row();
|
|
}
|
|
$this->db->order_by('statusorder', 'asc');
|
|
return $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_status')->result_array();
|
|
}
|
|
|
|
/**
|
|
* Add new ticket status
|
|
* @param array ticket status $_POST data
|
|
* @return mixed
|
|
*/
|
|
public function add_ticket_status($data, $playground = false) {
|
|
$this->db->insert(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_status', $data);
|
|
$insert_id = $this->db->insert_id();
|
|
if ($insert_id) {
|
|
log_activity('New Ticket Status Added [ID: ' . $insert_id . ', ' . $data['name'] . ']');
|
|
return $insert_id;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Update ticket status
|
|
* @param array $data ticket status $_POST data
|
|
* @param mixed $id ticket status id
|
|
* @return boolean
|
|
*/
|
|
public function update_ticket_status($data, $id, $playground = false) {
|
|
$this->db->where('ticketstatusid', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_status', $data);
|
|
if ($this->db->affected_rows() > 0) {
|
|
log_activity('Ticket Status Updated [ID: ' . $id . ' Name: ' . $data['name'] . ']');
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Delete ticket status
|
|
* @param mixed $id ticket status id
|
|
* @return mixed
|
|
*/
|
|
public function delete_ticket_status($id, $playground = false) {
|
|
$current = $this->get_ticket_status($id, $playground);
|
|
// Default statuses cant be deleted
|
|
if ($current->isdefault == 1) {
|
|
return ['default' => true, ];
|
|
// Not default check if if used in table
|
|
|
|
} else if (is_reference_in_table('status', db_prefix() . ($playground ? 'playground_' : '') . 'tickets', $id)) {
|
|
return ['referenced' => true, ];
|
|
}
|
|
$this->db->where('ticketstatusid', $id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_status');
|
|
if ($this->db->affected_rows() > 0) {
|
|
log_activity('Ticket Status Deleted [ID: ' . $id . ']');
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Ticket services
|
|
public function get_service($id = '', $playground = false) {
|
|
if (is_numeric($id)) {
|
|
$this->db->where('serviceid', $id);
|
|
return $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'services')->row();
|
|
}
|
|
$this->db->order_by('name', 'asc');
|
|
return $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'services')->result_array();
|
|
}
|
|
|
|
public function add_service($data, $playground = false) {
|
|
$this->db->insert(db_prefix() . ($playground ? 'playground_' : '') . 'services', $data);
|
|
$insert_id = $this->db->insert_id();
|
|
if ($insert_id) {
|
|
log_activity('New Ticket Service Added [ID: ' . $insert_id . '.' . $data['name'] . ']');
|
|
}
|
|
return $insert_id;
|
|
}
|
|
|
|
public function update_service($data, $id, $playground = false) {
|
|
$this->db->where('serviceid', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'services', $data);
|
|
if ($this->db->affected_rows() > 0) {
|
|
log_activity('Ticket Service Updated [ID: ' . $id . ' Name: ' . $data['name'] . ']');
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public function delete_service($id, $playground = false) {
|
|
if (is_reference_in_table('service', db_prefix() . ($playground ? 'playground_' : '') . 'tickets', $id)) {
|
|
return ['referenced' => true, ];
|
|
}
|
|
$this->db->where('serviceid', $id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'services');
|
|
if ($this->db->affected_rows() > 0) {
|
|
log_activity('Ticket Service Deleted [ID: ' . $id . ']');
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
* Used in home dashboard page
|
|
* Displays weekly ticket openings statistics (chart)
|
|
*/
|
|
public function get_weekly_tickets_opening_statistics($playground = false) {
|
|
$departments_ids = [];
|
|
if (!is_admin()) {
|
|
if (get_option('staff_access_only_assigned_departments') == 1) {
|
|
$this->load->model('departments_model');
|
|
$staff_deparments_ids = $this->departments_model->get_staff_departments(get_staff_user_id(), true, $playground);
|
|
$departments_ids = [];
|
|
if (count($staff_deparments_ids) == 0) {
|
|
$departments = $this->departments_model->get($playground);
|
|
foreach ($departments as $department) {
|
|
array_push($departments_ids, $department['departmentid']);
|
|
}
|
|
} else {
|
|
$departments_ids = $staff_deparments_ids;
|
|
}
|
|
}
|
|
}
|
|
$chart = ['labels' => get_weekdays(), 'datasets' => [['label' => _l('home_weekend_ticket_opening_statistics'), 'backgroundColor' => 'rgba(197, 61, 169, 0.5)', 'borderColor' => '#c53da9', 'borderWidth' => 1, 'tension' => false, 'data' => [0, 0, 0, 0, 0, 0, 0, ], ], ], ];
|
|
$monday = new DateTime(date('Y-m-d', strtotime('monday this week')));
|
|
$sunday = new DateTime(date('Y-m-d', strtotime('sunday this week')));
|
|
$thisWeekDays = get_weekdays_between_dates($monday, $sunday);
|
|
$byDepartments = count($departments_ids) > 0;
|
|
if (isset($thisWeekDays[1])) {
|
|
$i = 0;
|
|
foreach ($thisWeekDays[1] as $weekDate) {
|
|
$this->db->like('DATE(date)', $weekDate, 'after');
|
|
$this->db->where(db_prefix() . ($playground ? 'playground_' : '') . 'tickets.merged_ticket_id IS NULL', null, false);
|
|
if ($byDepartments) {
|
|
$this->db->where('department IN (SELECT departmentid FROM ' . db_prefix() . ($playground ? 'playground_' : '') . 'staff_departments WHERE departmentid IN (' . implode(',', $departments_ids) . ') AND staffid="' . get_staff_user_id() . '")');
|
|
}
|
|
$chart['datasets'][0]['data'][$i] = $this->db->count_all_results(db_prefix() . ($playground ? 'playground_' : '') . 'tickets');
|
|
$i++;
|
|
}
|
|
}
|
|
return $chart;
|
|
}
|
|
|
|
public function get_tickets_assignes_disctinct($playground = false) {
|
|
return $this->db->query('SELECT DISTINCT(assigned) as assigned FROM ' . db_prefix() . ($playground ? 'playground_' : '') . 'tickets WHERE assigned != 0 AND merged_ticket_id IS NULL')->result_array();
|
|
}
|
|
|
|
/**
|
|
* Check for previous tickets opened by this email/contact and link to the contact
|
|
* @param string $email email to check for
|
|
* @param mixed $contact_id the contact id to transfer the tickets
|
|
* @return boolean
|
|
*/
|
|
public function transfer_email_tickets_to_contact($email, $contact_id, $playground = false) {
|
|
// Some users don't want to fill the email
|
|
if (empty($email)) {
|
|
return false;
|
|
}
|
|
$this->load->model('cilents_model');
|
|
$customer_id = $this->clients_model->get_user_id_by_contact_id($contact_id, $playground);
|
|
$this->db->where('userid', 0)->where('contactid', 0)->where('admin IS NULL')->where('email', $email);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'tickets', ['email' => null, 'name' => null, 'userid' => $customer_id, 'contactid' => $contact_id, ]);
|
|
$this->db->where('userid', 0)->where('contactid', 0)->where('admin IS NULL')->where('email', $email);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'ticket_replies', ['email' => null, 'name' => null, 'userid' => $customer_id, 'contactid' => $contact_id, ]);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check whether the given ticketid is already merged into another primary ticket
|
|
*
|
|
* @param int $id
|
|
*
|
|
* @return boolean
|
|
*/
|
|
public function is_merged($id, $playground = false) {
|
|
return total_rows(($playground ? 'playground_' : '') . 'tickets', "ticketid={$id} and merged_ticket_id IS NOT NULL") > 0;
|
|
}
|
|
|
|
/**
|
|
* @param $primary_ticket_id
|
|
* @param $status
|
|
* @param array $ids
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function merge($primary_ticket_id, $status, array $ids, $playground = false) {
|
|
if ($this->is_merged($primary_ticket_id, $playground)) {
|
|
return false;
|
|
}
|
|
if (($index = array_search($primary_ticket_id, $ids)) !== false) {
|
|
unset($ids[$index]);
|
|
}
|
|
if (count($ids) == 0) {
|
|
return false;
|
|
}
|
|
return (new MergeTickets($primary_ticket_id, $ids))->markPrimaryTicketAs($status)->merge();
|
|
}
|
|
|
|
/**
|
|
* @param array $tickets id's of tickets to check
|
|
* @return array
|
|
*/
|
|
public function get_already_merged_tickets($tickets, $playground = false) {
|
|
if (count($tickets) === 0) {
|
|
return [];
|
|
}
|
|
$alreadyMerged = [];
|
|
foreach ($tickets as $ticketId) {
|
|
if ($this->is_merged((int)$ticketId, $playground)) {
|
|
$alreadyMerged[] = $ticketId;
|
|
}
|
|
}
|
|
return $alreadyMerged;
|
|
}
|
|
|
|
/**
|
|
* @param $primaryTicketId
|
|
* @return array
|
|
*/
|
|
public function get_merged_tickets_by_primary_id($primaryTicketId, $playground = false) {
|
|
return $this->db->where('merged_ticket_id', $primaryTicketId)->get(db_prefix() . ($playground ? 'playground_' : '') . 'tickets')->result_array();
|
|
}
|
|
|
|
public function update_staff_replying($ticketId, $userId = '', $playground = false) {
|
|
$ticket = $this->get($ticketId, [], $playground);
|
|
if ($userId === '') {
|
|
return $this->db->where('ticketid', $ticketId)->set('staff_id_replying', null)->update(db_prefix() . ($playground ? 'playground_' : '') . 'tickets');
|
|
}
|
|
if ($ticket->staff_id_replying !== $userId && !is_null($ticket->staff_id_replying)) {
|
|
return false;
|
|
}
|
|
if ($ticket->staff_id_replying === $userId) {
|
|
return true;
|
|
}
|
|
return $this->db->where('ticketid', $ticketId)->set('staff_id_replying', $userId)->update(db_prefix() . ($playground ? 'playground_' : '') . 'tickets');
|
|
}
|
|
|
|
public function get_staff_replying($ticketId, $playground = false) {
|
|
$this->db->select('ticketid,staff_id_replying');
|
|
$this->db->where('ticketid', $ticketId);
|
|
return $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'tickets')->row();
|
|
}
|
|
|
|
private function getStaffMembersForTicketNotification($department, $assignedStaff = 0, $playground = false) {
|
|
$this->load->model('departments_model');
|
|
$this->load->model('staff_model');
|
|
$staffToNotify = [];
|
|
if ($assignedStaff != 0 && get_option('staff_related_ticket_notification_to_assignee_only') == 1) {
|
|
$member = $this->staff_model->get($assignedStaff, ['active' => 1], $playground);
|
|
if ($member) {
|
|
$staffToNotify[] = (array)$member;
|
|
}
|
|
} else {
|
|
$staff = $this->staff_model->get('', ['active' => 1], $playground);
|
|
foreach ($staff as $member) {
|
|
if (get_option('access_tickets_to_none_staff_members') == 0 && !is_staff_member($member['staffid'])) {
|
|
continue;
|
|
}
|
|
$staff_departments = $this->departments_model->get_staff_departments($member['staffid'], true, $playground);
|
|
if (in_array($department, $staff_departments)) {
|
|
$staffToNotify[] = $member;
|
|
}
|
|
}
|
|
}
|
|
return $staffToNotify;
|
|
}
|
|
|
|
/**
|
|
* Check for ticket attachment after inserting ticket to database
|
|
* @param mixed $ticketid
|
|
* @return mixed false if no attachment || array uploaded attachments
|
|
*/
|
|
public function handle_ticket_attachments($ticketid, $index_name = 'attachments', $playground = false) {
|
|
$hookData = hooks()->apply_filters('before_handle_ticket_attachment', [
|
|
'ticket_id' => $ticketid,
|
|
'index_name' => $index_name,
|
|
'uploaded_files' => [],
|
|
'handled_externally' => false, // e.g. module upload to s3
|
|
'files' => $_FILES
|
|
]);
|
|
if ($hookData['handled_externally']) {
|
|
return count($hookData['uploaded_files']) > 0 ? $hookData['uploaded_files'] : false;
|
|
}
|
|
$this->load->model('misc_model');
|
|
$path = $this->misc_model->get_upload_path_by_type('ticket', $playground) . $ticketid . '/';
|
|
$uploaded_files = [];
|
|
if (isset($_FILES[$index_name])) {
|
|
_file_attachments_index_fix($index_name);
|
|
for ($i = 0; $i < count($_FILES[$index_name]['name']); $i++) {
|
|
hooks()->do_action('before_upload_ticket_attachment', $ticketid);
|
|
if ($i <= get_option('maximum_allowed_ticket_attachments')) {
|
|
// Get the temp file path
|
|
$tmpFilePath = $_FILES[$index_name]['tmp_name'][$i];
|
|
// Make sure we have a filepath
|
|
if (!empty($tmpFilePath) && $tmpFilePath != '') {
|
|
// Getting file extension
|
|
$extension = strtolower(pathinfo($_FILES[$index_name]['name'][$i], PATHINFO_EXTENSION));
|
|
$allowed_extensions = explode(',', get_option('ticket_attachments_file_extensions'));
|
|
$allowed_extensions = array_map('trim', $allowed_extensions);
|
|
// Check for all cases if this extension is allowed
|
|
if (!in_array('.' . $extension, $allowed_extensions)) {
|
|
continue;
|
|
}
|
|
_maybe_create_upload_path($path);
|
|
$filename = unique_filename($path, $_FILES[$index_name]['name'][$i]);
|
|
$newFilePath = $path . $filename;
|
|
// Upload the file into the temp dir
|
|
if (move_uploaded_file($tmpFilePath, $newFilePath)) {
|
|
array_push($uploaded_files, ['file_name' => $filename, 'filetype' => $_FILES[$index_name]['type'][$i], ]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (count($uploaded_files) > 0) {
|
|
return $uploaded_files;
|
|
}
|
|
return false;
|
|
}
|
|
}
|