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 Name |
+ Uploaded By |
+ Created At |
+ Version |
+
+
+
+
+
+ |
+
+ |
+ {{ @attach.file_name }} |
+ {{ @attach.username }} |
+ {{ @attach.created_at }} |
+ {{ @attach.version_number }} |
+
+
+
+
+
+
+
+