diff --git a/migrations/007_comment_moderation.sql b/migrations/007_comment_moderation.sql new file mode 100644 index 0000000..78356a1 --- /dev/null +++ b/migrations/007_comment_moderation.sql @@ -0,0 +1,14 @@ +-- ===================================================================== +-- Migration 007: Adds Status Column to Comments for Moderation +-- ===================================================================== + +-- Adds Status Column with Default 'pending' +ALTER TABLE comments + ADD COLUMN status VARCHAR(20) NOT NULL DEFAULT 'pending' + CHECK (status IN ('pending', 'approved', 'rejected')); + +-- Index for fast Status Filtering +CREATE INDEX idx_comments_status ON comments(status); + +-- Sets all existing Comments to 'approved' (retroactive) +UPDATE comments SET status = 'approved'; \ No newline at end of file diff --git a/migrations/008_comment_count_trigger.sql b/migrations/008_comment_count_trigger.sql new file mode 100644 index 0000000..04dba3b --- /dev/null +++ b/migrations/008_comment_count_trigger.sql @@ -0,0 +1,65 @@ +-- ===================================================================== +-- Migration 008: Adds comment_count Column with automatic Trigger +-- Mirrors Pattern from likes_count and dislikes_count. +-- ===================================================================== + + +-- --------------------------------------------------------------------- +-- Block 1: Adds comment_count Column to Contributions +-- --------------------------------------------------------------------- +ALTER TABLE contributions + ADD COLUMN comment_count INTEGER NOT NULL DEFAULT 0; + + +-- --------------------------------------------------------------------- +-- Block 2: Backfills existing Comment Counts +-- --------------------------------------------------------------------- +UPDATE contributions c +SET comment_count = ( + SELECT COUNT(*) + FROM comments cm + WHERE cm.contribution_id = c.contribution_id + AND cm.status = 'approved' +); + + +-- --------------------------------------------------------------------- +-- Block 3: Trigger Function to update comment_count +-- Fires on Status Change on comments. Only counts approved Comments +-- --------------------------------------------------------------------- +CREATE OR REPLACE FUNCTION update_comment_count() +RETURNS TRIGGER AS $$ +BEGIN + IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN + UPDATE contributions + SET comment_count = ( + SELECT COUNT(*) FROM comments + WHERE contribution_id = NEW.contribution_id + AND status = 'approved' + ) + WHERE contribution_id = NEW.contribution_id; + END IF; + + IF TG_OP = 'DELETE' OR (TG_OP = 'UPDATE' AND OLD.contribution_id != NEW.contribution_id) THEN + UPDATE contributions + SET comment_count = ( + SELECT COUNT(*) FROM comments + WHERE contribution_id = OLD.contribution_id + AND status = 'approved' + ) + WHERE contribution_id = OLD.contribution_id; + END IF; + + RETURN NULL; +END; +$$ LANGUAGE plpgsql; + + +-- --------------------------------------------------------------------- +-- Block 4: Attaches Trigger to comments Table +-- --------------------------------------------------------------------- +CREATE TRIGGER trigger_update_comment_count + AFTER INSERT OR DELETE OR UPDATE OF status + ON comments + FOR EACH ROW + EXECUTE FUNCTION update_comment_count(); \ No newline at end of file diff --git a/public/admin.php b/public/admin.php index c599583..8da4f3c 100644 --- a/public/admin.php +++ b/public/admin.php @@ -71,12 +71,12 @@ $news_items = $stmt->fetchAll(); // Loads Comments with Contribution for Moderation $stmt = $pdo->prepare(" - SELECT cm.comment_id, cm.contribution_id, cm.author_name, cm.browser_id, cm.content, cm.created_at, - co.title AS contribution_title - FROM comments cm - JOIN contributions co ON cm.contribution_id = co.contribution_id - WHERE co.municipality_id = :mid - ORDER BY cm.created_at DESC + SELECT contribution_id, title, category, description, author_name, + geom_type, status, likes_count, dislikes_count, comment_count, + photo_path, created_at, updated_at + FROM contributions + WHERE municipality_id = :mid + ORDER BY created_at DESC "); $stmt->execute([':mid' => $municipality['municipality_id']]); $all_comments = $stmt->fetchAll(); diff --git a/public/api/contributions.php b/public/api/contributions.php index 2c1620f..8a4f662 100644 --- a/public/api/contributions.php +++ b/public/api/contributions.php @@ -83,8 +83,8 @@ function handle_read($input) { $municipality_id = $input['municipality_id']; // Builds SQL Query with Placeholders for prepared Statement - $sql = "SELECT *, ST_AsGeoJSON(geom) AS geojson - FROM contributions + $sql = "SELECT *, ST_AsGeoJSON(geom) AS geojson + FROM contributions WHERE municipality_id = :mid"; $params = [':mid' => $municipality_id];