mirror of
https://github.com/discourse/discourse.git
synced 2024-11-28 07:13:44 +08: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
358 lines
8.4 KiB
Ruby
358 lines
8.4 KiB
Ruby
class UserSerializer < BasicUserSerializer
|
|
|
|
attr_accessor :omit_stats,
|
|
:topic_post_count
|
|
|
|
def self.staff_attributes(*attrs)
|
|
attributes(*attrs)
|
|
attrs.each do |attr|
|
|
define_method "include_#{attr}?" do
|
|
scope.is_staff?
|
|
end
|
|
end
|
|
end
|
|
|
|
def self.private_attributes(*attrs)
|
|
attributes(*attrs)
|
|
attrs.each do |attr|
|
|
define_method "include_#{attr}?" do
|
|
can_edit
|
|
end
|
|
end
|
|
end
|
|
|
|
# attributes that are hidden for TL0 users when seen by anonymous
|
|
def self.untrusted_attributes(*attrs)
|
|
attrs.each do |attr|
|
|
method_name = "include_#{attr}?"
|
|
define_method(method_name) do
|
|
return false if scope.restrict_user_fields?(object)
|
|
send(attr).present?
|
|
end
|
|
end
|
|
end
|
|
|
|
attributes :name,
|
|
:email,
|
|
:last_posted_at,
|
|
:last_seen_at,
|
|
:bio_raw,
|
|
:bio_cooked,
|
|
:created_at,
|
|
:website,
|
|
:website_name,
|
|
:profile_background,
|
|
:card_background,
|
|
:location,
|
|
:can_edit,
|
|
:can_edit_username,
|
|
:can_edit_email,
|
|
:can_edit_name,
|
|
:stats,
|
|
:can_send_private_messages,
|
|
:can_send_private_message_to_user,
|
|
:bio_excerpt,
|
|
:trust_level,
|
|
:moderator,
|
|
:admin,
|
|
:title,
|
|
:suspend_reason,
|
|
:suspended_till,
|
|
:uploaded_avatar_id,
|
|
:badge_count,
|
|
:has_title_badges,
|
|
:custom_fields,
|
|
:user_fields,
|
|
:topic_post_count,
|
|
:pending_count,
|
|
:profile_view_count
|
|
|
|
has_one :invited_by, embed: :object, serializer: BasicUserSerializer
|
|
has_many :groups, embed: :object, serializer: BasicGroupSerializer
|
|
has_many :featured_user_badges, embed: :ids, serializer: UserBadgeSerializer, root: :user_badges
|
|
has_one :card_badge, embed: :object, serializer: BadgeSerializer
|
|
has_one :user_option, embed: :object, serializer: UserOptionSerializer
|
|
|
|
def include_user_option?
|
|
can_edit
|
|
end
|
|
|
|
staff_attributes :post_count,
|
|
:can_be_deleted,
|
|
:can_delete_all_posts
|
|
|
|
private_attributes :locale,
|
|
:auto_track_topics_after_msecs,
|
|
:new_topic_duration_minutes,
|
|
:muted_category_ids,
|
|
:tracked_category_ids,
|
|
:watched_category_ids,
|
|
:private_messages_stats,
|
|
:system_avatar_upload_id,
|
|
:system_avatar_template,
|
|
:gravatar_avatar_upload_id,
|
|
:gravatar_avatar_template,
|
|
:custom_avatar_upload_id,
|
|
:custom_avatar_template,
|
|
:has_title_badges,
|
|
:card_image_badge,
|
|
:card_image_badge_id,
|
|
:muted_usernames
|
|
|
|
untrusted_attributes :bio_raw,
|
|
:bio_cooked,
|
|
:bio_excerpt,
|
|
:location,
|
|
:website,
|
|
:profile_background,
|
|
:card_background
|
|
|
|
###
|
|
### ATTRIBUTES
|
|
###
|
|
|
|
def groups
|
|
if scope.is_admin? || object.id == scope.user.try(:id)
|
|
object.groups
|
|
else
|
|
object.groups.where(visible: true)
|
|
end
|
|
end
|
|
|
|
def include_email?
|
|
object.id && object.id == scope.user.try(:id)
|
|
end
|
|
|
|
def card_badge
|
|
object.user_profile.card_image_badge
|
|
end
|
|
|
|
def bio_raw
|
|
object.user_profile.bio_raw
|
|
end
|
|
|
|
def bio_cooked
|
|
object.user_profile.bio_processed
|
|
end
|
|
|
|
def website
|
|
object.user_profile.website
|
|
end
|
|
|
|
def website_name
|
|
website_host = URI(website.to_s).host rescue nil
|
|
discourse_host = Discourse.current_hostname
|
|
return if website_host.nil?
|
|
if website_host == discourse_host
|
|
# example.com == example.com
|
|
website_host + URI(website.to_s).path
|
|
elsif (website_host.split('.').length == discourse_host.split('.').length) && discourse_host.split('.').length > 2
|
|
# www.example.com == forum.example.com
|
|
website_host.split('.')[1..-1].join('.') == discourse_host.split('.')[1..-1].join('.') ? website_host + URI(website.to_s).path : website_host
|
|
else
|
|
# example.com == forum.example.com
|
|
discourse_host.ends_with?("." << website_host) ? website_host + URI(website.to_s).path : website_host
|
|
end
|
|
end
|
|
|
|
def include_website_name
|
|
website.present?
|
|
end
|
|
|
|
def card_image_badge_id
|
|
object.user_profile.card_image_badge.try(:id)
|
|
end
|
|
|
|
def include_card_image_badge_id?
|
|
card_image_badge_id.present?
|
|
end
|
|
|
|
def card_image_badge
|
|
object.user_profile.card_image_badge.try(:image)
|
|
end
|
|
|
|
def include_card_image_badge?
|
|
card_image_badge.present?
|
|
end
|
|
|
|
def profile_background
|
|
object.user_profile.profile_background
|
|
end
|
|
|
|
def card_background
|
|
object.user_profile.card_background
|
|
end
|
|
|
|
def location
|
|
object.user_profile.location
|
|
end
|
|
|
|
def can_edit
|
|
scope.can_edit?(object)
|
|
end
|
|
|
|
def can_edit_username
|
|
scope.can_edit_username?(object)
|
|
end
|
|
|
|
def can_edit_email
|
|
scope.can_edit_email?(object)
|
|
end
|
|
|
|
def can_edit_name
|
|
scope.can_edit_name?(object)
|
|
end
|
|
|
|
def include_stats?
|
|
!omit_stats == true
|
|
end
|
|
|
|
def stats
|
|
UserAction.stats(object.id, scope)
|
|
end
|
|
|
|
# Needed because 'send_private_message_to_user' will always return false
|
|
# when the current user is being serialized
|
|
def can_send_private_messages
|
|
scope.can_send_private_message?(Discourse.system_user)
|
|
end
|
|
|
|
def can_send_private_message_to_user
|
|
scope.can_send_private_message?(object)
|
|
end
|
|
|
|
def bio_excerpt
|
|
object.user_profile.bio_excerpt(350 , { keep_newlines: true, keep_emoji_images: true })
|
|
end
|
|
|
|
def include_suspend_reason?
|
|
object.suspended?
|
|
end
|
|
|
|
def include_suspended_till?
|
|
object.suspended?
|
|
end
|
|
|
|
###
|
|
### STAFF ATTRIBUTES
|
|
###
|
|
|
|
def post_count
|
|
object.user_stat.try(:post_count)
|
|
end
|
|
|
|
def can_be_deleted
|
|
scope.can_delete_user?(object)
|
|
end
|
|
|
|
def can_delete_all_posts
|
|
scope.can_delete_all_posts?(object)
|
|
end
|
|
|
|
###
|
|
### PRIVATE ATTRIBUTES
|
|
###
|
|
|
|
def auto_track_topics_after_msecs
|
|
object.auto_track_topics_after_msecs || SiteSetting.default_other_auto_track_topics_after_msecs
|
|
end
|
|
|
|
def new_topic_duration_minutes
|
|
object.new_topic_duration_minutes || SiteSetting.default_other_new_topic_duration_minutes
|
|
end
|
|
|
|
def muted_category_ids
|
|
CategoryUser.lookup(object, :muted).pluck(:category_id)
|
|
end
|
|
|
|
def tracked_category_ids
|
|
CategoryUser.lookup(object, :tracking).pluck(:category_id)
|
|
end
|
|
|
|
def watched_category_ids
|
|
CategoryUser.lookup(object, :watching).pluck(:category_id)
|
|
end
|
|
|
|
def muted_usernames
|
|
MutedUser.where(user_id: object.id).joins(:muted_user).pluck(:username)
|
|
end
|
|
|
|
def include_private_messages_stats?
|
|
can_edit && !(omit_stats == true)
|
|
end
|
|
|
|
def private_messages_stats
|
|
UserAction.private_messages_stats(object.id, scope)
|
|
end
|
|
|
|
def system_avatar_upload_id
|
|
# should be left blank
|
|
end
|
|
|
|
def system_avatar_template
|
|
User.system_avatar_template(object.username)
|
|
end
|
|
|
|
def gravatar_avatar_upload_id
|
|
object.user_avatar.try(:gravatar_upload_id)
|
|
end
|
|
|
|
def gravatar_avatar_template
|
|
return unless gravatar_upload_id = object.user_avatar.try(:gravatar_upload_id)
|
|
User.avatar_template(object.username, gravatar_upload_id)
|
|
end
|
|
|
|
def custom_avatar_upload_id
|
|
object.user_avatar.try(:custom_upload_id)
|
|
end
|
|
|
|
def custom_avatar_template
|
|
return unless custom_upload_id = object.user_avatar.try(:custom_upload_id)
|
|
User.avatar_template(object.username, custom_upload_id)
|
|
end
|
|
|
|
def has_title_badges
|
|
object.badges.where(allow_title: true).count > 0
|
|
end
|
|
|
|
def user_fields
|
|
object.user_fields
|
|
end
|
|
|
|
def include_user_fields?
|
|
user_fields.present?
|
|
end
|
|
|
|
def include_topic_post_count?
|
|
topic_post_count.present?
|
|
end
|
|
|
|
def custom_fields
|
|
fields = nil
|
|
|
|
if scope.can_edit?(object)
|
|
fields = DiscoursePluginRegistry.serialized_current_user_fields.to_a
|
|
end
|
|
|
|
if SiteSetting.public_user_custom_fields.present?
|
|
fields ||= []
|
|
fields += SiteSetting.public_user_custom_fields.split('|')
|
|
end
|
|
|
|
if fields.present?
|
|
User.custom_fields_for_ids([object.id], fields)[object.id]
|
|
else
|
|
{}
|
|
end
|
|
end
|
|
|
|
def pending_count
|
|
0
|
|
end
|
|
|
|
def profile_view_count
|
|
object.user_profile.views
|
|
end
|
|
|
|
end
|