Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEV: move post flags into database #26951

Merged
merged 10 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,19 @@ export default Component.extend({

@discourseComputed("flag.name_key")
customPlaceholder(nameKey) {
return I18n.t("flagging.custom_placeholder_" + nameKey);
return I18n.t("flagging.custom_placeholder_" + nameKey, {
defaultValue: I18n.t("flagging.custom_placeholder_notify_moderators"),
});
},

@discourseComputed("flag.name", "flag.name_key", "username")
formattedName(name, nameKey, username) {
if (["notify_user", "notify_moderators"].includes(nameKey)) {
return name.replace(/{{username}}|%{username}/, username);
} else {
return I18n.t("flagging.formatted_name." + nameKey);
return I18n.t("flagging.formatted_name." + nameKey, {
defaultValue: name,
});
}
},

Expand Down
6 changes: 5 additions & 1 deletion app/assets/javascripts/discourse/app/lib/transform-post.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,11 @@ export default function transformPost(
postId: post.id,
action,
canUndo: a.can_undo,
description: I18n.t(`post.actions.by_you.${action}`),
description: I18n.t(`post.actions.by_you.${action}`, {
defaultValue: I18n.t(`post.actions.by_you.custom`, {
custom: a.actionType.name,
}),
}),
};
});
}
Expand Down
61 changes: 61 additions & 0 deletions app/models/flag.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# frozen_string_literal: true

class Flag < ActiveRecord::Base
scope :enabled, -> { where(enabled: true) }
lis2 marked this conversation as resolved.
Show resolved Hide resolved
scope :system, -> { where("id < 1000") }

before_save :set_position
before_save :set_name_key
after_save :reset_flag_settings!
after_destroy :reset_flag_settings!

def used?
PostAction.exists?(post_action_type_id: self.id) ||
ReviewableScore.exists?(reviewable_score_type: self.id)
end

def self.reset_flag_settings!
PostActionType.reload_types
lis2 marked this conversation as resolved.
Show resolved Hide resolved
ReviewableScore.reload_types
end

def system?
self.id < 1000
end

def applies_to?(type)
self.applies_to.include?(type)
end

private

def reset_flag_settings!
self.class.reset_flag_settings!
end

def set_position
self.position = Flag.maximum(:position).to_i + 1 if !self.position
martin-brennan marked this conversation as resolved.
Show resolved Hide resolved
end

def set_name_key
self.name_key = self.name.squeeze(" ").gsub(" ", "_").gsub(/[^\w]/, "").downcase
end
end

# == Schema Information
#
# Table name: flags
#
# id :bigint not null, primary key
# name :string
# name_key :string
# description :text
# notify_type :boolean default(FALSE), not null
# auto_action_type :boolean default(FALSE), not null
# custom_type :boolean default(FALSE), not null
# applies_to :string not null, is an Array
# position :integer not null
# enabled :boolean default(TRUE), not null
# created_at :datetime not null
# updated_at :datetime not null
#
43 changes: 18 additions & 25 deletions app/models/post_action_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def replace_flag_settings(settings)
if settings
@flag_settings = settings
else
initialize_flag_settings
reload_types
end
@types = nil
end
Expand Down Expand Up @@ -79,34 +79,27 @@ def is_flag?(sym)
flag_types.valid?(sym)
end

private

def initialize_flag_settings
def reload_types
@types = nil
@flag_settings = FlagSettings.new
@flag_settings.add(3, :off_topic, notify_type: true, auto_action_type: true)
@flag_settings.add(
4,
:inappropriate,
topic_type: true,
notify_type: true,
auto_action_type: true,
)
@flag_settings.add(8, :spam, topic_type: true, notify_type: true, auto_action_type: true)
@flag_settings.add(6, :notify_user, topic_type: false, notify_type: false, custom_type: true)
@flag_settings.add(
7,
:notify_moderators,
topic_type: true,
notify_type: true,
custom_type: true,
)
@flag_settings.add(10, :illegal, topic_type: true, notify_type: true, custom_type: true)
# When adding a new ID here, check that it doesn't clash with any added in
# `ReviewableScore.types`. You can thank me later.
Flag
.enabled
.order(:position)
.each do |flag|
@flag_settings.add(
flag.id,
flag.name_key.to_sym,
topic_type: flag.applies_to?("Topic"),
notify_type: flag.notify_type,
auto_action_type: flag.auto_action_type,
custom_type: flag.custom_type,
name: flag.name,
)
end
end
end

