From b2764a0f5840513fafa57a59abc3dbfb049e5252 Mon Sep 17 00:00:00 2001 From: tp_dhu Date: Sun, 16 Feb 2025 22:11:20 +0000 Subject: [PATCH] - refactored TicketController into protected functions - added custom fields to TicketController - attachment view --- app/controllers/TicketController.php | 238 +++++++++++++++++++++------ ui/views/attachment/index.html | 48 ++++++ 2 files changed, 237 insertions(+), 49 deletions(-) create mode 100644 ui/views/attachment/index.html diff --git a/app/controllers/TicketController.php b/app/controllers/TicketController.php index c290211..06596de 100644 --- a/app/controllers/TicketController.php +++ b/app/controllers/TicketController.php @@ -2,13 +2,6 @@ class TicketController { - protected function check_access($f3){ - if(!$f3->exists('SESSION.user')){ - // $f3->set('SESSION.error', 'You don\'t have permission for this ticket.'); - $f3->reroute('/login'); - } - } - // list all tickts public function index($f3){ $this->check_access($f3); @@ -35,24 +28,13 @@ class TicketController { $ticket_id = $f3->get('PARAMS.id'); $db = $f3->get('DB'); - $result = $db->exec( - 'SELECT t.*, u.username as created_by_name - FROM tickets t - LEFT JOIN users u ON t.created_by = u.id - WHERE t.id =? LIMIT 1', - [$ticket_id] - ); - - if(!$result){ - // no record - $f3->set('SESSION.error', 'Ticket not found.'); - $f3->reroute('/tickets'); - } - - $ticket = $result[0]; - $f3->set('ticket', $ticket); + $this->get_ticket($f3, $db, $ticket_id); + $this->get_child_tickets($f3, $db, $ticket_id); + $this->get_parent_tickets($f3, $db, $ticket_id); + $this->get_custom_fields($f3, $db, $ticket_id); // render + $f3->set('js', 'ticket_view.js'); $f3->set('content', '../ui/views/ticket/view.html'); echo \Template::instance()->render('../ui/templates/layout.html'); @@ -66,6 +48,7 @@ class TicketController { } // handle POST + // including custom forms public function create($f3){ $this->check_access($f3); @@ -84,39 +67,31 @@ class TicketController { [$title, $description, $priority, $status, $created_by] ); - $f3->reroute('/tickets'); - } + $ticket_id = $db->lastInserId(); - protected function get_ticket_check_edit_permission($f3){ + // custom fields + $meta_keys = $f3->get('POST.meta_key'); // eg ['department', 'category'] + $meta_values = $f3->get('POST.meta_value'); - $db = $f3->get('DB'); - - $ticket_id = $f3->get('PARAMS.id'); - $result = $db->exec('SELECT * FROM tickets WHERE id = ? LIMIT 1', [$ticket_id]); - - if(!$result){ - $f3->set('SESSION.error', 'Ticket not found.'); - $f3->reroute('/tickets'); + if(is_array($meta_keys) && is_array($meta_values)){ + foreach($meta_keys as $index => $key){ + $val = $meta_values[$index] ?? ''; + if(!empty($key) && $val !== ''){ + $db->exec( + 'INSERT INTO ticket_meta (ticket_id, meta_key, meta_value) + VALUES (?,?,?)', + [$ticket_id, $key, $val] + ); + } + } } - $ticket = $result[0]; - - // TODO: refine - $current_user = $f3->get('SESSION.user'); - $is_admin = (isset($current_user['role']) && $current_user['role'] == 'admin'); - $is_assigned = ($ticket['assigned_to'] == $current_user['id']); - - if(!$is_admin && !$is_assigned){ // should this be || - // if not assigned and not admin, disallow edit - $f3->set('SESSION.error', 'You do not have permission to edit this ticket.'); - $f3->reroute('/tickets'); - } - - return $ticket; - + // reroute to ticket + $f3->reroute('/ticket/'.$ticket_id); } // show edit form + // including custom forms public function editForm($f3){ $this->check_access($f3); @@ -127,6 +102,15 @@ class TicketController { $ticket = $this->get_ticket_check_edit_permission($f3); $f3->set('ticket', $ticket); + // fetch custom fields + $meta = $db->exec( + 'SELECT id, meta_key, meta_value + FROM ticket_meta + WHERE ticket_id = ?', + [$ticket_id] + ); + $f3->set('ticket_meta', $meta); + $f3->set('ticket', $ticket); $f3->set('content', '../ui/views/ticket/edit.html'); echo \Template::instance()->render('../ui/templates/layout.html'); @@ -155,7 +139,163 @@ class TicketController { [$title, $description, $priority, $status, $updated_by, 'NOW()', $ticket_id] ); + // handle custom fields + // 1. update existing custom fields + $meta_ids = $f3->get('POST.meta_id'); + $meta_keys = $f3->get('POST.meta_key'); + $meta_values = $f3->get('POST.meta_value'); + + if(is_array($meta_ids) && is_array($meta_keys) && is_array($meta_values)){ + foreach($meta_ids as $idx => $m_id){ + $m_key = $meta_keys[$idx] ?? ''; + $m_val = $meta_values[$idx] ?? ''; + + if(!empty($m_key) && $m_val !== ''){ + $db->exec( + 'UPDATE ticket_meta + SET meta_key = ?, meta_value=? + WHERE id = ? AND ticket_id = ?', + [$m_key, $m_val, $m_id, $ticket_id] + ); + } else { + // delete if the user cleared it + $db->exec( + 'DELETE FROM ticket_meta + WHERE id =? AND ticket_id = ?', + [$m_id, $ticket_id] + ); + } + } + } + + // 2. insert new fields + $new_keys = $f3->get('POST.new_meta_key'); + $new_values = $f3->get('POST.new_meta_value'); + if(is_array($new_keys) && is_array($new_values)){ + foreach($new_keys as $idx => $n_key){ + $n_val = $new_values[$idx] ?? ''; + if(!empty($n_key) && $n_val !== ''){ + $db->exec( + 'INSERT INTO ticket_meta (ticket_id, meta_key, meta_value) + VALUES (?,?,?)', + [$ticket_id, $n_key, $n_val] + ); + } + } + } + $f3->reroute('/ticket/' . $ticket_id); } + // subtask + public function addSubtask($f3){ + $this->check_access($f3); + + $parent_id = (int) $f3->get('PARAMS.id'); + $child_id = (int) $f3->get('POST.child_ticket_id'); + $db = $f3->get('DB'); + + // TODO check that both parent and child tickets exist + // ensure you don't link a ticket to itself, etc. + + // insert or ignore + $db->exec( + 'INSERT IGNORE INTO ticket_relations (parent_ticket_id, child_ticket_id) + VALUES (?, ?)', + [$parent_id, $child_id] + ); + $f3->reroute('/ticket/' . $parent_id); + } + + protected function check_access($f3){ + if(!$f3->exists('SESSION.user')){ + // $f3->set('SESSION.error', 'You don\'t have permission for this ticket.'); + $f3->reroute('/login'); + } + } + + protected function get_ticket_check_edit_permission($f3){ + + $db = $f3->get('DB'); + + $ticket_id = $f3->get('PARAMS.id'); + $result = $db->exec('SELECT * FROM tickets WHERE id = ? LIMIT 1', [$ticket_id]); + + if(!$result){ + $f3->set('SESSION.error', 'Ticket not found.'); + $f3->reroute('/tickets'); + } + + $ticket = $result[0]; + + // TODO: refine + $current_user = $f3->get('SESSION.user'); + $is_admin = (isset($current_user['role_name']) && $current_user['role_name'] == 'admin'); + $is_assigned = ($ticket['assigned_to'] == $current_user['id']); + + if(!$is_admin && !$is_assigned){ // should this be || + // if not assigned and not admin, disallow edit + $f3->set('SESSION.error', 'You do not have permission to edit this ticket.'); + $f3->reroute('/tickets'); + } + + return $ticket; + + } + + protected function get_ticket($f3, $db, $ticket_id){ + $result = $db->exec( + 'SELECT t.*, u.username as created_by_name + FROM tickets t + LEFT JOIN users u ON t.created_by = u.id + WHERE t.id =? LIMIT 1', + [$ticket_id] + ); + + if(!$result){ + // no record + $f3->set('SESSION.error', 'Ticket not found.'); + $f3->reroute('/tickets'); + } + + $ticket = $result[0]; + $f3->set('ticket', $ticket); + } + + protected function get_child_tickets($f3, $db, $ticket_id){ + $child_tickets = $db->exec( + 'SELECT c.* + FROM ticket_relations r + INNER JOIN tickets c ON r.child_ticket_id = c.id + WHERE r.parent_ticket_id = ?', + [$ticket_id]); + $f3->set('child_tickets', $child_tickets); + } + + protected function get_parent_tickets($f3, $db, $ticket_id){ + $parent_tickets = $db->exec( + 'SELECT p.* + FROM ticket_relations r + INNER JOIN tickets p ON r.parent_ticket_id = p.id + WHERE r.child_ticket_id = ?', + [$ticket_id] + ); + $f3->set('parent_tickets', $parent_tickets); + } + + protected function get_custom_fields($f3, $db, $ticket_id){ + $meta = $db->exec( + 'SELECT meta_key, meta_value + FROM ticket_meta + WHERE ticket_id = ?', + [$ticket_id] + ); + // convert meta rows into assoc array + $meta_array = []; + foreach($meta as $m){ + $meta_array[$m['meta_key']] = $m['meta_value']; + } + $f3->set('ticket_meta', $meta_array); + } + } \ No newline at end of file diff --git a/ui/views/attachment/index.html b/ui/views/attachment/index.html new file mode 100644 index 0000000..b2a1236 --- /dev/null +++ b/ui/views/attachment/index.html @@ -0,0 +1,48 @@ +
+
+

Attachments

+
+ + + + + + + + + + + + + + + + + + + + + + +
File NameUploaded ByCreated AtVersion
+ + {{ @attach.file_name }}{{ @attach.username }}{{ @attach.created_at }}{{ @attach.version_number }}
+
+
+

Upload attachment

+
+
+
+ + + + +
+
+ +
+
+
+
+
+