Class: BookmarkManager

Inherits:
Object
  • Object
show all
Includes:
HasErrors
Defined in:
lib/bookmark_manager.rb

Instance Attribute Summary

Attributes included from HasErrors

#conflict, #errors, #forbidden, #not_found

Class Method Summary collapse

Instance Method Summary collapse

Methods included from HasErrors

#add_error, #add_errors_from, #rollback_from_errors!, #rollback_with!, #validate_child

Constructor Details

#initialize(user) ⇒ BookmarkManager

Returns a new instance of BookmarkManager.



6
7
8
9
# File 'lib/bookmark_manager.rb', line 6

def initialize(user)
  @user = user
  @guardian = Guardian.new(user)
end

Class Method Details

.bookmark_metadata(bookmark, user) ⇒ Object



11
12
13
# File 'lib/bookmark_manager.rb', line 11

def self.(bookmark, user)
  bookmark.registered_bookmarkable.(bookmark, user)
end

.send_reminder_notification(id) ⇒ Object



94
95
96
# File 'lib/bookmark_manager.rb', line 94

def self.send_reminder_notification(id)
  BookmarkReminderNotificationHandler.new(Bookmark.find_by(id: id)).send_notification
end

Instance Method Details

#create_for(bookmarkable_id:, bookmarkable_type:, name: nil, reminder_at: nil, options: {}) ⇒ Object

Creates a bookmark for a registered bookmarkable (see Bookmark.register_bookmarkable and RegisteredBookmarkable for details on this).

Only allows creation of bookmarks for records the user can access via Guardian.

Any ActiveModel validation errors raised by the Bookmark model are hoisted to the instance of this class for further reporting.

Before creation validations, after create callbacks, and after delete callbacks are all RegisteredBookmarkable specific and should be defined there.

Parameters:

  • bookmarkable_id (Integer)

    The ID of the ActiveRecord model to attach the bookmark to.

  • bookmarkable_type (String)

    The class name of the ActiveRecord model to attach the bookmark to.

  • name (String) (defaults to: nil)

    A short note for the bookmark, shown on the user bookmark list and on hover of reminder notifications.

  • reminder_at (defaults to: nil)

    The datetime when a bookmark reminder should be sent after. Note this is not the exact time a reminder will be sent, as we send reminders on a rolling schedule. See Jobs::BookmarkReminderNotifications



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/bookmark_manager.rb', line 42

def create_for(bookmarkable_id:, bookmarkable_type:, name: nil, reminder_at: nil, options: {})
  registered_bookmarkable = Bookmark.registered_bookmarkable_from_type(bookmarkable_type)

  if registered_bookmarkable.blank?
    return add_error(I18n.t("bookmarks.errors.invalid_bookmarkable", type: bookmarkable_type))
  end

  bookmarkable = registered_bookmarkable.model.find_by(id: bookmarkable_id)
  registered_bookmarkable.validate_before_create(@guardian, bookmarkable)

  bookmark =
    Bookmark.create(
      {
        user_id: @user.id,
        bookmarkable: bookmarkable,
        name: name,
        reminder_at: reminder_at,
        reminder_set_at: Time.zone.now,
      }.merge(bookmark_model_options_with_defaults(options)),
    )

  return add_errors_from(bookmark) if bookmark.errors.any?

  registered_bookmarkable.after_create(@guardian, bookmark, options)

  bookmark
end

#destroy(bookmark_id) ⇒ Object



70
71
72
73
74
75
76
77
78
# File 'lib/bookmark_manager.rb', line 70

def destroy(bookmark_id)
  bookmark = find_bookmark_and_check_access(bookmark_id)

  bookmark.destroy

  bookmark.registered_bookmarkable.after_destroy(@guardian, bookmark)

  bookmark
end

#destroy_for_topic(topic, filter = {}, opts = {}) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/bookmark_manager.rb', line 80

def destroy_for_topic(topic, filter = {}, opts = {})
  topic_bookmarks = Bookmark.for_user_in_topic(@user.id, topic.id)
  topic_bookmarks = topic_bookmarks.where(filter)

  Bookmark.transaction do
    topic_bookmarks.each do |bookmark|
      raise Discourse::InvalidAccess.new if !@guardian.can_delete?(bookmark)
      bookmark.destroy
    end

    update_topic_user_bookmarked(topic, opts)
  end
end

#toggle_pin(bookmark_id:) ⇒ Object



118
119
120
121
122
123
124
125
126
# File 'lib/bookmark_manager.rb', line 118

def toggle_pin(bookmark_id:)
  bookmark = find_bookmark_and_check_access(bookmark_id)
  bookmark.pinned = !bookmark.pinned
  success = bookmark.save

  return add_errors_from(bookmark) if bookmark.errors.any?

  success
end

#update(bookmark_id:, name:, reminder_at:, options: {}) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/bookmark_manager.rb', line 98

def update(bookmark_id:, name:, reminder_at:, options: {})
  bookmark = find_bookmark_and_check_access(bookmark_id)

  if bookmark.reminder_at != reminder_at
    bookmark.reminder_at = reminder_at
    bookmark.reminder_last_sent_at = nil
  end

  success =
    bookmark.update(
      { name: name, reminder_set_at: Time.zone.now }.merge(
        bookmark_model_options_with_defaults(options),
      ),
    )

  return add_errors_from(bookmark) if bookmark.errors.any?

  success
end