initialize_flag_settings
reload_types
end

# == Schema Information
Expand Down
12 changes: 6 additions & 6 deletions app/serializers/post_action_type_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,25 @@ def is_flag
end

def name
i18n("title")
i18n("title", default: object.class.flag_settings.names[object.id])
end

def description
i18n("description", tos_url: tos_url, base_path: Discourse.base_path)
i18n("description", vars: { tos_url: tos_url, base_path: Discourse.base_path })
end

def short_description
i18n("short_description", tos_url: tos_url, base_path: Discourse.base_path)
i18n("short_description", vars: { tos_url: tos_url, base_path: Discourse.base_path })
end

def name_key
PostActionType.types[object.id]
PostActionType.types[object.id].to_s
end

protected

def i18n(field, vars = nil)
def i18n(field, default: nil, vars: nil)
key = "post_action_types.#{name_key}.#{field}"
vars ? I18n.t(key, vars) : I18n.t(key)
vars ? I18n.t(key, vars, default: default) : I18n.t(key, default: default)
end
end
5 changes: 3 additions & 2 deletions app/serializers/reviewable_score_type_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ def type

# Allow us to share post action type translations for backwards compatibility
def title
I18n.t("post_action_types.#{ReviewableScore.types[id]}.title", default: nil) ||
I18n.t("reviewable_score_types.#{ReviewableScore.types[id]}.title")
I18n.t("post_action_types.#{type}.title", default: nil) ||
I18n.t("reviewable_score_types.#{type}.title", default: nil) ||
PostActionType.flag_settings.names[id]
end

def reviewable_priority
Expand Down
9 changes: 1 addition & 8 deletions app/serializers/site_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -350,13 +350,6 @@ def include_lazy_load_categories?
private

def ordered_flags(flags)
notify_moderators_type = PostActionType.flag_types[:notify_moderators]
types = flags

if notify_moderators_flag = types.index(notify_moderators_type)
types.insert(types.length, types.delete_at(notify_moderators_flag))
end

types.map { |id| PostActionType.new(id: id) }
flags.map { |id| PostActionType.new(id: id) }
end
end
4 changes: 2 additions & 2 deletions app/serializers/topic_flag_type_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
class TopicFlagTypeSerializer < PostActionTypeSerializer
protected

def i18n(field, vars = nil)
def i18n(field, default: nil, vars: nil)
key = "topic_flag_types.#{name_key}.#{field}"
vars ? I18n.t(key, vars) : I18n.t(key)
vars ? I18n.t(key, vars, default: default) : I18n.t(key, default: default)
end
end
1 change: 1 addition & 0 deletions config/locales/client.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3748,6 +3748,7 @@ en:
illegal: "You flagged this as illegal"
notify_moderators: "You flagged this for moderation"
notify_user: "You sent a message to this user"
custom: "You flagged this topic as %{custom}"

delete:
confirm:
Expand Down
56 changes: 56 additions & 0 deletions db/fixtures/003_flags.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# frozen_string_literal: true

