tp_servicedesk/app/controllers/AttachmentController.php
tp_dhu a852dccd8b - added interface - for CRUD, ensures all methods are present and aligned.
- added trait for checking authorisation with redirect stored in session to return - shows which controllers requires auth, adds check function
2025-02-17 01:21:16 +00:00

148 lines
4.1 KiB
PHP

<?php
class AttachmentController {
use RequiresAuth;
// 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]);
}
}