mirror of
https://github.com/discourse/discourse.git
synced 2024-12-01 09:53:43 +08:00
f4d0a77d5f
We already add the "delete user" and "delete and block user" options to the drop-down for potential spam, but we should do this for potentially illegal posts as well. This is entirely based on the implementation for the potential spam one, including caching the status on the reviewable record. Also note that just as for potential spam, the user must be "deletable" for the option to appear. I also took the liberty to move the options in the drop-down to what I think is a more intuitive place. (Between delete post and suspend/silence user.)
171 lines
5.5 KiB
Ruby
171 lines
5.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class ReviewablePost < Reviewable
|
|
def self.action_aliases
|
|
{ reject_and_silence: :reject_and_suspend }
|
|
end
|
|
|
|
def self.queue_for_review_if_possible(post, created_or_edited_by)
|
|
return unless SiteSetting.review_every_post
|
|
return if post.post_type != Post.types[:regular] || post.topic.private_message?
|
|
return if Reviewable.pending.where(target: post).exists?
|
|
if created_or_edited_by.bot? || created_or_edited_by.staff? ||
|
|
created_or_edited_by.has_trust_level?(TrustLevel[4])
|
|
return
|
|
end
|
|
system_user = Discourse.system_user
|
|
|
|
needs_review!(
|
|
target: post,
|
|
topic: post.topic,
|
|
created_by: system_user,
|
|
reviewable_by_moderator: true,
|
|
potential_spam: false,
|
|
).tap do |reviewable|
|
|
reviewable.add_score(system_user, ReviewableScore.types[:needs_approval], force_review: true)
|
|
end
|
|
end
|
|
|
|
def build_actions(actions, guardian, args)
|
|
return unless pending?
|
|
|
|
if post.trashed? && guardian.can_recover_post?(post)
|
|
build_action(actions, :approve_and_restore, icon: "check")
|
|
elsif post.hidden?
|
|
build_action(actions, :approve_and_unhide, icon: "check")
|
|
else
|
|
build_action(actions, :approve, icon: "check")
|
|
end
|
|
|
|
reject =
|
|
actions.add_bundle(
|
|
"#{id}-reject",
|
|
icon: "xmark",
|
|
label: "reviewables.actions.reject.bundle_title",
|
|
)
|
|
|
|
if post.trashed?
|
|
build_action(actions, :reject_and_keep_deleted, icon: "trash-can", bundle: reject)
|
|
elsif guardian.can_delete_post_or_topic?(post)
|
|
build_action(actions, :reject_and_delete, icon: "trash-can", bundle: reject)
|
|
end
|
|
|
|
if guardian.can_suspend?(target_created_by)
|
|
build_action(
|
|
actions,
|
|
:reject_and_suspend,
|
|
icon: "ban",
|
|
bundle: reject,
|
|
client_action: "suspend",
|
|
)
|
|
build_action(
|
|
actions,
|
|
:reject_and_silence,
|
|
icon: "microphone-slash",
|
|
bundle: reject,
|
|
client_action: "silence",
|
|
)
|
|
end
|
|
end
|
|
|
|
def perform_approve(performed_by, _args)
|
|
successful_transition :approved, recalculate_score: false
|
|
end
|
|
|
|
def perform_reject_and_keep_deleted(performed_by, _args)
|
|
successful_transition :rejected, recalculate_score: false
|
|
end
|
|
|
|
def perform_approve_and_restore(performed_by, _args)
|
|
PostDestroyer.new(performed_by, post).recover
|
|
|
|
successful_transition :approved, recalculate_score: false
|
|
end
|
|
|
|
def perform_approve_and_unhide(performed_by, _args)
|
|
post.unhide!
|
|
|
|
successful_transition :approved, recalculate_score: false
|
|
end
|
|
|
|
def perform_reject_and_delete(performed_by, _args)
|
|
PostDestroyer.new(performed_by, post, reviewable: self).destroy
|
|
|
|
successful_transition :rejected, recalculate_score: false
|
|
end
|
|
|
|
def perform_reject_and_suspend(performed_by, _args)
|
|
successful_transition :rejected, recalculate_score: false
|
|
end
|
|
|
|
private
|
|
|
|
def post
|
|
@post ||= (target || Post.with_deleted.find_by(id: target_id))
|
|
end
|
|
|
|
def build_action(
|
|
actions,
|
|
id,
|
|
icon:,
|
|
button_class: nil,
|
|
bundle: nil,
|
|
client_action: nil,
|
|
confirm: false
|
|
)
|
|
actions.add(id, bundle: bundle) do |action|
|
|
prefix = "reviewables.actions.#{id}"
|
|
action.icon = icon
|
|
action.button_class = button_class
|
|
action.label = "#{prefix}.title"
|
|
action.description = "#{prefix}.description"
|
|
action.client_action = client_action
|
|
action.confirm_message = "#{prefix}.confirm" if confirm
|
|
end
|
|
end
|
|
|
|
def successful_transition(to_state, recalculate_score: true)
|
|
create_result(:success, to_state) do |result|
|
|
result.recalculate_score = recalculate_score
|
|
result.update_flag_stats = { status: to_state, user_ids: [created_by_id] }
|
|
end
|
|
end
|
|
end
|
|
|
|
# == Schema Information
|
|
#
|
|
# Table name: reviewables
|
|
#
|
|
# id :bigint not null, primary key
|
|
# type :string not null
|
|
# status :integer default("pending"), not null
|
|
# created_by_id :integer not null
|
|
# reviewable_by_moderator :boolean default(FALSE), not null
|
|
# category_id :integer
|
|
# topic_id :integer
|
|
# score :float default(0.0), not null
|
|
# potential_spam :boolean default(FALSE), not null
|
|
# target_id :integer
|
|
# target_type :string
|
|
# target_created_by_id :integer
|
|
# payload :json
|
|
# version :integer default(0), not null
|
|
# latest_score :datetime
|
|
# created_at :datetime not null
|
|
# updated_at :datetime not null
|
|
# force_review :boolean default(FALSE), not null
|
|
# reject_reason :text
|
|
# potentially_illegal :boolean default(FALSE)
|
|
#
|
|
# Indexes
|
|
#
|
|
# idx_reviewables_score_desc_created_at_desc (score,created_at)
|
|
# index_reviewables_on_reviewable_by_group_id (reviewable_by_group_id)
|
|
# index_reviewables_on_status_and_created_at (status,created_at)
|
|
# index_reviewables_on_status_and_score (status,score)
|
|
# index_reviewables_on_status_and_type (status,type)
|
|
# index_reviewables_on_target_id_where_post_type_eq_post (target_id) WHERE ((target_type)::text = 'Post'::text)
|
|
# index_reviewables_on_topic_id_and_status_and_created_by_id (topic_id,status,created_by_id)
|
|
# index_reviewables_on_type_and_target_id (type,target_id) UNIQUE
|
|
#
|