conn = $conn; $this->ticketModel = new TicketModel($conn); $this->commentModel = new CommentModel($conn); $this->auditLogModel = new AuditLogModel($conn); $this->userModel = new UserModel($conn); $this->workflowModel = new WorkflowModel($conn); $this->templateModel = new TemplateModel($conn); $this->customFieldModel = new CustomFieldModel($conn); } public function view($id) { // Get current user $currentUser = $GLOBALS['currentUser'] ?? null; $userId = $currentUser['user_id'] ?? null; // Get ticket data $ticket = $this->ticketModel->getTicketById($id); if (!$ticket || !$this->ticketModel->canUserAccessTicket($ticket, $currentUser)) { http_response_code(404); include dirname(__DIR__) . '/views/error_404.php'; return; } // Load first page of comments; show "load more" if ticket has many $commentPageSize = 50; $totalComments = $this->commentModel->getCommentCount((int)$id); $comments = $this->commentModel->getCommentsByTicketId($id, true, $commentPageSize, 0); // Get timeline for this ticket $timeline = $this->auditLogModel->getTicketTimeline($id); // Get all users for assignment dropdown $allUsers = $this->userModel->getAllUsers(); // Get allowed status transitions for this ticket $allowedTransitions = $this->workflowModel->getAllowedTransitions($ticket['status']); // Custom fields applicable to this ticket's category, with any // already-saved values for it $customFieldDefs = $this->customFieldModel->getAllDefinitions($ticket['category'], true); $customFieldValues = $this->customFieldModel->getValuesForTicket($id); // Make $conn available to view for visibility groups $conn = $this->conn; // Load the view include dirname(__DIR__) . '/views/TicketView.php'; } public function create() { // Get current user $currentUser = $GLOBALS['currentUser'] ?? null; $userId = $currentUser['user_id'] ?? null; // All active custom field definitions (every category, plus // category-less ones) — the create form renders them all and toggles // visibility client-side as the Category select changes, since the // ticket doesn't exist yet to scope the query to one category. $allCustomFieldDefs = $this->customFieldModel->getAllDefinitions(null, true); // Check if form was submitted if ($_SERVER['REQUEST_METHOD'] === 'POST') { // Validate CSRF token require_once dirname(__DIR__) . '/middleware/CsrfMiddleware.php'; $csrfToken = $_POST['csrf_token'] ?? ''; if (!CsrfMiddleware::validateToken($csrfToken)) { $error = "Invalid or expired security token. Please try again."; $templates = $this->templateModel->getAllTemplates(); $allUsers = $this->userModel->getAllUsers(); $conn = $this->conn; include dirname(__DIR__) . '/views/CreateTicketView.php'; return; } // Validation (incl. required custom fields), creation, audit log, // stats cache, custom field values, duplicate link and notification // live in TicketCreationService so the MCP create_ticket tool runs // the same code path. require_once dirname(__DIR__) . '/services/TicketCreationService.php'; $result = TicketCreationService::create($this->conn, $currentUser ?? [], [ 'title' => $_POST['title'] ?? '', 'description' => $_POST['description'] ?? '', 'priority' => $_POST['priority'] ?? '4', 'category' => $_POST['category'] ?? 'General', 'type' => $_POST['type'] ?? 'Issue', 'status' => $_POST['status'] ?? 'Open', 'visibility' => $_POST['visibility'] ?? 'public', 'visibility_groups' => (isset($_POST['visibility_groups']) && is_array($_POST['visibility_groups'])) ? $_POST['visibility_groups'] : null, 'assigned_to' => $_POST['assigned_to'] ?? null, 'custom_fields' => $_POST['custom_fields'] ?? [], 'link_duplicate_of' => $_POST['link_duplicate_of'] ?? '', ]); if ($result['success']) { // Redirect to the new ticket header("Location: " . $GLOBALS['config']['BASE_URL'] . "/ticket/" . $result['ticket_id']); exit; } else { $error = $result['error']; $templates = $this->templateModel->getAllTemplates(); $allUsers = $this->userModel->getAllUsers(); $conn = $this->conn; // Make $conn available to view include dirname(__DIR__) . '/views/CreateTicketView.php'; return; } } else { // Get all templates for the template selector $templates = $this->templateModel->getAllTemplates(); // Get all users for assignment dropdown $allUsers = $this->userModel->getAllUsers(); $conn = $this->conn; // Make $conn available to view // Display the create ticket form include dirname(__DIR__) . '/views/CreateTicketView.php'; } } }