mirror of
https://github.com/discourse/discourse.git
synced 2025-02-12 23:23:59 +08:00
![Martin Brennan](/assets/img/avatar_default.png)
Unless we have specified `override = true` in the DeprecatedSettings class for an old -> new settings map, we should not allow people to change the old setting in the UI and have it affect the new setting.
233 lines
8.9 KiB
Ruby
233 lines
8.9 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, override, _|
|
|
if old_name == id
|
|
if !override
|
|
raise Discourse::InvalidParameters, "You cannot change this site setting because it is deprecated, use #{new_name} instead."
|
|
end
|
|
break new_name
|
|
end
|
|
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 = value_or_default(SiteSetting.public_send(id)) if update_existing_users
|
|
|
|
SiteSetting.set_and_log(id, value, current_user)
|
|
|
|
if update_existing_users
|
|
new_value = value_or_default(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.human_users.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("|")
|
|
|
|
notification_level = category_notification_level(id)
|
|
|
|
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
|
|
|
|
notification_level = tag_notification_level(id)
|
|
|
|
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 = value_or_default(params[id])
|
|
|
|
raise_access_hidden_setting(id)
|
|
previous_value = value_or_default(SiteSetting.public_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.human_users.where(user_option => previous_value).count
|
|
elsif id.start_with?("default_categories_")
|
|
previous_category_ids = previous_value.split("|")
|
|
new_category_ids = new_value.split("|")
|
|
|
|
notification_level = category_notification_level(id)
|
|
|
|
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)
|
|
|
|
notification_level = tag_notification_level(id)
|
|
|
|
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
|
|
|
|
def tag_notification_level(id)
|
|
case id
|
|
when "default_tags_watching"
|
|
NotificationLevels.all[:watching]
|
|
when "default_tags_tracking"
|
|
NotificationLevels.all[:tracking]
|
|
when "default_tags_muted"
|
|
NotificationLevels.all[:muted]
|
|
when "default_tags_watching_first_post"
|
|
NotificationLevels.all[:watching_first_post]
|
|
end
|
|
end
|
|
|
|
def category_notification_level(id)
|
|
case id
|
|
when "default_categories_watching"
|
|
NotificationLevels.all[:watching]
|
|
when "default_categories_tracking"
|
|
NotificationLevels.all[:tracking]
|
|
when "default_categories_muted"
|
|
NotificationLevels.all[:muted]
|
|
when "default_categories_watching_first_post"
|
|
NotificationLevels.all[:watching_first_post]
|
|
when "default_categories_normal"
|
|
NotificationLevels.all[:regular]
|
|
end
|
|
end
|
|
|
|
def value_or_default(value)
|
|
value.nil? ? "" : value
|
|
end
|
|
end
|