mirror of
https://github.com/discourse/discourse.git
synced 2026-08-08 17:53:55 +08:00
Currently the `content_localization_language_switcher` validation error
names prerequisite settings as plain text so admins have to search for
each one manually.
This change extends the `{{setting:...}}` marker from #40338 with a
multi-setting form: `{{settings:one,two|label}}`. This renders a single
link to a filtered view of all the referenced settings.
The error message now links each required setting inline plus an "All
required settings" link. The admin UI receives an HTML message (and
plain text is still provided elsewhere, like the API).
<img width="1408" height="464" alt="image"
src="https://github.com/user-attachments/assets/576bcd79-daf1-4bd7-84ec-2add4db27f85"
/>
All settings are shown with an OR search prefixed by `any:` so
pipe-delineated settings can still be searched for separately
`any:content_localization_language_switcher|set_locale_from_cookie|allow_user_locale|content_localization_supported_locales`
<img width="2318" height="1706" alt="image"
src="https://github.com/user-attachments/assets/332092de-8d7c-4935-9e08-c3cb38a38fad"
/>
166 lines
5.4 KiB
Ruby
Vendored
166 lines
5.4 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
class Admin::SiteSettingsController < Admin::AdminController
|
|
rescue_from Discourse::InvalidParameters do |e|
|
|
render_json_error e.message, status: 422
|
|
end
|
|
|
|
rescue_from Discourse::InvalidHTMLParameters do |e|
|
|
render_json_error e.html_message, html_message: true, status: 422
|
|
end
|
|
|
|
def index
|
|
params.permit(:categories, :plugin, :names)
|
|
render_json_dump(
|
|
site_settings:
|
|
SiteSetting.all_settings(
|
|
filter_categories: params[:categories],
|
|
filter_plugin: params[:plugin],
|
|
filter_names: params[:names],
|
|
),
|
|
default_theme:
|
|
BasicThemeSerializer.new(Theme.find_default, scope: guardian, root: false).as_json,
|
|
)
|
|
end
|
|
|
|
def update
|
|
id = params.require(:id)
|
|
|
|
if id === "bulk_update"
|
|
settings =
|
|
params[:settings].to_unsafe_h.map do |setting_name, config|
|
|
{ setting_name:, value: config[:value], backfill: config[:backfill] }
|
|
end
|
|
else
|
|
backfill = params[:update_existing_user]
|
|
settings = [{ setting_name: id, value: params[id], backfill: }]
|
|
end
|
|
|
|
SiteSetting::Update.call(
|
|
guardian:,
|
|
params: {
|
|
settings:,
|
|
},
|
|
options: {
|
|
# TODO: remove once the site setting is no longer hidden
|
|
allow_changing_hidden: %i[enable_site_owner_onboarding],
|
|
},
|
|
) do
|
|
on_success { head :no_content }
|
|
on_exceptions do |e|
|
|
raise e if e.is_a?(Discourse::InvalidParameters)
|
|
raise Discourse::InvalidParameters, e.message
|
|
end
|
|
on_failed_policy(:settings_are_not_deprecated) do |policy|
|
|
raise Discourse::InvalidParameters, policy.reason
|
|
end
|
|
on_failed_policy(:settings_are_visible) do |policy|
|
|
raise Discourse::InvalidParameters, policy.reason
|
|
end
|
|
on_failed_policy(:settings_are_unshadowed_globally) do |policy|
|
|
raise Discourse::InvalidParameters, policy.reason
|
|
end
|
|
on_failed_policy(:settings_are_configurable) do |policy|
|
|
raise Discourse::InvalidParameters, policy.reason
|
|
end
|
|
end
|
|
end
|
|
|
|
def user_count
|
|
params.require(:site_setting_id)
|
|
id = params[:site_setting_id]
|
|
raise Discourse::NotFound unless id.start_with?("default_")
|
|
raise Discourse::NotFound unless SiteSetting.has_setting?(id)
|
|
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 = SiteSettingUpdateExistingUsers.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 = SiteSettingUpdateExistingUsers.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 = SiteSettingUpdateExistingUsers.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 SiteSettingUpdateExistingUsers.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 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 value_or_default(value)
|
|
value.nil? ? "" : value
|
|
end
|
|
end
|