2019-05-03 06:17:27 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2014-03-05 20:52:20 +08:00
|
|
|
class UserBadgesController < ApplicationController
|
2021-06-01 16:33:40 +08:00
|
|
|
MAX_BADGES = 96 # This was limited in PR#2360 to make it divisible by 8
|
|
|
|
|
2017-11-22 01:22:24 +08:00
|
|
|
before_action :ensure_badges_enabled
|
|
|
|
|
2014-03-05 20:52:20 +08:00
|
|
|
def index
|
2016-01-18 14:59:07 +08:00
|
|
|
params.permit [:granted_before, :offset, :username]
|
2014-08-26 01:38:20 +08:00
|
|
|
|
|
|
|
badge = fetch_badge_from_params
|
2021-06-01 16:33:40 +08:00
|
|
|
user_badges = badge.user_badges.order('granted_at DESC, id DESC').limit(MAX_BADGES)
|
2021-07-08 15:46:21 +08:00
|
|
|
user_badges = user_badges.includes(:user, :granted_by, badge: :badge_type, post: :topic, user: [:primary_group, :flair_group])
|
2014-04-22 17:40:47 +08:00
|
|
|
|
2016-01-18 14:59:07 +08:00
|
|
|
grant_count = nil
|
|
|
|
|
|
|
|
if params[:username]
|
2019-10-21 18:32:27 +08:00
|
|
|
user_id = User.where(username_lower: params[:username].downcase).pluck_first(:id)
|
2016-01-18 14:59:07 +08:00
|
|
|
user_badges = user_badges.where(user_id: user_id) if user_id
|
2016-03-05 07:57:32 +08:00
|
|
|
grant_count = badge.user_badges.where(user_id: user_id).count
|
2016-01-18 14:59:07 +08:00
|
|
|
end
|
|
|
|
|
2014-07-18 13:46:36 +08:00
|
|
|
if offset = params[:offset]
|
|
|
|
user_badges = user_badges.offset(offset.to_i)
|
2014-04-16 22:56:11 +08:00
|
|
|
end
|
2014-04-22 17:40:47 +08:00
|
|
|
|
2022-10-27 11:48:00 +08:00
|
|
|
user_badges_topic_ids = user_badges.map { |user_badge| user_badge.post&.topic_id }.compact
|
|
|
|
|
2016-01-18 14:59:07 +08:00
|
|
|
user_badges = UserBadges.new(user_badges: user_badges,
|
|
|
|
username: params[:username],
|
|
|
|
grant_count: grant_count)
|
|
|
|
|
2022-10-27 11:48:00 +08:00
|
|
|
render_serialized(
|
|
|
|
user_badges,
|
|
|
|
UserBadgesSerializer,
|
|
|
|
root: :user_badge_info,
|
|
|
|
include_long_description: true,
|
|
|
|
allowed_user_badge_topic_ids: guardian.can_see_topic_ids(topic_ids: user_badges_topic_ids)
|
|
|
|
)
|
2014-08-26 01:38:20 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def username
|
|
|
|
params.permit [:grouped]
|
|
|
|
|
2017-12-07 14:23:27 +08:00
|
|
|
user = fetch_user_from_params(include_inactive: current_user.try(:staff?) || (current_user && SiteSetting.show_inactive_accounts))
|
2020-06-03 21:33:02 +08:00
|
|
|
raise Discourse::NotFound unless guardian.can_see_profile?(user)
|
2015-09-25 08:20:47 +08:00
|
|
|
user_badges = user.user_badges
|
2014-04-22 17:40:47 +08:00
|
|
|
|
2014-06-10 09:23:18 +08:00
|
|
|
if params[:grouped]
|
2021-06-01 16:33:40 +08:00
|
|
|
user_badges = user_badges.group(:badge_id).select_for_grouping
|
2014-05-21 15:22:42 +08:00
|
|
|
end
|
|
|
|
|
2021-03-17 13:55:23 +08:00
|
|
|
user_badges = user_badges.includes(badge: [:badge_grouping, :badge_type, :image_upload])
|
2015-09-25 08:20:47 +08:00
|
|
|
.includes(post: :topic)
|
|
|
|
.includes(:granted_by)
|
|
|
|
|
2022-10-27 11:48:00 +08:00
|
|
|
user_badges_topic_ids = user_badges.map { |user_badge| user_badge.post&.topic_id }.compact
|
|
|
|
|
2021-06-01 16:33:40 +08:00
|
|
|
render_serialized(
|
|
|
|
user_badges,
|
|
|
|
DetailedUserBadgeSerializer,
|
2022-10-27 11:48:00 +08:00
|
|
|
allowed_user_badge_topic_ids: guardian.can_see_topic_ids(topic_ids: user_badges_topic_ids),
|
2021-06-01 16:33:40 +08:00
|
|
|
root: :user_badges,
|
|
|
|
)
|
2014-03-05 20:52:20 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def create
|
|
|
|
params.require(:username)
|
|
|
|
user = fetch_user_from_params
|
|
|
|
|
|
|
|
unless can_assign_badge_to_user?(user)
|
2018-11-29 01:01:41 +08:00
|
|
|
return render json: failed_json, status: 403
|
2014-03-05 20:52:20 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
badge = fetch_badge_from_params
|
2015-02-25 09:52:43 +08:00
|
|
|
post_id = nil
|
2014-03-05 20:52:20 +08:00
|
|
|
|
2015-02-25 09:52:43 +08:00
|
|
|
if params[:reason].present?
|
2018-11-29 01:01:41 +08:00
|
|
|
unless is_badge_reason_valid? params[:reason]
|
2018-12-31 17:46:39 +08:00
|
|
|
return render json: failed_json.merge(message: I18n.t('invalid_grant_badge_reason_link')), status: 400
|
2018-11-29 01:01:41 +08:00
|
|
|
end
|
|
|
|
|
2018-12-31 16:04:47 +08:00
|
|
|
if route = Discourse.route_for(params[:reason])
|
2020-06-29 18:31:20 +08:00
|
|
|
if route[:controller] == "topics" && route[:action] == "show"
|
|
|
|
topic_id = (route[:id] || route[:topic_id]).to_i
|
|
|
|
post_number = route[:post_number] || 1
|
|
|
|
post_id = Post.find_by(topic_id: topic_id, post_number: post_number)&.id if topic_id > 0
|
|
|
|
end
|
2015-02-25 09:52:43 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
user_badge = BadgeGranter.grant(badge, user, granted_by: current_user, post_id: post_id)
|
|
|
|
|
|
|
|
render_serialized(user_badge, DetailedUserBadgeSerializer, root: "user_badge")
|
2014-03-05 20:52:20 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def destroy
|
|
|
|
params.require(:id)
|
|
|
|
user_badge = UserBadge.find(params[:id])
|
|
|
|
|
|
|
|
unless can_assign_badge_to_user?(user_badge.user)
|
|
|
|
render json: failed_json, status: 403
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2014-03-20 03:30:12 +08:00
|
|
|
BadgeGranter.revoke(user_badge, revoked_by: current_user)
|
2014-03-05 20:52:20 +08:00
|
|
|
render json: success_json
|
|
|
|
end
|
|
|
|
|
2021-06-01 16:33:40 +08:00
|
|
|
def toggle_favorite
|
|
|
|
params.require(:user_badge_id)
|
|
|
|
user_badge = UserBadge.find(params[:user_badge_id])
|
|
|
|
user_badges = user_badge.user.user_badges
|
|
|
|
|
|
|
|
unless can_favorite_badge?(user_badge)
|
|
|
|
return render json: failed_json, status: 403
|
|
|
|
end
|
|
|
|
|
2021-06-23 19:41:23 +08:00
|
|
|
if !user_badge.is_favorite && user_badges.select(:badge_id).distinct.where(is_favorite: true).count >= SiteSetting.max_favorite_badges
|
2021-06-01 16:33:40 +08:00
|
|
|
return render json: failed_json, status: 400
|
|
|
|
end
|
|
|
|
|
2021-06-23 19:41:23 +08:00
|
|
|
UserBadge
|
|
|
|
.where(user_id: user_badge.user_id, badge_id: user_badge.badge_id)
|
2021-07-16 11:13:00 +08:00
|
|
|
.update_all(is_favorite: !user_badge.is_favorite)
|
2021-06-01 16:33:40 +08:00
|
|
|
UserBadge.update_featured_ranks!(user_badge.user_id)
|
|
|
|
end
|
|
|
|
|
2014-03-05 20:52:20 +08:00
|
|
|
private
|
|
|
|
|
|
|
|
# Get the badge from either the badge name or id specified in the params.
|
|
|
|
def fetch_badge_from_params
|
|
|
|
badge = nil
|
2018-06-07 13:28:18 +08:00
|
|
|
|
2014-03-05 20:52:20 +08:00
|
|
|
params.permit(:badge_name)
|
|
|
|
if params[:badge_name].nil?
|
|
|
|
params.require(:badge_id)
|
2014-07-14 15:40:01 +08:00
|
|
|
badge = Badge.find_by(id: params[:badge_id], enabled: true)
|
2014-03-05 20:52:20 +08:00
|
|
|
else
|
2014-07-14 15:40:01 +08:00
|
|
|
badge = Badge.find_by(name: params[:badge_name], enabled: true)
|
2014-03-05 20:52:20 +08:00
|
|
|
end
|
2015-05-07 09:00:51 +08:00
|
|
|
raise Discourse::NotFound if badge.blank?
|
2014-03-05 20:52:20 +08:00
|
|
|
|
|
|
|
badge
|
|
|
|
end
|
2017-11-22 01:22:24 +08:00
|
|
|
|
2014-03-05 20:52:20 +08:00
|
|
|
def can_assign_badge_to_user?(user)
|
|
|
|
master_api_call = current_user.nil? && is_api?
|
|
|
|
master_api_call || guardian.can_grant_badges?(user)
|
2018-06-07 13:28:18 +08:00
|
|
|
end
|
|
|
|
|
2021-06-01 16:33:40 +08:00
|
|
|
def can_favorite_badge?(user_badge)
|
|
|
|
current_user == user_badge.user && !(1..4).include?(user_badge.badge_id)
|
|
|
|
end
|
|
|
|
|
2017-11-22 01:22:24 +08:00
|
|
|
def ensure_badges_enabled
|
|
|
|
raise Discourse::NotFound unless SiteSetting.enable_badges?
|
|
|
|
end
|
2018-11-29 01:01:41 +08:00
|
|
|
|
|
|
|
def is_badge_reason_valid?(reason)
|
|
|
|
route = Discourse.route_for(reason)
|
|
|
|
route && (route[:controller] == 'posts' || route[:controller] == 'topics')
|
|
|
|
end
|
2014-03-05 20:52:20 +08:00
|
|
|
end
|