diff --git a/app/models/post_action.rb b/app/models/post_action.rb index 8efa750b53..1e533b0a9b 100644 --- a/app/models/post_action.rb +++ b/app/models/post_action.rb @@ -52,6 +52,26 @@ class PostAction < ActiveRecord::Base .count end + # Forums can choose to apply a minimum number of flags required before it shows up in + # the admin interface. One exception is posts hidden by tl3/tl4 - we want those to + # show up even if the minimum visibility is not met. + def self.apply_minimum_visibility(relation) + return relation unless SiteSetting.min_flags_staff_visibility > 1 + + params = { + min_flags: SiteSetting.min_flags_staff_visibility, + hidden_reasons: Post.hidden_reasons.only(:flagged_by_tl3_user, :flagged_by_tl4_user).values + } + + relation.having(<<~SQL, params) + (COUNT(*) >= :min_flags) OR + (SUM(CASE + WHEN posts.hidden_reason_id IN (:hidden_reasons) THEN 1 + ELSE 0 + END) > 0) + SQL + end + def self.update_flagged_posts_count flagged_relation = PostAction.active .flags @@ -61,10 +81,7 @@ class PostAction < ActiveRecord::Base .where('posts.user_id > 0') .group("posts.id") - if SiteSetting.min_flags_staff_visibility > 1 - flagged_relation = flagged_relation - .having("count(*) >= ?", SiteSetting.min_flags_staff_visibility) - end + flagged_relation = apply_minimum_visibility(flagged_relation) posts_flagged_count = flagged_relation .pluck("posts.id") @@ -638,6 +655,7 @@ class PostAction < ActiveRecord::Base message_type: hiding_again ? :post_hidden_again : :post_hidden, message_options: options) end + update_flagged_posts_count end def self.guess_hide_reason(post) diff --git a/lib/flag_query.rb b/lib/flag_query.rb index f3ef77ec0f..cd0ed15089 100644 --- a/lib/flag_query.rb +++ b/lib/flag_query.rb @@ -35,8 +35,8 @@ module FlagQuery .group(:post_id) .order('MIN(post_actions.created_at) DESC') - if opts[:filter] != "old" && SiteSetting.min_flags_staff_visibility > 1 - post_ids_relation = post_ids_relation.having("count(*) >= ?", SiteSetting.min_flags_staff_visibility) + if opts[:filter] != "old" + post_ids_relation = PostAction.apply_minimum_visibility(post_ids_relation) end post_ids = post_ids_relation.pluck(:post_id).uniq diff --git a/spec/components/flag_query_spec.rb b/spec/components/flag_query_spec.rb index 428a5aa319..aee160780e 100644 --- a/spec/components/flag_query_spec.rb +++ b/spec/components/flag_query_spec.rb @@ -114,11 +114,11 @@ describe FlagQuery do it "respects `min_flags_staff_visibility`" do admin = Fabricate(:admin) - moderator = Fabricate(:moderator) + flagger = Fabricate(:user) post = create_post - PostAction.act(moderator, post, PostActionType.types[:spam]) + PostAction.act(flagger, post, PostActionType.types[:spam]) SiteSetting.min_flags_staff_visibility = 2 posts, topics, users = FlagQuery.flagged_posts_report(admin) @@ -133,5 +133,33 @@ describe FlagQuery do expect(users).to be_present end + it "respects `min_flags_staff_visibility` for tl3 hidden spam" do + admin = Fabricate(:admin) + tl3 = Fabricate(:user, trust_level: 3) + post = create_post + + post.user.update_column(:trust_level, 0) + PostAction.act(tl3, post, PostActionType.types[:spam]) + + SiteSetting.min_flags_staff_visibility = 2 + posts, topics, users = FlagQuery.flagged_posts_report(admin) + expect(posts).to be_present + expect(topics).to be_present + expect(users).to be_present + end + + it "respects `min_flags_staff_visibility` for tl4 hidden posts" do + admin = Fabricate(:admin) + tl4 = Fabricate(:user, trust_level: 4) + post = create_post + PostAction.act(tl4, post, PostActionType.types[:spam]) + + SiteSetting.min_flags_staff_visibility = 2 + posts, topics, users = FlagQuery.flagged_posts_report(admin) + expect(posts).to be_present + expect(topics).to be_present + expect(users).to be_present + end + end end diff --git a/spec/models/post_action_spec.rb b/spec/models/post_action_spec.rb index a99ecc795e..823128d1a8 100644 --- a/spec/models/post_action_spec.rb +++ b/spec/models/post_action_spec.rb @@ -160,6 +160,26 @@ describe PostAction do expect(PostAction.flagged_posts_count).to eq(1) end + it "tl3 hidden posts will supersede min_flags_staff_visibility" do + SiteSetting.min_flags_staff_visibility = 2 + expect(PostAction.flagged_posts_count).to eq(0) + + codinghorror.update_column(:trust_level, 3) + post.user.update_column(:trust_level, 0) + PostAction.act(codinghorror, post, PostActionType.types[:spam]) + expect(PostAction.flagged_posts_count).to eq(1) + end + + it "tl4 hidden posts will supersede min_flags_staff_visibility" do + SiteSetting.min_flags_staff_visibility = 2 + expect(PostAction.flagged_posts_count).to eq(0) + + codinghorror.update_column(:trust_level, 4) + PostAction.act(codinghorror, post, PostActionType.types[:off_topic]) + + expect(PostAction.flagged_posts_count).to eq(1) + end + it "should reset counts when a topic is deleted" do PostAction.act(codinghorror, post, PostActionType.types[:off_topic]) post.topic.trash!