mirror of
https://github.com/discourse/discourse.git
synced 2024-11-23 06:29:30 +08:00
1ea19a4d51
Since the "users" table is already added in the "includes" method it gives unexpected results while using it again in the "joins" method.
124 lines
4.6 KiB
Ruby
124 lines
4.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class DirectoryItemsController < ApplicationController
|
|
PAGE_SIZE = 50
|
|
|
|
def index
|
|
raise Discourse::InvalidAccess.new(:enable_user_directory) unless SiteSetting.enable_user_directory?
|
|
|
|
period = params.require(:period)
|
|
period_type = DirectoryItem.period_types[period.to_sym]
|
|
raise Discourse::InvalidAccess.new(:period_type) unless period_type
|
|
result = DirectoryItem.where(period_type: period_type).includes(user: :user_custom_fields)
|
|
|
|
if params[:group]
|
|
group = Group.find_by(name: params[:group])
|
|
raise Discourse::InvalidParameters.new(:group) if group.blank?
|
|
guardian.ensure_can_see!(group)
|
|
guardian.ensure_can_see_group_members!(group)
|
|
|
|
result = result.includes(user: :groups).where(users: { groups: { id: group.id } })
|
|
else
|
|
result = result.includes(user: :primary_group)
|
|
end
|
|
|
|
if params[:exclude_usernames]
|
|
result = result.references(:user).where.not(users: { username: params[:exclude_usernames].split(",") })
|
|
end
|
|
|
|
order = params[:order] || DirectoryColumn.automatic_column_names.first
|
|
dir = params[:asc] ? 'ASC' : 'DESC'
|
|
active_directory_column_names = DirectoryColumn.active_column_names
|
|
if active_directory_column_names.include?(order.to_sym)
|
|
result = result.order("directory_items.#{order} #{dir}, directory_items.id")
|
|
elsif params[:order] === 'username'
|
|
result = result.order("users.#{order} #{dir}, directory_items.id")
|
|
else
|
|
# Ordering by user field value
|
|
user_field = UserField.find_by(name: params[:order])
|
|
if user_field
|
|
result = result
|
|
.references(:user)
|
|
.joins("LEFT OUTER JOIN user_custom_fields ON user_custom_fields.user_id = users.id AND user_custom_fields.name = 'user_field_#{user_field.id}'")
|
|
.order("user_custom_fields.name = 'user_field_#{user_field.id}' ASC, user_custom_fields.value #{dir}")
|
|
end
|
|
end
|
|
|
|
if period_type == DirectoryItem.period_types[:all]
|
|
result = result.includes(:user_stat)
|
|
end
|
|
page = params[:page].to_i
|
|
|
|
user_ids = nil
|
|
if params[:name].present?
|
|
user_ids = UserSearch.new(params[:name], include_staged_users: true).search.pluck(:id)
|
|
if user_ids.present?
|
|
# Add the current user if we have at least one other match
|
|
if current_user && result.dup.where(user_id: user_ids).exists?
|
|
user_ids << current_user.id
|
|
end
|
|
result = result.where(user_id: user_ids)
|
|
else
|
|
result = result.where('false')
|
|
end
|
|
end
|
|
|
|
if params[:username]
|
|
user_id = User.where(username_lower: params[:username].to_s.downcase).pluck_first(:id)
|
|
if user_id
|
|
result = result.where(user_id: user_id)
|
|
else
|
|
result = result.where('false')
|
|
end
|
|
end
|
|
|
|
result_count = result.count
|
|
result = result.limit(PAGE_SIZE).offset(PAGE_SIZE * page).to_a
|
|
|
|
more_params = params.slice(:period, :order, :asc, :group, :user_field_ids).permit!
|
|
more_params[:page] = page + 1
|
|
load_more_uri = URI.parse(directory_items_path(more_params))
|
|
load_more_directory_items_json = "#{load_more_uri.path}.json?#{load_more_uri.query}"
|
|
|
|
# Put yourself at the top of the first page
|
|
if result.present? && current_user.present? && page == 0 && !params[:group].present?
|
|
|
|
position = result.index { |r| r.user_id == current_user.id }
|
|
|
|
# Don't show the record unless you're not in the top positions already
|
|
if (position || 10) >= 10
|
|
your_item = DirectoryItem.where(period_type: period_type, user_id: current_user.id).first
|
|
result.insert(0, your_item) if your_item
|
|
end
|
|
|
|
end
|
|
|
|
last_updated_at = DirectoryItem.last_updated_at(period_type)
|
|
|
|
serializer_opts = {}
|
|
if params[:user_field_ids]
|
|
serializer_opts[:user_custom_field_map] = {}
|
|
|
|
user_field_ids = params[:user_field_ids]&.split("|")&.map(&:to_i)
|
|
user_field_ids.each do |user_field_id|
|
|
serializer_opts[:user_custom_field_map]["#{User::USER_FIELD_PREFIX}#{user_field_id}"] = user_field_id
|
|
end
|
|
end
|
|
|
|
if params[:plugin_column_ids]
|
|
serializer_opts[:plugin_column_ids] = params[:plugin_column_ids]&.split("|")&.map(&:to_i)
|
|
end
|
|
|
|
serializer_opts[:attributes] = active_directory_column_names
|
|
|
|
serialized = serialize_data(result, DirectoryItemSerializer, serializer_opts)
|
|
render_json_dump(directory_items: serialized,
|
|
meta: {
|
|
last_updated_at: last_updated_at,
|
|
total_rows_directory_items: result_count,
|
|
load_more_directory_items: load_more_directory_items_json
|
|
}
|
|
)
|
|
end
|
|
end
|