mirror of
https://github.com/discourse/discourse.git
synced 2024-11-23 21:10:17 +08:00
a08691a599
Settings that are using the new `file_size_restriction` types like the
`max_image_size_kb` setting need to have their values saved as integers.
This was a recent regression in 00209f03e6
that caused these values to be saved as strings.
This change also removes negatives from the validation regex because
file sizes can't be negative anyways.
Bug report: https://meta.discourse.org/t/289037
312 lines
11 KiB
Ruby
312 lines
11 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)
|
|
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)
|
|
|
|
case SiteSetting.type_supervisor.get_type(id)
|
|
when :integer
|
|
value = value.tr("^-0-9", "")
|
|
when :file_size_restriction
|
|
value = value.tr("^0-9", "").to_i
|
|
when :uploaded_image_list
|
|
value = Upload.get_from_urls(value.split("|")).to_a
|
|
end
|
|
|
|
value = Upload.get_from_url(value) || "" if SiteSetting.type_supervisor.get_type(id) == :upload
|
|
|
|
update_existing_users = params[:update_existing_user].present?
|
|
previous_value = value_or_default(SiteSetting.get(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 do |user|
|
|
category_users << {
|
|
category_id: category_id,
|
|
user_id: user.id,
|
|
notification_level: notification_level,
|
|
}
|
|
end
|
|
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 do |user|
|
|
tag_users << {
|
|
tag_id: tag_id,
|
|
user_id: user.id,
|
|
notification_level: notification_level,
|
|
created_at: now,
|
|
updated_at: now,
|
|
}
|
|
end
|
|
TagUser.insert_all!(tag_users)
|
|
end
|
|
end
|
|
elsif is_sidebar_default_setting?(id)
|
|
Jobs.enqueue(
|
|
:backfill_sidebar_site_settings,
|
|
setting_name: id,
|
|
previous_value: previous_value,
|
|
new_value: new_value,
|
|
)
|
|
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
|
|
elsif is_sidebar_default_setting?(id)
|
|
json[:user_count] = SidebarSiteSettingsBackfiller.new(
|
|
id,
|
|
previous_value: previous_value,
|
|
new_value: new_value,
|
|
).number_of_users_to_backfill
|
|
end
|
|
|
|
render json: json
|
|
end
|
|
|
|
private
|
|
|
|
def is_sidebar_default_setting?(setting_name)
|
|
%w[default_navigation_menu_categories default_navigation_menu_tags].include?(setting_name.to_s)
|
|
end
|
|
|
|
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",
|
|
default_hide_profile_and_presence: "hide_profile_and_presence",
|
|
default_sidebar_link_to_filtered_list: "sidebar_link_to_filtered_list",
|
|
default_sidebar_show_count_of_new_items: "sidebar_show_count_of_new_items",
|
|
}
|
|
end
|
|
|
|
def raise_access_hidden_setting(id)
|
|
id = id.to_sym
|
|
|
|
if SiteSetting.hidden_settings.include?(id)
|
|
raise Discourse::InvalidParameters, "You are not allowed to change hidden settings"
|
|
end
|
|
|
|
if SiteSetting.plugins[id] && !Discourse.plugins_by_name[SiteSetting.plugins[id]].configurable?
|
|
raise Discourse::InvalidParameters, "You are not allowed to change unconfigurable 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
|