diff --git a/app/controllers/AttachmentController.php b/app/controllers/AttachmentController.php new file mode 100644 index 0000000..a0f934d --- /dev/null +++ b/app/controllers/AttachmentController.php @@ -0,0 +1,152 @@ +exists('SESSION.user')){ + $f3->reroute('/login'); + } + } + + // list attachments + public function index($f3){ + $this->check_access($f3); + + $ticket_id = (int) $f3->get('PARAMS.id'); + $db = $f3->get('DB'); + + // fetch attachments + + $attachments = $db->exec( + 'SELECT a.*, u.username + FROM attachments a + LEFT JOIN users u ON u.id = a.uploaded_by + WHERE a.ticket_id = ? + ORDER BY a.created_at DESC', + [$ticket_id] + ); + + $f3->set('ticket_id', $ticket_id); + $f3->set('attachments', $attachments); + + $f3->set('content', '../ui/views/attachment/index.html'); + // echo \Template::instance()->render('../ui/templates/layout.html'); + echo \Template::instance()->render($f3->get('content')); + } + + // handle file upload + public function upload($f3){ + $this->check_access($f3); + + $ticket_id = (int) $f3->get('PARAMS.id'); + $uploaded_by = $f3->get('SESSION.user.id'); + + if(!isset($_FILES['attachment']) || $_FILES['attachment']['error'] !== UPLOAD_ERR_OK){ + $f3->reroute('/ticket/'.$ticket_id.'/attachments'); + } + + $file_info = $_FILES['attachment']; + $original_name = $file_info['name']; + $tmp_path = $file_info['tmp_name']; + + // create a unique file path + $upload_dir = '../storage/attachments/tickets/'.$ticket_id.'/'; + if(!is_dir($upload_dir)){ + mkdir($upload_dir, 0777, true); + } + + // if file exists increment version + $db = $f3->get('DB'); + $existing = $db->exec( + 'SELECT * FROM attachments + WHERE ticket_id =? AND file_name = ? + ORDER BY version_number DESC + LIMIT 1', + [$ticket_id, $original_name] + ); + + $new_version = 1; + if($existing){ + $new_version = $existing[0]['version_number'] + 1; + } + + $final_path = $upload_dir.$new_version.'_'.$original_name; + + // move file + move_uploaded_file($tmp_path, $final_path); + + // store meta data in DB + $db->exec( + 'INSERT INTO attachments + (ticket_id, path, file_name, version_number, uploaded_by, created_at) + VALUES (?,?,?,?,?,NOW())', + [$ticket_id, $final_path, $original_name, $new_version, $uploaded_by] + ); + + $f3->reroute('/ticket/'.$ticket_id.''); + } + + // download attachment + public function download($f3){ + $this->check_access($f3); + + $attachment_id = (int) $f3->get('PARAMS.id'); + $db = $f3->get('DB'); + + $rows = $db->exec('SELECT * FROM attachments WHERE id = ?', [$attachment_id]); + + if(!$rows){ + $f3->error(404, "File not found"); + return; + } + + $attachment = $rows[0]; + $file_path = $attachment['path']; + $file_name = $attachment['file_name']; + + // validate file exists + if(!file_exists($file_path)){ + $f3->error(404, "File not found"); + return; + } + + // output headers for download + header('Content-Description: File Transfer'); + header('Content-Type: application/octet-stream'); + header('Content-Disposition: attachment; filename="'.basename($file_name).'"'); + header('Content-Length: '. filesize($file_path)); + + // flush headers + flush(); + + // read file + readfile($file_path); + exit; + } + + // delete an attachment + public function delete($f3){ + $this->check_access($f3); + + $attachment_id = (int) $f3->get('PARAMS.id'); + $current_user = $f3->get('SESSION.user'); + + $db = $f3->get('DB'); + + $rows = $db->exec('SELECT * FROM attachments WHERE id =? LIMIT 1', [$attachment_id]); + if(!$rows){ + $f3->error(404, "Attachment not found"); + return; + } + + $attachment = $rows[0]; + // TODO: role or ownership + + if(file_exists($attachment['path'])){ + unlink($attachment['path']); + } + + // remove DB row + $db->exec('DELETE FROM attachments WHERE id =?', [$attachment_id]); + } +} \ No newline at end of file