mirror of
https://github.com/discourse/discourse.git
synced 2025-02-23 07:40:54 +08:00

* FEATURE: set notification levels when added to a group This feature allows admins and group owners to define default category and tag tracking levels that will be applied to user preferences automatically at the time when users are added to the group. Users are free to change those preferences afterwards. When removed from a group, the user's notification preferences aren't changed.
152 lines
4.2 KiB
Ruby
152 lines
4.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class GroupUser < ActiveRecord::Base
|
|
belongs_to :group, counter_cache: "user_count"
|
|
belongs_to :user
|
|
|
|
after_save :update_title
|
|
after_destroy :grant_other_available_title
|
|
|
|
after_save :set_primary_group
|
|
after_destroy :remove_primary_group, :recalculate_trust_level
|
|
|
|
before_create :set_notification_level
|
|
after_save :grant_trust_level
|
|
after_save :set_category_notifications
|
|
after_save :set_tag_notifications
|
|
|
|
def self.notification_levels
|
|
NotificationLevels.all
|
|
end
|
|
|
|
protected
|
|
|
|
def set_notification_level
|
|
self.notification_level = group&.default_notification_level || 3
|
|
end
|
|
|
|
def set_primary_group
|
|
user.update!(primary_group: group) if group.primary_group
|
|
end
|
|
|
|
def remove_primary_group
|
|
DB.exec("
|
|
UPDATE users
|
|
SET primary_group_id = NULL
|
|
WHERE id = :user_id AND primary_group_id = :id",
|
|
id: group.id, user_id: user_id
|
|
)
|
|
end
|
|
|
|
def grant_other_available_title
|
|
if group.title.present? && group.title == user.title
|
|
user.update_attribute(:title, user.next_best_title)
|
|
end
|
|
end
|
|
|
|
def update_title
|
|
if group.title.present?
|
|
DB.exec("
|
|
UPDATE users SET title = :title
|
|
WHERE (title IS NULL OR title = '') AND id = :id",
|
|
id: user_id, title: group.title
|
|
)
|
|
end
|
|
end
|
|
|
|
def grant_trust_level
|
|
return if group.grant_trust_level.nil?
|
|
|
|
TrustLevelGranter.grant(group.grant_trust_level, user)
|
|
end
|
|
|
|
def recalculate_trust_level
|
|
return if group.grant_trust_level.nil?
|
|
return if self.destroyed_by_association&.active_record == User # User is being destroyed, so don't try to recalculate
|
|
|
|
Promotion.recalculate(user)
|
|
end
|
|
|
|
def set_category_notifications
|
|
self.class.set_category_notifications(group, user)
|
|
end
|
|
|
|
def self.set_category_notifications(group, user)
|
|
group_levels = group.group_category_notification_defaults.each_with_object({}) do |r, h|
|
|
h[r.notification_level] ||= []
|
|
h[r.notification_level] << r.category_id
|
|
end
|
|
|
|
return if group_levels.empty?
|
|
|
|
user_levels = CategoryUser.where(user_id: user.id).each_with_object({}) do |r, h|
|
|
h[r.notification_level] ||= []
|
|
h[r.notification_level] << r.category_id
|
|
end
|
|
|
|
higher_level_category_ids = user_levels.values.flatten
|
|
|
|
[:muted, :tracking, :watching_first_post, :watching].each do |level|
|
|
level_num = NotificationLevels.all[level]
|
|
higher_level_category_ids -= (user_levels[level_num] || [])
|
|
if group_category_ids = group_levels[level_num]
|
|
CategoryUser.batch_set(
|
|
user,
|
|
level,
|
|
group_category_ids + (user_levels[level_num] || []) - higher_level_category_ids
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
def set_tag_notifications
|
|
self.class.set_tag_notifications(group, user)
|
|
end
|
|
|
|
def self.set_tag_notifications(group, user)
|
|
group_levels = group.group_tag_notification_defaults.each_with_object({}) do |r, h|
|
|
h[r.notification_level] ||= []
|
|
h[r.notification_level] << r.tag_id
|
|
end
|
|
|
|
return if group_levels.empty?
|
|
|
|
user_levels = TagUser.where(user_id: user.id).each_with_object({}) do |r, h|
|
|
h[r.notification_level] ||= []
|
|
h[r.notification_level] << r.tag_id
|
|
end
|
|
|
|
higher_level_tag_ids = user_levels.values.flatten
|
|
|
|
[:muted, :tracking, :watching_first_post, :watching].each do |level|
|
|
level_num = NotificationLevels.all[level]
|
|
higher_level_tag_ids -= (user_levels[level_num] || [])
|
|
if group_tag_ids = group_levels[level_num]
|
|
TagUser.batch_set(
|
|
user,
|
|
level,
|
|
group_tag_ids + (user_levels[level_num] || []) - higher_level_tag_ids
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
# == Schema Information
|
|
#
|
|
# Table name: group_users
|
|
#
|
|
# id :integer not null, primary key
|
|
# group_id :integer not null
|
|
# user_id :integer not null
|
|
# created_at :datetime not null
|
|
# updated_at :datetime not null
|
|
# owner :boolean default(FALSE), not null
|
|
# notification_level :integer default(2), not null
|
|
#
|
|
# Indexes
|
|
#
|
|
# index_group_users_on_group_id_and_user_id (group_id,user_id) UNIQUE
|
|
# index_group_users_on_user_id_and_group_id (user_id,group_id) UNIQUE
|
|
#
|