mirror of
https://github.com/discourse/discourse.git
synced 2024-11-30 09:34:17 +08:00
9e5b213089
For the following conditions, the TopicUser.bookmarked column was not updated correctly: * When a bookmark was auto-deleted because the reminder was sent * When a bookmark was auto-deleted because the owner of the bookmark replied to the topic This adds another migration to fix the out-of-sync column and also some refactors to BookmarkManager to allow for more of these delete cases. BookmarkManager is used instead of directly destroying the bookmark in PostCreator and BookmarkReminderNotificationHandler.
110 lines
3.0 KiB
Ruby
110 lines
3.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class BookmarkManager
|
|
include HasErrors
|
|
|
|
def initialize(user)
|
|
@user = user
|
|
end
|
|
|
|
def create(post_id:, name: nil, reminder_type: nil, reminder_at: nil, options: {})
|
|
post = Post.unscoped.includes(:topic).find(post_id)
|
|
reminder_type = parse_reminder_type(reminder_type)
|
|
|
|
raise Discourse::InvalidAccess.new if !Guardian.new(@user).can_see_post?(post)
|
|
|
|
bookmark = Bookmark.create(
|
|
{
|
|
user_id: @user.id,
|
|
topic: post.topic,
|
|
post: post,
|
|
name: name,
|
|
reminder_type: reminder_type,
|
|
reminder_at: reminder_at,
|
|
reminder_set_at: Time.zone.now
|
|
}.merge(options)
|
|
)
|
|
|
|
if bookmark.errors.any?
|
|
return add_errors_from(bookmark)
|
|
end
|
|
|
|
update_topic_user_bookmarked(post.topic)
|
|
|
|
bookmark
|
|
end
|
|
|
|
def destroy(bookmark_id)
|
|
bookmark = Bookmark.find_by(id: bookmark_id)
|
|
|
|
raise Discourse::NotFound if bookmark.blank?
|
|
raise Discourse::InvalidAccess.new if !Guardian.new(@user).can_delete?(bookmark)
|
|
|
|
bookmark.destroy
|
|
|
|
bookmarks_remaining_in_topic = update_topic_user_bookmarked(bookmark.topic)
|
|
|
|
{ topic_bookmarked: bookmarks_remaining_in_topic }
|
|
end
|
|
|
|
def destroy_for_topic(topic, filter = {}, opts = {})
|
|
topic_bookmarks = Bookmark.where(user_id: @user.id, topic_id: topic.id)
|
|
topic_bookmarks = topic_bookmarks.where(filter)
|
|
|
|
Bookmark.transaction do
|
|
topic_bookmarks.each do |bookmark|
|
|
raise Discourse::InvalidAccess.new if !Guardian.new(@user).can_delete?(bookmark)
|
|
bookmark.destroy
|
|
end
|
|
|
|
update_topic_user_bookmarked(topic, opts)
|
|
end
|
|
end
|
|
|
|
def self.send_reminder_notification(id)
|
|
bookmark = Bookmark.find_by(id: id)
|
|
BookmarkReminderNotificationHandler.send_notification(bookmark)
|
|
end
|
|
|
|
def update(bookmark_id:, name:, reminder_type:, reminder_at:, options: {})
|
|
bookmark = Bookmark.find_by(id: bookmark_id)
|
|
|
|
raise Discourse::NotFound if bookmark.blank?
|
|
raise Discourse::InvalidAccess.new if !Guardian.new(@user).can_edit?(bookmark)
|
|
|
|
reminder_type = parse_reminder_type(reminder_type)
|
|
|
|
success = bookmark.update(
|
|
{
|
|
name: name,
|
|
reminder_at: reminder_at,
|
|
reminder_type: reminder_type,
|
|
reminder_set_at: Time.zone.now
|
|
}.merge(options)
|
|
)
|
|
|
|
if bookmark.errors.any?
|
|
return add_errors_from(bookmark)
|
|
end
|
|
|
|
success
|
|
end
|
|
|
|
private
|
|
|
|
def update_topic_user_bookmarked(topic, opts = {})
|
|
# PostCreator can specify whether auto_track is enabled or not, don't want to
|
|
# create a TopicUser in that case
|
|
bookmarks_remaining_in_topic = Bookmark.exists?(topic_id: topic.id, user: @user)
|
|
return bookmarks_remaining_in_topic if opts.key?(:auto_track) && !opts[:auto_track]
|
|
|
|
TopicUser.change(@user.id, topic, bookmarked: bookmarks_remaining_in_topic)
|
|
bookmarks_remaining_in_topic
|
|
end
|
|
|
|
def parse_reminder_type(reminder_type)
|
|
return if reminder_type.blank?
|
|
reminder_type.is_a?(Integer) ? reminder_type : Bookmark.reminder_types[reminder_type.to_sym]
|
|
end
|
|
end
|