672 lines
23 KiB
PHP
672 lines
23 KiB
PHP
<?php
|
|
// =====================================================================
|
|
// Contributions API Endpoint
|
|
// Handles CRUD Operations for Contributions (Points, Lines, Polygons)
|
|
// and Voting. Actions are determined by the 'action' Parameter in
|
|
// the Request.
|
|
//
|
|
// Supported Actions:
|
|
// read — Load approved Contributions
|
|
// create — Insert Contributions
|
|
// update — Update Contributions
|
|
// delete — Delete Contributions
|
|
// vote — Like or Dislike Contributions
|
|
// =====================================================================
|
|
|
|
require_once __DIR__ . '/db.php';
|
|
|
|
|
|
// ---------------------------------------------------------------------
|
|
// Read Action Parameter and Route to correct Handler
|
|
// ---------------------------------------------------------------------
|
|
$input = get_input();
|
|
$action = $input['action'] ?? '';
|
|
|
|
switch ($action) {
|
|
case 'read':
|
|
handle_read($input);
|
|
break;
|
|
case 'create':
|
|
handle_create($input);
|
|
break;
|
|
case 'update':
|
|
handle_update($input);
|
|
break;
|
|
case 'delete':
|
|
handle_delete($input);
|
|
break;
|
|
case 'vote':
|
|
handle_vote($input);
|
|
break;
|
|
case 'create_news':
|
|
handle_create_news($input);
|
|
break;
|
|
case 'update_news':
|
|
handle_update_news($input);
|
|
break;
|
|
case 'delete_news':
|
|
handle_delete_news($input);
|
|
break;
|
|
case 'read_comments':
|
|
handle_read_comments($input);
|
|
break;
|
|
case 'create_comment':
|
|
handle_create_comment($input);
|
|
break;
|
|
case 'delete_comment':
|
|
handle_delete_comment($input);
|
|
break;
|
|
default:
|
|
error_response('Unknown Action. Supported Actions are read, create, update, delete, vote.');
|
|
}
|
|
|
|
|
|
// =====================================================================
|
|
// Action Handlers for Contributions
|
|
// =====================================================================
|
|
|
|
|
|
// ---------------------------------------------------------------------
|
|
// READ: Loads approved Contributions as GeoJSON FeatureCollection
|
|
// Required: municipality_id
|
|
// Optional: category
|
|
// ---------------------------------------------------------------------
|
|
function handle_read($input) {
|
|
$pdo = get_db();
|
|
|
|
// Validate Input
|
|
$missing = validate_required($input, ['municipality_id']);
|
|
if (!empty($missing)) {
|
|
error_response('Missing Fields: ' . implode(', ', $missing));
|
|
}
|
|
|
|
$municipality_id = $input['municipality_id'];
|
|
|
|
// Builds SQL Query with Placeholders for prepared Statement
|
|
$sql = "SELECT *, ST_AsGeoJSON(geom) AS geojson
|
|
FROM contributions
|
|
WHERE municipality_id = :mid";
|
|
$params = [':mid' => $municipality_id];
|
|
|
|
// Optional: Filters by Status (Default: only approved)
|
|
$status = $input['status'] ?? 'approved';
|
|
if ($status !== 'all') {
|
|
$sql .= " AND status = :status";
|
|
$params[':status'] = $status;
|
|
}
|
|
|
|
// Optional: Filters by Category
|
|
if (!empty($input['category'])) {
|
|
$sql .= " AND category = :cat";
|
|
$params[':cat'] = $input['category'];
|
|
}
|
|
|
|
$sql .= " ORDER BY created_at DESC";
|
|
|
|
try {
|
|
// Prepared Statement to prevent SQL Injection
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute($params);
|
|
// Fetches Results as PHP-Array
|
|
$rows = $stmt->fetchAll();
|
|
} catch (PDOException $e) {
|
|
error_response('Database Error: ' . $e->getMessage(), 500);
|
|
}
|
|
|
|
// Builds GeoJSON FeatureCollection
|
|
$features = [];
|
|
|
|
foreach ($rows as $row) {
|
|
$geometry = json_decode($row['geojson']);
|
|
|
|
// Removes raw Geometry Columns from Properties
|
|
unset($row['geom']);
|
|
unset($row['geojson']);
|
|
|
|
$features[] = [
|
|
'type' => 'Feature',
|
|
'geometry' => $geometry,
|
|
'properties' => $row
|
|
];
|
|
}
|
|
|
|
$featureCollection = [
|
|
'type' => 'FeatureCollection',
|
|
'features' => $features
|
|
];
|
|
|
|
// Includes User's Votes for persistent Vote Display
|
|
// Returns which Contributions the current Browser has voted on
|
|
$browser_id = $input['browser_id'] ?? '';
|
|
if ($browser_id !== '') {
|
|
$stmt = $pdo->prepare("
|
|
SELECT contribution_id, vote_type
|
|
FROM votes
|
|
WHERE browser_id = :bid
|
|
");
|
|
$stmt->execute([':bid' => $browser_id]);
|
|
$user_votes = [];
|
|
foreach ($stmt->fetchAll() as $v) {
|
|
$user_votes[$v['contribution_id']] = $v['vote_type'];
|
|
}
|
|
$featureCollection['user_votes'] = $user_votes;
|
|
}
|
|
|
|
json_response($featureCollection);
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------------
|
|
// CREATE: Inserts new Contributions
|
|
// Required: municipality_id, geom, geom_type, category, title, author_name
|
|
// Optional: description
|
|
// ---------------------------------------------------------------------
|
|
// ---------------------------------------------------------------------
|
|
// CREATE: Inserts new Contributions with optional Photo Upload
|
|
// Required: municipality_id, geom, geom_type, category, title, author_name
|
|
// Optional: description, browser_id, photo (File Upload)
|
|
// ---------------------------------------------------------------------
|
|
function handle_create($input) {
|
|
$pdo = get_db();
|
|
|
|
// Validates Input
|
|
$missing = validate_required($input, [
|
|
'municipality_id', 'geom', 'geom_type', 'category', 'title', 'author_name'
|
|
]);
|
|
if (!empty($missing)) {
|
|
error_response('Missing Fields: ' . implode(', ', $missing));
|
|
}
|
|
|
|
// Validates Geometry Type
|
|
$valid_geom_types = ['point', 'line', 'polygon'];
|
|
if (!in_array($input['geom_type'], $valid_geom_types)) {
|
|
error_response('Invalid Geometry Type. Must be: ' . implode(', ', $valid_geom_types));
|
|
}
|
|
|
|
// Validates GeoJSON
|
|
$geojson = json_decode($input['geom']);
|
|
if (!$geojson || !isset($geojson->type)) {
|
|
error_response('Invalid GeoJSON in Geometry Field.');
|
|
}
|
|
|
|
// Handles Photo Upload
|
|
$photo_path = null;
|
|
if (isset($_FILES['photo']) && $_FILES['photo']['error'] === UPLOAD_ERR_OK) {
|
|
$photo_path = handle_photo_upload($_FILES['photo']);
|
|
if (!$photo_path) {
|
|
error_response('Photo Upload failed. JPG, PNG, GIF and WebP up to 5 MB are allowed.');
|
|
}
|
|
}
|
|
|
|
// Prepared SQL Statement
|
|
try {
|
|
$stmt = $pdo->prepare("
|
|
INSERT INTO contributions
|
|
(municipality_id, geom, geom_type, category, title, description, author_name, browser_id, photo_path)
|
|
VALUES
|
|
(:mid, ST_SetSRID(ST_GeomFromGeoJSON(:geom), 4326), :geom_type,
|
|
:category, :title, :description, :author_name, :browser_id, :photo_path)
|
|
");
|
|
|
|
$stmt->execute([
|
|
':mid' => $input['municipality_id'],
|
|
':geom' => $input['geom'],
|
|
':geom_type' => $input['geom_type'],
|
|
':category' => $input['category'],
|
|
':title' => $input['title'],
|
|
':description' => $input['description'] ?? '',
|
|
':author_name' => $input['author_name'],
|
|
':browser_id' => $input['browser_id'] ?? null,
|
|
':photo_path' => $photo_path
|
|
]);
|
|
|
|
json_response([
|
|
'message' => 'Contribution created successfully.',
|
|
'contribution_id' => (int) $pdo->lastInsertId()
|
|
], 201);
|
|
|
|
} catch (PDOException $e) {
|
|
error_response('Database Error: ' . $e->getMessage(), 500);
|
|
}
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------------
|
|
// UPDATE: Updates existing Contributions
|
|
// Required: contribution_id
|
|
// Optional: category, title, description, status
|
|
// Provided Fields are updated. Others remain unchanged.
|
|
// ---------------------------------------------------------------------
|
|
function handle_update($input) {
|
|
$pdo = get_db();
|
|
|
|
// Validates Input
|
|
$missing = validate_required($input, ['contribution_id']);
|
|
if (!empty($missing)) {
|
|
error_response('Missing Fields: ' . implode(', ', $missing));
|
|
}
|
|
|
|
$contribution_id = $input['contribution_id'];
|
|
|
|
// Checks if Contribution exists
|
|
$stmt = $pdo->prepare("SELECT contribution_id FROM contributions WHERE contribution_id = :id");
|
|
$stmt->execute([':id' => $contribution_id]);
|
|
if (!$stmt->fetch()) {
|
|
error_response('Contribution not found.', 404);
|
|
}
|
|
|
|
// Builds dynamic SQL Query to only update sent Fields
|
|
$updatable_fields = ['category', 'title', 'description', 'status', 'address'];
|
|
$set_clauses = [];
|
|
$params = [':id' => $contribution_id];
|
|
|
|
foreach ($updatable_fields as $field) {
|
|
if (isset($input[$field]) && $input[$field] !== '') {
|
|
$set_clauses[] = "$field = :$field";
|
|
$params[":$field"] = $input[$field];
|
|
}
|
|
}
|
|
|
|
if (empty($set_clauses)) {
|
|
error_response('No Fields to update. Provide at least one of: ' . implode(', ', $updatable_fields));
|
|
}
|
|
|
|
// Validates Status
|
|
if (isset($params[':status'])) {
|
|
$valid_statuses = ['pending', 'approved', 'rejected', 'in_progress', 'done'];
|
|
if (!in_array($params[':status'], $valid_statuses)) {
|
|
error_response('Invalid Status. Must be: ' . implode(', ', $valid_statuses));
|
|
}
|
|
}
|
|
|
|
// Builds SQL Statement
|
|
$sql = "UPDATE contributions SET " . implode(', ', $set_clauses) . " WHERE contribution_id = :id";
|
|
|
|
// Prepared SQL Statement
|
|
try {
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute($params);
|
|
|
|
json_response(['message' => 'Contribution updated successfully.']);
|
|
|
|
} catch (PDOException $e) {
|
|
error_response('Database Error: ' . $e->getMessage(), 500);
|
|
}
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------------
|
|
// DELETE: Deletes existing Contributions
|
|
// Required: contribution_id
|
|
// Associated Votes are deleted automatically
|
|
// ---------------------------------------------------------------------
|
|
function handle_delete($input) {
|
|
$pdo = get_db();
|
|
|
|
// Validates Input
|
|
$missing = validate_required($input, ['contribution_id']);
|
|
if (!empty($missing)) {
|
|
error_response('Missing Fields: ' . implode(', ', $missing));
|
|
}
|
|
|
|
$contribution_id = $input['contribution_id'];
|
|
|
|
// Checks if Contribution exists
|
|
$stmt = $pdo->prepare("SELECT contribution_id FROM contributions WHERE contribution_id = :id");
|
|
$stmt->execute([':id' => $contribution_id]);
|
|
if (!$stmt->fetch()) {
|
|
error_response('Contribution not found.', 404);
|
|
}
|
|
|
|
// Prepared SQL Statement
|
|
try {
|
|
$stmt = $pdo->prepare("DELETE FROM contributions WHERE contribution_id = :id");
|
|
$stmt->execute([':id' => $contribution_id]);
|
|
|
|
json_response(['message' => 'Contribution deleted successfully.']);
|
|
|
|
} catch (PDOException $e) {
|
|
error_response('Database Error: ' . $e->getMessage(), 500);
|
|
}
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------------
|
|
// VOTE: Likes or Dislikes a Contribution
|
|
// Required: contribution_id, voter_name, vote_type
|
|
// Database Trigger automatically updates Likes and Dislikes Count
|
|
// UNIQUE Constraint prevents duplicate Votes per Voter.
|
|
// ---------------------------------------------------------------------
|
|
function handle_vote($input) {
|
|
$pdo = get_db();
|
|
|
|
// Validates Input
|
|
$missing = validate_required($input, ['contribution_id', 'voter_name', 'vote_type']);
|
|
if (!empty($missing)) {
|
|
error_response('Missing Fields: ' . implode(', ', $missing));
|
|
}
|
|
|
|
// Validates Vote Type
|
|
$valid_vote_types = ['like', 'dislike'];
|
|
if (!in_array($input['vote_type'], $valid_vote_types)) {
|
|
error_response('Invalid vote_type. Must be: ' . implode(', ', $valid_vote_types));
|
|
}
|
|
|
|
// Checks if Contribution exists
|
|
$stmt = $pdo->prepare("SELECT contribution_id FROM contributions WHERE contribution_id = :id");
|
|
$stmt->execute([':id' => $input['contribution_id']]);
|
|
if (!$stmt->fetch()) {
|
|
error_response('Contribution not found.', 404);
|
|
}
|
|
|
|
// Prepared SQL Statement
|
|
try {
|
|
// Checks if Voter already voted on this Contribution
|
|
$browser_id = $input['browser_id'] ?? '';
|
|
if (empty($browser_id)) {
|
|
error_response('Browser ID required for Voting.');
|
|
}
|
|
|
|
$stmt = $pdo->prepare("
|
|
SELECT vote_id, vote_type FROM votes
|
|
WHERE contribution_id = :cid AND browser_id = :bid
|
|
");
|
|
$stmt->execute([':cid' => $input['contribution_id'], ':bid' => $browser_id]);
|
|
$existing = $stmt->fetch();
|
|
|
|
if ($existing) {
|
|
if ($existing['vote_type'] === $input['vote_type']) {
|
|
// Same Vote Type — Removes Vote
|
|
$stmt = $pdo->prepare("DELETE FROM votes WHERE vote_id = :vid");
|
|
$stmt->execute([':vid' => $existing['vote_id']]);
|
|
json_response(['message' => 'Vote removed.', 'action' => 'removed']);
|
|
} else {
|
|
// Different Vote Type — Switches Vote
|
|
$stmt = $pdo->prepare("DELETE FROM votes WHERE vote_id = :vid");
|
|
$stmt->execute([':vid' => $existing['vote_id']]);
|
|
|
|
$stmt = $pdo->prepare("
|
|
INSERT INTO votes (contribution_id, voter_name, vote_type, browser_id)
|
|
VALUES (:cid, :voter, :vtype, :bid)
|
|
");
|
|
$stmt->execute([
|
|
':cid' => $input['contribution_id'],
|
|
':voter' => $input['voter_name'],
|
|
':vtype' => $input['vote_type'],
|
|
':bid' => $browser_id
|
|
]);
|
|
json_response(['message' => 'Vote changed.', 'action' => 'changed'], 200);
|
|
}
|
|
} else {
|
|
// No existing Vote — Inserts Vote
|
|
$stmt = $pdo->prepare("
|
|
INSERT INTO votes (contribution_id, voter_name, vote_type, browser_id)
|
|
VALUES (:cid, :voter, :vtype, :bid)
|
|
");
|
|
$stmt->execute([
|
|
':cid' => $input['contribution_id'],
|
|
':voter' => $input['voter_name'],
|
|
':vtype' => $input['vote_type'],
|
|
':bid' => $browser_id
|
|
]);
|
|
json_response(['message' => 'Vote recorded.', 'action' => 'created'], 201);
|
|
}
|
|
|
|
} catch (PDOException $e) {
|
|
error_response('Database Error: ' . $e->getMessage(), 500);
|
|
}
|
|
}
|
|
|
|
|
|
// =====================================================================
|
|
// Action Handlers for News
|
|
// =====================================================================
|
|
|
|
// ---------------------------------------------------------------------
|
|
// CREATE NEWS: Inserts new News Entry
|
|
// Required: municipality_id, title, content
|
|
// ---------------------------------------------------------------------
|
|
function handle_create_news($input) {
|
|
$pdo = get_db();
|
|
$missing = validate_required($input, ['municipality_id', 'title', 'content']);
|
|
if (!empty($missing)) {
|
|
error_response('Missing Fields: ' . implode(', ', $missing));
|
|
}
|
|
|
|
try {
|
|
$stmt = $pdo->prepare("
|
|
INSERT INTO news (municipality_id, title, content, author_name)
|
|
VALUES (:mid, :title, :content, :author)
|
|
");
|
|
$stmt->execute([
|
|
':mid' => $input['municipality_id'],
|
|
':title' => $input['title'],
|
|
':content' => $input['content'],
|
|
':author' => $input['author_name'] ?? 'Stadtverwaltung'
|
|
]);
|
|
json_response(['message' => 'News created successfully.', 'news_id' => (int) $pdo->lastInsertId()], 201);
|
|
} catch (PDOException $e) {
|
|
error_response('Database Error: ' . $e->getMessage(), 500);
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
// UPDATE NEWS: Updates existing News Entry
|
|
// Required: news_id
|
|
// Optional: title, content
|
|
// ---------------------------------------------------------------------
|
|
function handle_update_news($input) {
|
|
$pdo = get_db();
|
|
$missing = validate_required($input, ['news_id']);
|
|
if (!empty($missing)) {
|
|
error_response('Missing Fields: ' . implode(', ', $missing));
|
|
}
|
|
|
|
$set = [];
|
|
$params = [':id' => $input['news_id']];
|
|
|
|
foreach (['title', 'content', 'author_name'] as $field) {
|
|
if (isset($input[$field]) && $input[$field] !== '') {
|
|
$set[] = "$field = :$field";
|
|
$params[":$field"] = $input[$field];
|
|
}
|
|
}
|
|
|
|
if (empty($set)) {
|
|
error_response('No Fields to update.');
|
|
}
|
|
|
|
try {
|
|
$stmt = $pdo->prepare("UPDATE news SET " . implode(', ', $set) . " WHERE news_id = :id");
|
|
$stmt->execute($params);
|
|
json_response(['message' => 'News updated successfully.']);
|
|
} catch (PDOException $e) {
|
|
error_response('Database Error: ' . $e->getMessage(), 500);
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
// DELETE NEWS: Deletes existing News Entry
|
|
// Required: news_id
|
|
// ---------------------------------------------------------------------
|
|
function handle_delete_news($input) {
|
|
$pdo = get_db();
|
|
$missing = validate_required($input, ['news_id']);
|
|
if (!empty($missing)) {
|
|
error_response('Missing Fields: ' . implode(', ', $missing));
|
|
}
|
|
|
|
try {
|
|
$stmt = $pdo->prepare("DELETE FROM news WHERE news_id = :id");
|
|
$stmt->execute([':id' => $input['news_id']]);
|
|
json_response(['message' => 'News deleted successfully.']);
|
|
} catch (PDOException $e) {
|
|
error_response('Database Error: ' . $e->getMessage(), 500);
|
|
}
|
|
}
|
|
|
|
|
|
// =====================================================================
|
|
// Action Handlers for Photos
|
|
// =====================================================================
|
|
|
|
// ---------------------------------------------------------------------
|
|
// PHOTO UPLOAD: Validates and Saves uploaded Photo Files
|
|
// Returns relative Path on Success, null on Failure.
|
|
// Allowed: JPG, PNG, GIF, WebP. with maximum Size of 5 MB.
|
|
// ---------------------------------------------------------------------
|
|
function handle_photo_upload($file) {
|
|
// Validates File Size
|
|
$max_size = 5 * 1024 * 1024;
|
|
if ($file['size'] > $max_size) {
|
|
return null;
|
|
}
|
|
|
|
// Validates MIME Type
|
|
$allowed_types = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
|
|
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
|
$mime = finfo_file($finfo, $file['tmp_name']);
|
|
finfo_close($finfo);
|
|
|
|
if (!in_array($mime, $allowed_types)) {
|
|
return null;
|
|
}
|
|
|
|
// Generates unique Filename
|
|
$ext = [
|
|
'image/jpeg' => 'jpg',
|
|
'image/png' => 'png',
|
|
'image/gif' => 'gif',
|
|
'image/webp' => 'webp'
|
|
][$mime];
|
|
|
|
$filename = uniqid('photo_', true) . '.' . $ext;
|
|
$upload_dir = __DIR__ . '/../uploads/photos/';
|
|
$target_path = $upload_dir . $filename;
|
|
|
|
// Creates Upload Directory
|
|
if (!is_dir($upload_dir)) {
|
|
mkdir($upload_dir, 0755, true);
|
|
}
|
|
|
|
// Moves uploaded File
|
|
if (move_uploaded_file($file['tmp_name'], $target_path)) {
|
|
return 'uploads/photos/' . $filename;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
// =====================================================================
|
|
// Action Handlers for Comments
|
|
// =====================================================================
|
|
|
|
// ---------------------------------------------------------------------
|
|
// READ COMMENTS: Loads Comments for a Contribution
|
|
// Returns Comments sorted by Date (newest first)
|
|
// Required: contribution_id
|
|
// ---------------------------------------------------------------------
|
|
function handle_read_comments($input) {
|
|
$pdo = get_db();
|
|
|
|
$missing = validate_required($input, ['contribution_id']);
|
|
if (!empty($missing)) {
|
|
error_response('Missing Fields: ' . implode(', ', $missing));
|
|
}
|
|
|
|
try {
|
|
$stmt = $pdo->prepare("
|
|
SELECT comment_id, contribution_id, author_name, browser_id, content, created_at
|
|
FROM comments
|
|
WHERE contribution_id = :cid
|
|
ORDER BY created_at ASC
|
|
");
|
|
$stmt->execute([':cid' => $input['contribution_id']]);
|
|
$comments = $stmt->fetchAll();
|
|
|
|
json_response(['comments' => $comments, 'count' => count($comments)]);
|
|
|
|
} catch (PDOException $e) {
|
|
error_response('Database Error: ' . $e->getMessage(), 500);
|
|
}
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------------
|
|
// CREATE COMMENT: Adds Comments to Contributions
|
|
// Required: contribution_id, author_name, content
|
|
// Optional: browser_id
|
|
// ---------------------------------------------------------------------
|
|
function handle_create_comment($input) {
|
|
$pdo = get_db();
|
|
|
|
$missing = validate_required($input, ['contribution_id', 'author_name', 'content']);
|
|
if (!empty($missing)) {
|
|
error_response('Missing Fields: ' . implode(', ', $missing));
|
|
}
|
|
|
|
// Validates Content Length
|
|
if (strlen($input['content']) > 1000) {
|
|
error_response('Comment too long. Maximum 1000 Characters.');
|
|
}
|
|
|
|
// Checks if Contribution exists
|
|
$stmt = $pdo->prepare("SELECT contribution_id FROM contributions WHERE contribution_id = :id");
|
|
$stmt->execute([':id' => $input['contribution_id']]);
|
|
if (!$stmt->fetch()) {
|
|
error_response('Contribution not found.', 404);
|
|
}
|
|
|
|
try {
|
|
$stmt = $pdo->prepare("
|
|
INSERT INTO comments (contribution_id, author_name, browser_id, content)
|
|
VALUES (:cid, :author, :bid, :content)
|
|
");
|
|
$stmt->execute([
|
|
':cid' => $input['contribution_id'],
|
|
':author' => $input['author_name'],
|
|
':bid' => $input['browser_id'] ?? null,
|
|
':content' => $input['content']
|
|
]);
|
|
|
|
$stmt2 = $pdo->prepare("
|
|
UPDATE contributions
|
|
SET comment_count = comment_count + 1
|
|
WHERE contribution_id = :cid;
|
|
");
|
|
|
|
$stmt2->execute([':cid' => $input['contribution_id']]);
|
|
|
|
json_response([
|
|
'message' => 'Comment created successfully.',
|
|
'comment_id' => (int) $pdo->lastInsertId()
|
|
], 201);
|
|
|
|
} catch (PDOException $e) {
|
|
error_response('Database Error: ' . $e->getMessage(), 500);
|
|
}
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------------
|
|
// DELETE COMMENT: Removes a Comment
|
|
// Required: comment_id
|
|
// ---------------------------------------------------------------------
|
|
function handle_delete_comment($input) {
|
|
$pdo = get_db();
|
|
|
|
$missing = validate_required($input, ['comment_id']);
|
|
if (!empty($missing)) {
|
|
error_response('Missing Fields: ' . implode(', ', $missing));
|
|
}
|
|
|
|
try {
|
|
$stmt = $pdo->prepare("DELETE FROM comments WHERE comment_id = :id");
|
|
$stmt->execute([':id' => $input['comment_id']]);
|
|
|
|
json_response(['message' => 'Comment deleted successfully.']);
|
|
|
|
} catch (PDOException $e) {
|
|
error_response('Database Error: ' . $e->getMessage(), 500);
|
|
}
|
|
} |