ticketModel = new TicketModel($conn); $this->commentModel = new CommentModel($conn); $this->envVars = $envVars; } public function update($id, $data) { debug_log("ApiTicketController->update called with ID: $id and data: " . json_encode($data)); // First, get the current ticket data to fill in missing fields $currentTicket = $this->ticketModel->getTicketById($id); if (!$currentTicket) { return [ 'success' => false, 'error' => 'Ticket not found' ]; } debug_log("Current ticket data: " . json_encode($currentTicket)); // Merge current data with updates, keeping existing values for missing fields $updateData = [ 'ticket_id' => $id, 'title' => $data['title'] ?? $currentTicket['title'], 'description' => $data['description'] ?? $currentTicket['description'], 'category' => $data['category'] ?? $currentTicket['category'], 'type' => $data['type'] ?? $currentTicket['type'], 'status' => $data['status'] ?? $currentTicket['status'], 'priority' => isset($data['priority']) ? (int)$data['priority'] : (int)$currentTicket['priority'] ]; debug_log("Merged update data: " . json_encode($updateData)); // Validate required fields if (empty($updateData['title'])) { return [ 'success' => false, 'error' => 'Title cannot be empty' ]; } // Validate priority range if ($updateData['priority'] < 1 || $updateData['priority'] > 5) { return [ 'success' => false, 'error' => 'Priority must be between 1 and 5' ]; } // Validate status $validStatuses = ['Open', 'Closed', 'In Progress', 'Pending']; if (!in_array($updateData['status'], $validStatuses)) { return [ 'success' => false, 'error' => 'Invalid status value' ]; } debug_log("Validation passed, calling ticketModel->updateTicket"); // Update ticket $result = $this->ticketModel->updateTicket($updateData); debug_log("TicketModel->updateTicket returned: " . ($result ? 'true' : 'false')); if ($result) { // Send Discord webhook notification $this->sendDiscordWebhook($id, $currentTicket, $updateData, $data); return [ 'success' => true, 'status' => $updateData['status'], 'priority' => $updateData['priority'], 'message' => 'Ticket updated successfully' ]; } else { return [ 'success' => false, 'error' => 'Failed to update ticket in database' ]; } } private function sendDiscordWebhook($ticketId, $oldData, $newData, $changedFields) { if (!isset($this->envVars['DISCORD_WEBHOOK_URL']) || empty($this->envVars['DISCORD_WEBHOOK_URL'])) { debug_log("Discord webhook URL not configured, skipping webhook"); return; } $webhookUrl = $this->envVars['DISCORD_WEBHOOK_URL']; debug_log("Sending Discord webhook to: $webhookUrl"); // Determine what fields actually changed $changes = []; foreach ($changedFields as $field => $newValue) { if ($field === 'ticket_id') continue; // Skip ticket_id $oldValue = $oldData[$field] ?? 'N/A'; if ($oldValue != $newValue) { $changes[] = [ 'name' => ucfirst($field), 'value' => "$oldValue → $newValue", 'inline' => true ]; } } if (empty($changes)) { debug_log("No actual changes detected, skipping webhook"); return; } // Create ticket URL $ticketUrl = "http://t.lotusguild.org/ticket/$ticketId"; // Determine embed color based on priority $colors = [ 1 => 0xff4d4d, // Red 2 => 0xffa726, // Orange 3 => 0x42a5f5, // Blue 4 => 0x66bb6a, // Green 5 => 0x9e9e9e // Gray ]; $color = $colors[$newData['priority']] ?? 0x3498db; $embed = [ 'title' => '🔄 Ticket Updated', 'description' => "**#{$ticketId}** - " . $newData['title'], 'color' => $color, 'fields' => array_merge($changes, [ [ 'name' => '🔗 View Ticket', 'value' => "[Click here to view]($ticketUrl)", 'inline' => false ] ]), 'footer' => [ 'text' => 'Tinker Tickets' ], 'timestamp' => date('c') ]; $payload = [ 'embeds' => [$embed] ]; debug_log("Discord payload: " . json_encode($payload)); // Send webhook $ch = curl_init($webhookUrl); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_TIMEOUT, 10); $webhookResult = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $curlError = curl_error($ch); curl_close($ch); if ($curlError) { debug_log("Discord webhook cURL error: $curlError"); } else { debug_log("Discord webhook sent. HTTP Code: $httpCode, Response: $webhookResult"); } } } debug_log("Controller defined successfully"); // Create database connection debug_log("Creating database connection"); $conn = new mysqli( $GLOBALS['config']['DB_HOST'], $GLOBALS['config']['DB_USER'], $GLOBALS['config']['DB_PASS'], $GLOBALS['config']['DB_NAME'] ); if ($conn->connect_error) { throw new Exception("Database connection failed: " . $conn->connect_error); } debug_log("Database connection successful"); // Check request method if ($_SERVER['REQUEST_METHOD'] !== 'POST') { throw new Exception("Method not allowed. Expected POST, got " . $_SERVER['REQUEST_METHOD']); } // Get POST data $input = file_get_contents('php://input'); $data = json_decode($input, true); debug_log("Received raw input: " . $input); debug_log("Decoded data: " . json_encode($data)); if (!$data) { throw new Exception("Invalid JSON data received: " . $input); } if (!isset($data['ticket_id'])) { throw new Exception("Missing ticket_id parameter"); } $ticketId = (int)$data['ticket_id']; debug_log("Processing ticket ID: $ticketId"); // Initialize controller debug_log("Initializing controller"); $controller = new ApiTicketController($conn, $envVars); debug_log("Controller initialized"); // Update ticket debug_log("Calling controller update method"); $result = $controller->update($ticketId, $data); debug_log("Update completed with result: " . json_encode($result)); // Close database connection $conn->close(); // Discard any output that might have been generated ob_end_clean(); // Return response header('Content-Type: application/json'); echo json_encode($result); debug_log("Response sent successfully"); } catch (Exception $e) { debug_log("Error: " . $e->getMessage()); debug_log("Stack trace: " . $e->getTraceAsString()); // Discard any output that might have been generated ob_end_clean(); // Return error response header('Content-Type: application/json'); http_response_code(500); echo json_encode([ 'success' => false, 'error' => $e->getMessage() ]); debug_log("Error response sent"); } ?>