diff options
author | Yorhel <git@yorhel.nl> | 2020-03-21 09:59:25 +0100 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2020-03-21 10:01:33 +0100 |
commit | 45a4cc5efc3ca1f7cb174cfa30205e36a40d2420 (patch) | |
tree | 702565b1b54b9f82a51402008977f2de90b4b0fa | |
parent | 8837061d105aa44e6df294523b8295ea8f66daa6 (diff) |
boardmod feature: Full deletion of threads/posts
Intended to prevent unecessary "deleted" posts, bumping of old threads
and stray notifications when a spammer hits the boards.
To make that easier, there should also be a "delete all posts by this
user" function, but that'll be even trickier.
-rw-r--r-- | elm/Discussions/Edit.elm | 17 | ||||
-rw-r--r-- | lib/VNWeb/Discussions/Edit.pm | 22 |
2 files changed, 38 insertions, 1 deletions
diff --git a/elm/Discussions/Edit.elm b/elm/Discussions/Edit.elm index 4eaf7aa9..1ce6bd75 100644 --- a/elm/Discussions/Edit.elm +++ b/elm/Discussions/Edit.elm @@ -33,6 +33,7 @@ type alias Model = , hidden : Bool , private : Bool , nolastmod : Bool + , delete : Bool , title : Maybe String , boards : Maybe (List GDE.SendBoards) , boardAdd : A.Model GApi.ApiBoardResult @@ -54,6 +55,7 @@ init d = , hidden = d.hidden , private = d.private , nolastmod = False + , delete = False , title = d.title , boards = d.boards , boardAdd = A.init "" @@ -76,6 +78,7 @@ encode m = , hidden = m.hidden , private = m.private , nolastmod = m.nolastmod + , delete = m.delete , boards = m.boards , poll = if m.pollEnabled then m.poll else Nothing , title = m.title @@ -98,6 +101,7 @@ type Msg | Hidden Bool | Private Bool | Nolastmod Bool + | Delete Bool | Content TP.Msg | Title String | BoardDel Int @@ -119,6 +123,7 @@ update msg model = Hidden b -> ({ model | hidden = b }, Cmd.none) Private b -> ({ model | private = b }, Cmd.none) Nolastmod b -> ({ model | nolastmod=b }, Cmd.none) + Delete b -> ({ model | delete = b }, Cmd.none) Content m -> let (nm,nc) = TP.update m model.msg in ({ model | msg = nm }, Cmd.map Content nc) Title s -> ({ model | title = Just s }, Cmd.none) PollEnabled b -> ({ model | pollEnabled = b, poll = if model.poll == Nothing then Just { question = "", max_options = 1, options = ["",""] } else model.poll }, Cmd.none) @@ -233,7 +238,17 @@ view model = , a [ href "/d9#3" ] [ text "Formatting" ] ] ] - ] ++ if thread then poll () else [] + ] + ++ (if thread then poll () else []) + ++ (if not model.can_mod then [] else + [ tr [ class "newpart" ] [ td [ colspan 2 ] [ text "DANGER ZONE" ] ] + , formField "" + [ inputCheck "" model.delete Delete + , text <| " Permanently delete this " ++ if thread then "thread and all replies." else "post." + , text <| if thread then "" else " This causes all replies after this one to be renumbered." + , text <| " This action can not be reverted, only do this with obvious spam!" + ] + ]) ] , div [ class "mainbox" ] [ fieldset [ class "submit" ] [ submitButton "Submit" model.state (isValid model) ] ] diff --git a/lib/VNWeb/Discussions/Edit.pm b/lib/VNWeb/Discussions/Edit.pm index 15e5c198..a0627448 100644 --- a/lib/VNWeb/Discussions/Edit.pm +++ b/lib/VNWeb/Discussions/Edit.pm @@ -27,6 +27,7 @@ my $FORM = { hidden => { anybool => 1 }, # When can_mod private => { anybool => 1 }, # When can_private && (num = 1 || tid = undef) nolastmod => { anybool => 1, _when => 'in' }, # When can_mod + delete => { anybool => 1 }, # When can_mod msg => { maxlength => 32768 }, }; @@ -49,6 +50,26 @@ elm_api DiscussionsEdit => $FORM_OUT, $FORM_IN, sub { return tuwf->resNotFound if $tid && !$t->{id}; return elm_Unauth if !can_edit t => $t; + if($data->{delete} && auth->permBoardmod) { + warn "AUDIT: Delete t$tid.$num\n"; + # BUG: Doesn't cause stats_cache to be updated. But who cares about that. + if($num == 1) { + # (This could be a single query if there were proper ON DELETE CASCADE in the DB, though that's hard for notifications...) + tuwf->dbExeci('DELETE FROM threads_posts WHERE tid =', \$tid); + tuwf->dbExeci('DELETE FROM threads_boards WHERE tid =', \$tid); + tuwf->dbExeci('DELETE FROM threads WHERE id =', \$tid); + tuwf->dbExeci(q{DELETE FROM notifications WHERE ltype = 't' AND iid =}, \$tid); + return elm_Redirect '/t'; + } else { + tuwf->dbExeci('DELETE FROM threads_posts WHERE tid =', \$tid, 'AND num =', \$num); + tuwf->dbExeci('UPDATE threads_posts SET num = num - 1 WHERE tid =', \$tid, 'AND num >', \$num); + tuwf->dbExeci('UPDATE threads SET count = count - 1 WHERE id =', \$tid); + tuwf->dbExeci(q{DELETE FROM notifications WHERE ltype = 't' AND iid =}, \$tid, 'AND subid =', \$num); + tuwf->dbExeci(q{UPDATE notifications SET subid = subid - 1 WHERE ltype = 't' AND iid =}, \$tid, 'AND subid >', \$num); + return elm_Redirect "/t$tid"; + } + } + my $pollchanged = !$data->{tid} && $data->{poll}; if($num == 1) { die "Invalid title" if !length $data->{title}; @@ -152,6 +173,7 @@ TUWF::get qr{(?:/t/(?<board>$BOARD_RE)/new|/$RE{postid}/edit)}, sub { $t->{num} //= undef; $t->{private} //= 0; $t->{locked} //= 0; + $t->{delete} = 0; framework_ title => $tid ? 'Edit post' : 'Create new thread', sub { elm_ 'Discussions.Edit' => $FORM_OUT, $t; |