false, 'error' => 'Authentication required']); exit; } // CSRF Protection require_once dirname(__DIR__) . '/middleware/CsrfMiddleware.php'; $csrfToken = $_SERVER['HTTP_X_CSRF_TOKEN'] ?? ''; if (!CsrfMiddleware::validateToken($csrfToken)) { http_response_code(403); echo json_encode(['success' => false, 'error' => 'Invalid CSRF token']); exit; } // Only accept POST if ($_SERVER['REQUEST_METHOD'] !== 'POST') { http_response_code(405); echo json_encode(['success' => false, 'error' => 'Method not allowed']); exit; } // Get request data $input = file_get_contents('php://input'); $data = json_decode($input, true); if (!$data || empty($data['ticket_id'])) { http_response_code(400); echo json_encode(['success' => false, 'error' => 'Missing ticket_id']); exit; } $sourceTicketId = $data['ticket_id']; $userId = $_SESSION['user']['user_id']; // Get database connection $conn = Database::getConnection(); // Get the source ticket $ticketModel = new TicketModel($conn); $sourceTicket = $ticketModel->getTicketById($sourceTicketId); if (!$sourceTicket) { http_response_code(404); echo json_encode(['success' => false, 'error' => 'Source ticket not found']); exit; } // Prepare cloned ticket data $clonedTicketData = [ 'title' => '[CLONE] ' . $sourceTicket['title'], 'description' => $sourceTicket['description'], 'priority' => $sourceTicket['priority'], 'category' => $sourceTicket['category'], 'type' => $sourceTicket['type'], 'visibility' => $sourceTicket['visibility'] ?? 'public', 'visibility_groups' => $sourceTicket['visibility_groups'] ?? null ]; // Create the cloned ticket $result = $ticketModel->createTicket($clonedTicketData, $userId); if ($result['success']) { // Log the clone operation $auditLog = new AuditLogModel($conn); $auditLog->log($userId, 'create', 'ticket', $result['ticket_id'], [ 'action' => 'clone', 'source_ticket_id' => $sourceTicketId, 'title' => $clonedTicketData['title'] ]); // Optionally create a "relates_to" dependency require_once dirname(__DIR__) . '/models/DependencyModel.php'; $dependencyModel = new DependencyModel($conn); $dependencyModel->addDependency($result['ticket_id'], $sourceTicketId, 'relates_to', $userId); header('Content-Type: application/json'); echo json_encode([ 'success' => true, 'new_ticket_id' => $result['ticket_id'], 'message' => 'Ticket cloned successfully' ]); } else { http_response_code(500); echo json_encode([ 'success' => false, 'error' => $result['error'] ?? 'Failed to create cloned ticket' ]); } } catch (Exception $e) { error_log("Clone ticket API error: " . $e->getMessage()); http_response_code(500); echo json_encode(['success' => false, 'error' => 'An internal error occurred']); }