query("SELECT * FROM todos ORDER BY created_at DESC"); $todos = $stmt->fetchAll(PDO::FETCH_ASSOC); // Convert is_completed to boolean foreach ($todos as &$todo) { $todo['is_completed'] = (bool) $todo['is_completed']; } http_response_code(200); echo json_encode([ 'success' => true, 'data' => $todos ]); break; case 'POST': // Create new todo $input = json_decode(file_get_contents('php://input'), true); if (!isset($input['title']) || trim($input['title']) === '') { http_response_code(400); echo json_encode([ 'success' => false, 'error' => 'Title is required' ]); break; } $title = trim($input['title']); $description = isset($input['description']) ? trim($input['description']) : ''; $stmt = $pdo->prepare("INSERT INTO todos (title, description) VALUES (?, ?)"); $stmt->execute([$title, $description]); $id = $pdo->lastInsertId(); // Fetch the created todo $stmt = $pdo->prepare("SELECT * FROM todos WHERE id = ?"); $stmt->execute([$id]); $todo = $stmt->fetch(PDO::FETCH_ASSOC); $todo['is_completed'] = (bool) $todo['is_completed']; http_response_code(201); echo json_encode([ 'success' => true, 'data' => $todo ]); break; case 'PUT': // Update todo $input = json_decode(file_get_contents('php://input'), true); if (!isset($input['id'])) { http_response_code(400); echo json_encode([ 'success' => false, 'error' => 'Todo ID is required' ]); break; } $id = $input['id']; // Check if todo exists $stmt = $pdo->prepare("SELECT * FROM todos WHERE id = ?"); $stmt->execute([$id]); $todo = $stmt->fetch(PDO::FETCH_ASSOC); if (!$todo) { http_response_code(404); echo json_encode([ 'success' => false, 'error' => 'Todo not found' ]); break; } // Build update query dynamically based on provided fields $updates = []; $params = []; if (isset($input['title'])) { $updates[] = "title = ?"; $params[] = trim($input['title']); } if (isset($input['description'])) { $updates[] = "description = ?"; $params[] = trim($input['description']); } if (isset($input['is_completed'])) { $updates[] = "is_completed = ?"; $params[] = $input['is_completed'] ? 1 : 0; } if (empty($updates)) { http_response_code(400); echo json_encode([ 'success' => false, 'error' => 'No fields to update' ]); break; } $params[] = $id; $sql = "UPDATE todos SET " . implode(', ', $updates) . " WHERE id = ?"; $stmt = $pdo->prepare($sql); $stmt->execute($params); // Fetch updated todo $stmt = $pdo->prepare("SELECT * FROM todos WHERE id = ?"); $stmt->execute([$id]); $todo = $stmt->fetch(PDO::FETCH_ASSOC); $todo['is_completed'] = (bool) $todo['is_completed']; http_response_code(200); echo json_encode([ 'success' => true, 'data' => $todo ]); break; case 'DELETE': // Delete todo $input = json_decode(file_get_contents('php://input'), true); if (!isset($input['id'])) { http_response_code(400); echo json_encode([ 'success' => false, 'error' => 'Todo ID is required' ]); break; } $id = $input['id']; // Check if todo exists $stmt = $pdo->prepare("SELECT * FROM todos WHERE id = ?"); $stmt->execute([$id]); $todo = $stmt->fetch(PDO::FETCH_ASSOC); if (!$todo) { http_response_code(404); echo json_encode([ 'success' => false, 'error' => 'Todo not found' ]); break; } // Delete the todo $stmt = $pdo->prepare("DELETE FROM todos WHERE id = ?"); $stmt->execute([$id]); http_response_code(200); echo json_encode([ 'success' => true, 'message' => 'Todo deleted successfully' ]); break; default: http_response_code(405); echo json_encode([ 'success' => false, 'error' => 'Method not allowed' ]); break; } } catch (PDOException $e) { http_response_code(500); echo json_encode([ 'success' => false, 'error' => 'Database error: ' . $e->getMessage() ]); } catch (Exception $e) { http_response_code(500); echo json_encode([ 'success' => false, 'error' => 'Server error: ' . $e->getMessage() ]); }