2014-03-05 20:52:20 +08:00
class BadgeGranter
def initialize ( badge , user , opts = { } )
@badge , @user , @opts = badge , user , opts
@granted_by = opts [ :granted_by ] || Discourse . system_user
end
def self . grant ( badge , user , opts = { } )
BadgeGranter . new ( badge , user , opts ) . grant
end
def grant
return if @granted_by and ! Guardian . new ( @granted_by ) . can_grant_badges? ( @user )
2014-04-14 13:58:27 +08:00
user_badge = UserBadge . find_by ( badge_id : @badge . id , user_id : @user . id )
2014-03-05 20:52:20 +08:00
2014-04-14 13:58:27 +08:00
unless user_badge
UserBadge . transaction do
user_badge = UserBadge . create! ( badge : @badge , user : @user ,
granted_by : @granted_by , granted_at : Time . now )
2014-03-05 20:52:20 +08:00
2014-04-14 13:58:27 +08:00
Badge . increment_counter 'grant_count' , @badge . id
if @granted_by != Discourse . system_user
StaffActionLogger . new ( @granted_by ) . log_badge_grant ( user_badge )
end
2014-04-17 03:59:45 +08:00
@user . notifications . create ( notification_type : Notification . types [ :granted_badge ] ,
data : { badge_id : @badge . id ,
badge_name : @badge . name } . to_json )
2014-03-20 03:30:12 +08:00
end
2014-03-05 20:52:20 +08:00
end
user_badge
end
2014-03-20 03:30:12 +08:00
def self . revoke ( user_badge , options = { } )
2014-03-05 20:52:20 +08:00
UserBadge . transaction do
user_badge . destroy!
2014-04-17 03:59:45 +08:00
Badge . decrement_counter 'grant_count' , user_badge . badge_id
2014-03-20 03:30:12 +08:00
if options [ :revoked_by ]
StaffActionLogger . new ( options [ :revoked_by ] ) . log_badge_revoke ( user_badge )
end
2014-04-18 11:10:53 +08:00
# If the user's title is the same as the badge name, remove their title.
if user_badge . user . title == user_badge . badge . name
user_badge . user . title = nil
user_badge . user . save!
end
# Delete notification -- This is inefficient, but not very easy to optimize
# unless the data hash is converted into a hstore.
2014-04-17 03:59:45 +08:00
notification = user_badge . user . notifications . where ( notification_type : Notification . types [ :granted_badge ] ) . where ( " data LIKE ? " , " % " + user_badge . badge_id . to_s + " % " ) . select { | n | n . data_hash [ " badge_id " ] == user_badge . badge_id } . first
notification && notification . destroy
2014-03-05 20:52:20 +08:00
end
end
end