Flag.seed do |s|
lis2 marked this conversation as resolved.
Show resolved Hide resolved
s.id = 3
s.name = "off_topic"
s.position = 2
s.notify_type = true
s.auto_action_type = true
s.custom_type = false
s.applies_to = %w[Post Chat::Message]
end
Flag.seed do |s|
s.id = 4
s.name = "inappropriate"
s.position = 3
s.notify_type = true
s.auto_action_type = true
s.custom_type = false
s.applies_to = %w[Post Topic Chat::Message]
end
Flag.seed do |s|
s.id = 8
s.name = "spam"
s.position = 4
s.notify_type = true
s.auto_action_type = true
s.custom_type = false
s.applies_to = %w[Post Topic Chat::Message]
end
Flag.seed do |s|
s.id = 6
s.name = "notify_user"
s.position = 0
s.notify_type = false
s.auto_action_type = false
s.custom_type = true
s.applies_to = %w[Post Chat::Message]
end
Flag.seed do |s|
s.id = 7
s.name = "notify_moderators"
s.position = 1
s.notify_type = true
s.auto_action_type = false
s.custom_type = true
s.applies_to = %w[Post Topic Chat::Message]
end
Flag.seed do |s|
s.id = 10
s.name = "illegal"
s.position = 5
s.notify_type = true
s.auto_action_type = false
s.custom_type = true
s.applies_to = %w[Post Topic Chat::Message]
end
2 changes: 1 addition & 1 deletion db/migrate/20181031165343_add_flag_stats_to_user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def up
SUM(CASE WHEN pa.deferred_at IS NOT NULL THEN 1 ELSE 0 END) as flags_ignored
FROM post_actions AS pa
INNER JOIN users AS u ON u.id = pa.user_id
WHERE pa.post_action_type_id IN (#{PostActionType.notify_flag_types.values.join(", ")})
WHERE pa.post_action_type_id IN (3, 4, 8, 7, 10)
AND pa.user_id > 0
GROUP BY u.id
) AS x
Expand Down
19 changes: 19 additions & 0 deletions db/migrate/20240423054323_create_flags.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

class CreateFlags < ActiveRecord::Migration[7.0]
def change
create_table :flags do |t|
t.string :name, unique: true
lis2 marked this conversation as resolved.
Show resolved Hide resolved
t.string :name_key, unique: true
t.text :description
t.boolean :notify_type, default: false, null: false
t.boolean :auto_action_type, default: false, null: false
t.boolean :custom_type, default: false, null: false
lis2 marked this conversation as resolved.
Show resolved Hide resolved
t.string :applies_to, array: true, null: false
t.integer :position, null: false
t.boolean :enabled, default: true, null: false
t.timestamps
end
DB.exec("SELECT setval('flags_id_seq', 1001, FALSE);")
end
end
25 changes: 18 additions & 7 deletions lib/flag_settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class FlagSettings
:topic_flag_types,
:auto_action_types,
:custom_types,
:names,
)

def initialize
Expand All @@ -16,18 +17,28 @@ def initialize
@auto_action_types = Enum.new
@custom_types = Enum.new
@without_custom_types = Enum.new
@names = Enum.new
end

def add(id, name, topic_type: nil, notify_type: nil, auto_action_type: nil, custom_type: nil)
@all_flag_types[name] = id
@topic_flag_types[name] = id if !!topic_type
@notify_types[name] = id if !!notify_type
@auto_action_types[name] = id if !!auto_action_type
def add(
id,
name_key,
topic_type: nil,
notify_type: nil,
auto_action_type: nil,
custom_type: nil,
name: nil
)
@all_flag_types[name_key] = id
@topic_flag_types[name_key] = id if !!topic_type
@notify_types[name_key] = id if !!notify_type
@auto_action_types[name_key] = id if !!auto_action_type
@names[id] = name if name

if !!custom_type
@custom_types[name] = id
@custom_types[name_key] = id
else
@without_custom_types[name] = id
@without_custom_types[name_key] = id
end
end

Expand Down
2 changes: 2 additions & 0 deletions lib/guardian.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require "guardian/category_guardian"
require "guardian/ensure_magic"
require "guardian/group_guardian"
require "guardian/flag_guardian"
require "guardian/post_guardian"
require "guardian/post_revision_guardian"
require "guardian/sidebar_guardian"
Expand All @@ -16,6 +17,7 @@ class Guardian
include BookmarkGuardian
include CategoryGuardian
include EnsureMagic
include FlagGuardian
include GroupGuardian
include PostGuardian
include PostRevisionGuardian
Expand Down
7 changes: 7 additions & 0 deletions lib/guardian/flag_guardian.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

module FlagGuardian
def can_edit_flag?(flag)
@user.admin? && !flag.system? && !flag.used?
end
end