mirror of
https://github.com/discourse/discourse.git
synced 2024-12-01 04:53:51 +08:00
90a3fbc07b
* DEV: Remove HTML setting type and sanitization logic. We concluded that we don't want settings to contain HTML, so I'm removing the setting type and sanitization logic. Additionally, we no longer allow the global-notice text to contain HTML. I searched for usages of this setting type in the `all-the-plugins` repo and found none, so I haven't added a migration for existing settings. * Mark Global notices containing links as HTML Safe.
237 lines
9.5 KiB
Ruby
237 lines
9.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class Admin::SiteSettingsController < Admin::AdminController
|
|
rescue_from Discourse::InvalidParameters do |e|
|
|
render_json_error e.message, status: 422
|
|
end
|
|
|
|
def index
|
|
render_json_dump(
|
|
site_settings: SiteSetting.all_settings,
|
|
diags: SiteSetting.diags
|
|
)
|
|
end
|
|
|
|
def update
|
|
params.require(:id)
|
|
id = params[:id]
|
|
value = params[id]
|
|
value.strip! if value.is_a?(String)
|
|
|
|
new_setting_name = SiteSettings::DeprecatedSettings::SETTINGS.find do |old_name, new_name, _, _|
|
|
break new_name if old_name == id
|
|
end
|
|
id = new_setting_name if new_setting_name
|
|
|
|
raise_access_hidden_setting(id)
|
|
|
|
if SiteSetting.type_supervisor.get_type(id) == :uploaded_image_list
|
|
value = Upload.get_from_urls(value.split("|")).to_a
|
|
end
|
|
|
|
if SiteSetting.type_supervisor.get_type(id) == :upload
|
|
value = Upload.get_from_url(value) || ""
|
|
end
|
|
|
|
update_existing_users = params[:update_existing_user].present?
|
|
previous_value = SiteSetting.send(id) || "" if update_existing_users
|
|
|
|
SiteSetting.set_and_log(id, value, current_user)
|
|
|
|
if update_existing_users
|
|
new_value = value || ""
|
|
|
|
if (user_option = user_options[id.to_sym]).present?
|
|
if user_option == "text_size_key"
|
|
previous_value = UserOption.text_sizes[previous_value.to_sym]
|
|
new_value = UserOption.text_sizes[new_value.to_sym]
|
|
elsif user_option == "title_count_mode_key"
|
|
previous_value = UserOption.title_count_modes[previous_value.to_sym]
|
|
new_value = UserOption.title_count_modes[new_value.to_sym]
|
|
end
|
|
|
|
attrs = { user_option => new_value }
|
|
attrs[:email_digests] = (new_value.to_i != 0) if id == "default_email_digest_frequency"
|
|
|
|
UserOption.where(user_option => previous_value).update_all(attrs)
|
|
elsif id.start_with?("default_categories_")
|
|
previous_category_ids = previous_value.split("|")
|
|
new_category_ids = new_value.split("|")
|
|
|
|
case id
|
|
when "default_categories_watching"
|
|
notification_level = NotificationLevels.all[:watching]
|
|
when "default_categories_tracking"
|
|
notification_level = NotificationLevels.all[:tracking]
|
|
when "default_categories_muted"
|
|
notification_level = NotificationLevels.all[:muted]
|
|
when "default_categories_watching_first_post"
|
|
notification_level = NotificationLevels.all[:watching_first_post]
|
|
when "default_categories_regular"
|
|
notification_level = NotificationLevels.all[:regular]
|
|
end
|
|
|
|
categories_to_unwatch = previous_category_ids - new_category_ids
|
|
CategoryUser.where(category_id: categories_to_unwatch, notification_level: notification_level).delete_all
|
|
TopicUser
|
|
.joins(:topic)
|
|
.where(notification_level: TopicUser.notification_levels[:watching],
|
|
notifications_reason_id: TopicUser.notification_reasons[:auto_watch_category],
|
|
topics: { category_id: categories_to_unwatch })
|
|
.update_all(notification_level: TopicUser.notification_levels[:regular])
|
|
|
|
(new_category_ids - previous_category_ids).each do |category_id|
|
|
skip_user_ids = CategoryUser.where(category_id: category_id).pluck(:user_id)
|
|
|
|
User.real.where(staged: false).where.not(id: skip_user_ids).select(:id).find_in_batches do |users|
|
|
category_users = []
|
|
users.each { |user| category_users << { category_id: category_id, user_id: user.id, notification_level: notification_level } }
|
|
CategoryUser.insert_all!(category_users)
|
|
end
|
|
end
|
|
elsif id.start_with?("default_tags_")
|
|
previous_tag_ids = Tag.where(name: previous_value.split("|")).pluck(:id)
|
|
new_tag_ids = Tag.where(name: new_value.split("|")).pluck(:id)
|
|
now = Time.zone.now
|
|
|
|
case id
|
|
when "default_tags_watching"
|
|
notification_level = NotificationLevels.all[:watching]
|
|
when "default_tags_tracking"
|
|
notification_level = NotificationLevels.all[:tracking]
|
|
when "default_tags_muted"
|
|
notification_level = NotificationLevels.all[:muted]
|
|
when "default_tags_watching_first_post"
|
|
notification_level = NotificationLevels.all[:watching_first_post]
|
|
end
|
|
|
|
TagUser.where(tag_id: (previous_tag_ids - new_tag_ids), notification_level: notification_level).delete_all
|
|
|
|
(new_tag_ids - previous_tag_ids).each do |tag_id|
|
|
skip_user_ids = TagUser.where(tag_id: tag_id).pluck(:user_id)
|
|
|
|
User.real.where(staged: false).where.not(id: skip_user_ids).select(:id).find_in_batches do |users|
|
|
tag_users = []
|
|
users.each { |user| tag_users << { tag_id: tag_id, user_id: user.id, notification_level: notification_level, created_at: now, updated_at: now } }
|
|
TagUser.insert_all!(tag_users)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
render body: nil
|
|
end
|
|
|
|
def user_count
|
|
params.require(:site_setting_id)
|
|
id = params[:site_setting_id]
|
|
raise Discourse::NotFound unless id.start_with?("default_")
|
|
new_value = params[id] || ""
|
|
|
|
raise_access_hidden_setting(id)
|
|
previous_value = SiteSetting.send(id) || ""
|
|
json = {}
|
|
|
|
if (user_option = user_options[id.to_sym]).present?
|
|
if user_option == "text_size_key"
|
|
previous_value = UserOption.text_sizes[previous_value.to_sym]
|
|
elsif user_option == "title_count_mode_key"
|
|
previous_value = UserOption.title_count_modes[previous_value.to_sym]
|
|
end
|
|
|
|
json[:user_count] = UserOption.where(user_option => previous_value).count
|
|
elsif id.start_with?("default_categories_")
|
|
previous_category_ids = previous_value.split("|")
|
|
new_category_ids = new_value.split("|")
|
|
|
|
case id
|
|
when "default_categories_watching"
|
|
notification_level = NotificationLevels.all[:watching]
|
|
when "default_categories_tracking"
|
|
notification_level = NotificationLevels.all[:tracking]
|
|
when "default_categories_muted"
|
|
notification_level = NotificationLevels.all[:muted]
|
|
when "default_categories_watching_first_post"
|
|
notification_level = NotificationLevels.all[:watching_first_post]
|
|
when "default_categories_regular"
|
|
notification_level = NotificationLevels.all[:regular]
|
|
end
|
|
|
|
user_ids = CategoryUser.where(category_id: previous_category_ids - new_category_ids, notification_level: notification_level).distinct.pluck(:user_id)
|
|
user_ids += User
|
|
.real
|
|
.joins("CROSS JOIN categories c")
|
|
.joins("LEFT JOIN category_users cu ON users.id = cu.user_id AND c.id = cu.category_id")
|
|
.where(staged: false)
|
|
.where("c.id IN (?) AND cu.notification_level IS NULL", new_category_ids - previous_category_ids)
|
|
.distinct
|
|
.pluck("users.id")
|
|
|
|
json[:user_count] = user_ids.uniq.count
|
|
elsif id.start_with?("default_tags_")
|
|
previous_tag_ids = Tag.where(name: previous_value.split("|")).pluck(:id)
|
|
new_tag_ids = Tag.where(name: new_value.split("|")).pluck(:id)
|
|
|
|
case id
|
|
when "default_tags_watching"
|
|
notification_level = TagUser.notification_levels[:watching]
|
|
when "default_tags_tracking"
|
|
notification_level = TagUser.notification_levels[:tracking]
|
|
when "default_tags_muted"
|
|
notification_level = TagUser.notification_levels[:muted]
|
|
when "default_tags_watching_first_post"
|
|
notification_level = TagUser.notification_levels[:watching_first_post]
|
|
end
|
|
|
|
user_ids = TagUser.where(tag_id: previous_tag_ids - new_tag_ids, notification_level: notification_level).distinct.pluck(:user_id)
|
|
user_ids += User
|
|
.real
|
|
.joins("CROSS JOIN tags t")
|
|
.joins("LEFT JOIN tag_users tu ON users.id = tu.user_id AND t.id = tu.tag_id")
|
|
.where(staged: false)
|
|
.where("t.id IN (?) AND tu.notification_level IS NULL", new_tag_ids - previous_tag_ids)
|
|
.distinct
|
|
.pluck("users.id")
|
|
|
|
json[:user_count] = user_ids.uniq.count
|
|
end
|
|
|
|
render json: json
|
|
end
|
|
|
|
private
|
|
|
|
def user_options
|
|
{
|
|
default_email_mailing_list_mode: "mailing_list_mode",
|
|
default_email_mailing_list_mode_frequency: "mailing_list_mode_frequency",
|
|
default_email_level: "email_level",
|
|
default_email_messages_level: "email_messages_level",
|
|
default_topics_automatic_unpin: "automatically_unpin_topics",
|
|
default_email_previous_replies: "email_previous_replies",
|
|
default_email_in_reply_to: "email_in_reply_to",
|
|
default_other_enable_quoting: "enable_quoting",
|
|
default_other_enable_defer: "enable_defer",
|
|
default_other_external_links_in_new_tab: "external_links_in_new_tab",
|
|
default_other_dynamic_favicon: "dynamic_favicon",
|
|
default_other_new_topic_duration_minutes: "new_topic_duration_minutes",
|
|
default_other_auto_track_topics_after_msecs: "auto_track_topics_after_msecs",
|
|
default_other_notification_level_when_replying: "notification_level_when_replying",
|
|
default_other_like_notification_frequency: "like_notification_frequency",
|
|
default_other_skip_new_user_tips: "skip_new_user_tips",
|
|
default_email_digest_frequency: "digest_after_minutes",
|
|
default_include_tl0_in_digests: "include_tl0_in_digests",
|
|
default_text_size: "text_size_key",
|
|
default_title_count_mode: "title_count_mode_key"
|
|
}
|
|
end
|
|
|
|
def raise_access_hidden_setting(id)
|
|
# note, as of Ruby 2.3 symbols are GC'd so this is considered safe
|
|
if SiteSetting.hidden_settings.include?(id.to_sym)
|
|
raise Discourse::InvalidParameters, "You are not allowed to change hidden settings"
|
|
end
|
|
end
|
|
|
|
end
|