diff --git a/app/models/reviewable_flagged_post.rb b/app/models/reviewable_flagged_post.rb index 009c2a78bf0..e523ded4889 100644 --- a/app/models/reviewable_flagged_post.rb +++ b/app/models/reviewable_flagged_post.rb @@ -198,6 +198,7 @@ class ReviewableFlaggedPost < Reviewable # Undo hide/silence if applicable if post&.hidden? + notify_poster(performed_by) post.unhide! UserSilencer.unsilence(post.user) if UserSilencer.was_silenced_for?(post) end @@ -210,30 +211,26 @@ class ReviewableFlaggedPost < Reviewable def perform_delete_and_ignore(performed_by, args) result = perform_ignore(performed_by, args) - PostDestroyer.new(performed_by, post).destroy + destroyer(performed_by, post).destroy result end def perform_delete_and_ignore_replies(performed_by, args) result = perform_ignore(performed_by, args) - - reply_ids = post.reply_ids(Guardian.new(performed_by), only_replies_to_single_post: false) - replies = Post.where(id: reply_ids.map { |r| r[:id] }) - PostDestroyer.new(performed_by, post).destroy - replies.each { |reply| PostDestroyer.new(performed_by, reply).destroy } + PostDestroyer.delete_with_replies(performed_by, post, self) result end def perform_delete_and_agree(performed_by, args) result = agree(performed_by, args) - PostDestroyer.new(performed_by, post).destroy + destroyer(performed_by, post).destroy result end def perform_delete_and_agree_replies(performed_by, args) result = agree(performed_by, args) - PostDestroyer.delete_with_replies(performed_by, post) + PostDestroyer.delete_with_replies(performed_by, post, self) result end @@ -283,6 +280,25 @@ protected end end +private + + def destroyer(performed_by, post) + PostDestroyer.new(performed_by, post, reviewable: self) + end + + def notify_poster(performed_by) + return unless performed_by.human? && performed_by.staff? + + Jobs.enqueue( + :send_system_message, + user_id: post.user_id, + message_type: :flags_disagreed, + message_options: { + flagged_post_raw_content: post.raw, + url: post.url + } + ) + end end # == Schema Information diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index caf705c4859..e1d5a55592e 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -2555,7 +2555,23 @@ en: The community flagged this post and now it is hidden. **Because this post has been hidden more than once, your post will now remain hidden until it is handled by a staff member.** For additional guidance, please refer to our [community guidelines](%{base_url}/guidelines). + + flags_disagreed: + title: "Flagged post restored by staff" + subject_template: "Flagged post restored by staff" + text_body_template: | + Hello, + This is an automated message from %{site_name} to let you know that [your post](%{base_url}%{url}) was restored. + + This post was flagged by the community and a staff member opted to restore it. + + [details="Click to expand restored post"] + ``` markdown + %{flagged_post_raw_content} + ``` + [/details] + flags_agreed_and_post_deleted: title: "Flagged post removed by staff" subject_template: "Flagged post removed by staff" diff --git a/lib/post_destroyer.rb b/lib/post_destroyer.rb index 228e5adfb4a..48517527d89 100644 --- a/lib/post_destroyer.rb +++ b/lib/post_destroyer.rb @@ -39,10 +39,10 @@ class PostDestroyer end end - def self.delete_with_replies(performed_by, post) + def self.delete_with_replies(performed_by, post, reviewable = nil) reply_ids = post.reply_ids(Guardian.new(performed_by), only_replies_to_single_post: false) replies = Post.where(id: reply_ids.map { |r| r[:id] }) - PostDestroyer.new(performed_by, post).destroy + PostDestroyer.new(performed_by, post, reviewable: reviewable).destroy replies.each { |reply| PostDestroyer.new(performed_by, reply).destroy } end @@ -156,12 +156,10 @@ class PostDestroyer TopicUser.update_post_action_cache(post_id: @post.id) DB.after_commit do - if reviewable = @post.reviewable_flag - if @opts[:defer_flags] - ignore(reviewable) - else - agree(reviewable) - end + if @opts[:reviewable] + notify_deletion(@opts[:reviewable]) + elsif reviewable = @post.reviewable_flag + @opts[:defer_flags] ? ignore(reviewable) : agree(reviewable) end end end @@ -263,23 +261,7 @@ class PostDestroyer end def agree(reviewable) - if @user.human? && @user.staff? && rs = reviewable.reviewable_scores.order('created_at DESC').first - Jobs.enqueue( - :send_system_message, - user_id: @post.user_id, - message_type: :flags_agreed_and_post_deleted, - message_options: { - flagged_post_raw_content: @post.raw, - url: @post.url, - flag_reason: I18n.t( - "flag_reasons.#{PostActionType.types[rs.reviewable_score_type]}", - locale: SiteSetting.default_locale, - base_path: Discourse.base_path - ) - } - ) - end - + notify_deletion(reviewable) result = reviewable.perform(@user, :agree_and_keep, post_was_deleted: true) reviewable.transition_to(result.transition_to, @user) end @@ -289,6 +271,26 @@ class PostDestroyer reviewable.transition_to(:ignored, @user) end + def notify_deletion(reviewable) + allowed_user = @user.human? && @user.staff? + return unless allowed_user && rs = reviewable.reviewable_scores.order('created_at DESC').first + + Jobs.enqueue( + :send_system_message, + user_id: @post.user_id, + message_type: :flags_agreed_and_post_deleted, + message_options: { + flagged_post_raw_content: @post.raw, + url: @post.url, + flag_reason: I18n.t( + "flag_reasons.#{PostActionType.types[rs.reviewable_score_type]}", + locale: SiteSetting.default_locale, + base_path: Discourse.base_path + ) + } + ) + end + def trash_user_actions UserAction.where(target_post_id: @post.id).each do |ua| row = { diff --git a/spec/models/reviewable_flagged_post_spec.rb b/spec/models/reviewable_flagged_post_spec.rb index 7df51b115f5..d060ac3c65d 100644 --- a/spec/models/reviewable_flagged_post_spec.rb +++ b/spec/models/reviewable_flagged_post_spec.rb @@ -273,4 +273,35 @@ RSpec.describe ReviewableFlaggedPost, type: :model do end + describe "#perform_delete_and_agree" do + it "notifies the user about the flagged post deletion" do + reviewable = Fabricate(:reviewable_flagged_post) + reviewable.add_score( + moderator, PostActionType.types[:spam], + created_at: reviewable.created_at + ) + + reviewable.perform(moderator, :delete_and_agree) + + assert_pm_creation_enqueued(reviewable.post.user_id, "flags_agreed_and_post_deleted") + end + end + + describe "#perform_disagree" do + it "notifies the user about the flagged post being restored" do + reviewable = Fabricate(:reviewable_flagged_post) + reviewable.post.update(hidden: true, hidden_at: Time.zone.now, hidden_reason_id: PostActionType.types[:spam]) + + reviewable.perform(moderator, :disagree) + + assert_pm_creation_enqueued(reviewable.post.user_id, "flags_disagreed") + end + end + + def assert_pm_creation_enqueued(user_id, pm_type) + expect(Jobs::SendSystemMessage.jobs.length).to eq(1) + job = Jobs::SendSystemMessage.jobs[0] + expect(job["args"][0]["user_id"]).to eq(user_id) + expect(job["args"][0]["message_type"]).to eq(pm_type) + end end