mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-23 23:58:31 -05:00
3829c78526
As it stands we load up user records quite frequently on the topic pages, this in turn pulls all the columns for the users being selected, just to discard them after they are loaded New structure keeps all options in a discrete table, this is better organised and allows us to easily add more column without worrying about bloating the user table
120 lines
3.7 KiB
Ruby
120 lines
3.7 KiB
Ruby
class UserUpdater
|
|
|
|
CATEGORY_IDS = {
|
|
watched_category_ids: :watching,
|
|
tracked_category_ids: :tracking,
|
|
muted_category_ids: :muted
|
|
}
|
|
|
|
OPTION_ATTR = [
|
|
:email_always,
|
|
:mailing_list_mode,
|
|
:email_digests,
|
|
:email_direct,
|
|
:email_private_messages,
|
|
:external_links_in_new_tab,
|
|
:enable_quoting,
|
|
:dynamic_favicon,
|
|
:disable_jump_reply,
|
|
:edit_history_public,
|
|
:automatically_unpin_topics,
|
|
:digest_after_days
|
|
]
|
|
|
|
def initialize(actor, user)
|
|
@user = user
|
|
@guardian = Guardian.new(actor)
|
|
end
|
|
|
|
def update(attributes = {})
|
|
user_profile = user.user_profile
|
|
user_profile.location = attributes[:location]
|
|
user_profile.dismissed_banner_key = attributes[:dismissed_banner_key] if attributes[:dismissed_banner_key].present?
|
|
user_profile.website = format_url(attributes.fetch(:website) { user_profile.website })
|
|
user_profile.bio_raw = attributes.fetch(:bio_raw) { user_profile.bio_raw }
|
|
user_profile.profile_background = attributes.fetch(:profile_background) { user_profile.profile_background }
|
|
user_profile.card_background = attributes.fetch(:card_background) { user_profile.card_background }
|
|
|
|
user.name = attributes.fetch(:name) { user.name }
|
|
user.locale = attributes.fetch(:locale) { user.locale }
|
|
|
|
if attributes[:auto_track_topics_after_msecs]
|
|
user.auto_track_topics_after_msecs = attributes[:auto_track_topics_after_msecs].to_i
|
|
end
|
|
|
|
if attributes[:new_topic_duration_minutes]
|
|
user.new_topic_duration_minutes = attributes[:new_topic_duration_minutes].to_i
|
|
end
|
|
|
|
if guardian.can_grant_title?(user)
|
|
user.title = attributes.fetch(:title) { user.title }
|
|
end
|
|
|
|
CATEGORY_IDS.each do |attribute, level|
|
|
if ids = attributes[attribute]
|
|
CategoryUser.batch_set(user, level, ids)
|
|
end
|
|
end
|
|
|
|
|
|
save_options = false
|
|
OPTION_ATTR.each do |attribute|
|
|
if attributes[attribute].present?
|
|
save_options = true
|
|
|
|
|
|
if [true,false].include?(user.user_option.send(attribute))
|
|
val = attributes[attribute].to_s == 'true'
|
|
user.user_option.send("#{attribute}=", val)
|
|
else
|
|
user.user_option.send("#{attribute}=", attributes[attribute])
|
|
end
|
|
end
|
|
end
|
|
|
|
fields = attributes[:custom_fields]
|
|
if fields.present?
|
|
user.custom_fields = user.custom_fields.merge(fields)
|
|
end
|
|
|
|
User.transaction do
|
|
if attributes.key?(:muted_usernames)
|
|
update_muted_users(attributes[:muted_usernames])
|
|
end
|
|
|
|
(!save_options || user.user_option.save) && user_profile.save && user.save
|
|
end
|
|
end
|
|
|
|
def update_muted_users(usernames)
|
|
usernames ||= ""
|
|
desired_ids = User.where(username: usernames.split(",")).pluck(:id)
|
|
if desired_ids.empty?
|
|
MutedUser.where(user_id: user.id).destroy_all
|
|
else
|
|
MutedUser.where('user_id = ? AND muted_user_id not in (?)', user.id, desired_ids).destroy_all
|
|
|
|
# SQL is easier here than figuring out how to do the same in AR
|
|
MutedUser.exec_sql("INSERT into muted_users(user_id, muted_user_id, created_at, updated_at)
|
|
SELECT :user_id, id, :now, :now
|
|
FROM users
|
|
WHERE
|
|
id in (:desired_ids) AND
|
|
id NOT IN (
|
|
SELECT muted_user_id
|
|
FROM muted_users
|
|
WHERE user_id = :user_id
|
|
)",
|
|
now: Time.now, user_id: user.id, desired_ids: desired_ids)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
attr_reader :user, :guardian
|
|
|
|
def format_url(website)
|
|
return nil if website.blank?
|
|
website =~ /^http/ ? website : "http://#{website}"
|
|
end
|
|
end
|