tp_servicedesk/app/controllers/TicketController.php
2025-05-10 15:26:21 +01:00

265 lines
9.0 KiB
PHP

<?php
class TicketController extends BaseController implements CRUD {
use RequiresAuth, CheckCSRF;
// list all tickts
public function index($f3){
$this->requireLogin();
$filter = $f3->get('GET.status');
// retrieve tickets
$ticket_mapper = new Ticket($this->getDB());
if($filter){
$tickets = $ticket_mapper->findFiltered($filter);
} else {
$tickets = $ticket_mapper->findAll();
}
// render
$this->renderView('views/ticket/index.html',
['tickets' => $tickets]
);
$f3->clear('SESSION.error');
}
// view a single ticket
// TODO_PROJECTS: show a link back to the related project
public function view($f3){
$this->requireLogin();
$ticket_id = $f3->get('PARAMS.id');
$ticket_mapper = new Ticket($this->getDB());
$ticket = $ticket_mapper->findById($ticket_id);
if(!$ticket){
$this->f3->set('SESSION.error', 'Ticket not found');
$this->f3->reroute('/tickets');
return;
}
$assigned_user = $ticket->getAssignedUser();
$ticket_history = $ticket->getHistory();
$map_statuses = array_column((new TicketStatus($this->getDB()))->findAll(), 'name', 'id');
$map_priorities = array_column((new TicketStatus($this->getDB()))->findAll(), 'name', 'id');
$map_users = array_column($this->getDB()->exec('SELECT id, display_name FROM users'), 'display_name', 'id');
// render
$this->renderView('views/ticket/view.html', [
'ticket' => $ticket,
'assigned_user' => $assigned_user,
'attachments' => $ticket->attachments(),
'comments' => $ticket->comments(),
'parent_tickets' => $ticket->getParentTickets(),
'child_tickets' => $ticket->getChildTickets(),
'ticket_meta' => $ticket->getMetaAssoc(),
'ticket_history' => $ticket_history,
'map' => [
'statuses' => $map_statuses,
'priorities' => $map_priorities,
'users' => $map_users
]
]);
}
// show create form
// TODO_PROJECTS: dropdown to associate ticket with project
public function createForm($f3){
$db = $this->getDB();
$priorities = (new TicketPriority($db))->findAll();
$statuses = (new TicketStatus($db))->findAll();
$all_tags_model = new \Tag($this->getDB());
$all_tags = $all_tags_model->find([], ['order' => 'name ASC']); // get all tags
// TODO: this needs moving into a model?
$users = $this->getDB()->exec('SELECT id, username, display_name FROM users ORDER BY display_name ASC');
$users = array_merge([['id'=>'-1', 'display_name'=>'--']], $users);
$this->requireLogin();
$this->renderView('views/ticket/create.html',[
'priorities' => $priorities,
'statuses' => $statuses,
'users' => $users,
'all_tags' => $all_tags
]);
}
// handle POST
// including custom forms
public function create($f3){
$this->requireLogin();
$this->checkCSRF($f3, '/ticket/create');
$data = [
'title' => $this->f3->get('POST.title'),
'created_at' => $this->f3->get('POST.created_at'),
'description' => $this->f3->get('POST.description'),
'priority_id' => $this->f3->get('POST.priority_id'),
'status_id' => $this->f3->get('POST.status_id'),
'created_by' => $this->f3->get('SESSION.user.id'),
'assigned_to' => $this->f3->get('POST.assigned_to') == '-1' ? null : $this->f3->get('POST.assigned_to')
];
$ticket_mapper = new Ticket($this->getDB());
$new_ticket_id = $ticket_mapper->createTicket($data);
// custom field
// $meta_keys = $this->f3->get('POST.meta_key');
// $meta_values = $this->f3->get('POST.meta_value');
// $meta_assoc = $ticket_mapper->assocMetaFromKeyValue($meta_keys, $meta_values);
// $ticket_mapper->setCustomFields($meta_assoc);
$new_ticket = $ticket_mapper->findById($new_ticket_id);
if($new_ticket){
// TAG handling for create
$posted_tags = $this->f3->get('POST.tags');
if(!empty($posted_tags) && is_array($posted_tags)){
$new_ticket->setTags($posted_tags);
}
}
$this->f3->set('SESSION.message', 'Ticket #' . $new_ticket_id . ' created successfully.');
$this->f3->reroute('/ticket/' . $new_ticket_id);
}
// show edit form
// including custom forms
// TODO_PROJECTS: allow reasssigning or removing a project association
public function editForm($f3)
{
$this->requireLogin();
$ticket_id = $f3->get('PARAMS.id');
$ticket_mapper = new Ticket($this->getDB());
$ticket = $ticket_mapper->findById($ticket_id);
if(!$ticket){
$this->f3->set('SESSION.error', 'Ticket not found.');
$this->f3->reroute('/tickets');
}
//
$f3->set('js', 'markdown_preview.js');
// dropdowns
$priorities = (new TicketPriority($this->getDB()))->findAll();
$statuses = (new TicketStatus($this->getDB()))->findAll();
$all_tags_model = new \Tag($this->getDB());
$all_tags = $all_tags_model->find([], ['order' => 'name ASC']);
// TODO: this needs moving into a model?
$users = $this->getDB()->exec('SELECT id, username, display_name FROM users ORDER BY display_name ASC');
$users = array_merge([['id'=>'-1', 'display_name'=>'--']], $users);
// paradox - empty($ticket->tags) was returning true, when there were items present
$current_ticket_tag_ids = [];
if(count($ticket->tags) > 0){
foreach($ticket->tags as $current_tag_data){
$current_ticket_tag_ids[] = $current_tag_data['id'];
}
}
$this->renderView('views/ticket/edit.html',[
'ticket' => $ticket,
'ticket_meta' => $ticket->getMeta(),
'priorities' => $priorities,
'statuses' => $statuses,
'users' => $users,
'all_tags' => $all_tags,
'current_ticket_tag_ids' => $current_ticket_tag_ids
]
);
return;
}
// process edit POST TODO: if assigned or admin
public function update($f3)
{
$this->requireLogin();
$this->checkCSRF($f3, '/ticket/create');
$ticket_id = $f3->get('PARAMS.id');
$ticket_mapper = new Ticket($this->getDB());
$ticket = $ticket_mapper->findById($ticket_id);
if(!$ticket){
$f3->set('SESSION.error', 'Ticket not found.');
$f3->reroute('/tickets');
}
$data = [
'title' => $f3->get('POST.title'),
'created_at' => $f3->get('POST.created_at'),
'description' => $f3->get('POST.description'),
'priority_id' => $f3->get('POST.priority_id'),
'status_id' => $f3->get('POST.status_id'),
'updated_by' => $f3->get('SESSION.user.id') ,
'assigned_to' => $f3->get('POST.assigned_to') == -1 ? null : $f3->get('POST.assigned_to')
];
$ticket->updateTicket($data);
// deal with meta data / custom fields
// $meta_keys = $this->f3->get('POST.meta_key');
// $meta_values = $this->f3->get('POST.meta_value');
// $meta_assoc = $ticket->assocMetaFromKeyValue($meta_keys, $meta_values);
// $ticket->setCustomFields($meta_assoc);
$posted_tags = $f3->get('POST.tags');
if(is_array($posted_tags)){
$ticket->setTags($posted_tags);
} elseif (empty($posted_tags)){
$ticket->setTags([]);
}
$f3->set('SESSION.message', 'Ticket #' . $ticket_id . ' updated successfully.') ;
$f3->reroute('/ticket/' . $ticket_id);
}
// subtask
public function addSubtask($f3){
$this->requireLogin();
$this->checkCSRF($f3, '/ticket/create');
$parent_id = (int) $f3->get('PARAMS.id');
$child_id = (int) $f3->get('POST.child_ticket_id');
$ticket_mapper = new Ticket($this->getDB());
$ticket = $ticket_mapper->findById($parent_id);
if(!$ticket){
$this->f3->set('SESSION.error', 'Parent Ticket not found');
$this->f3->reroute('/tickets');
}
$ticket->addChildTicket($child_id);
$this->f3->reroute('/ticket/' . $parent_id);
}
public function delete(): void
{
$this->requireLogin();
$ticket_id = (int)$this->f3->get('PARAMS.id');
$ticket_mapper = new Ticket($this->getDB());
$ticket = $ticket_mapper->findById($ticket_id);
if(!$ticket){
$this->f3->set('SESSION.error', 'Ticket not found');
$this->f3->reroute('/tickets');
}
$ticket->softDelete();
$this->f3->reroute('/tickets');
}
}