forked from discourse/discourse
-
Notifications
You must be signed in to change notification settings - Fork 0
/
post_bookmarkable.rb
104 lines (88 loc) · 3.17 KB
/
post_bookmarkable.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# frozen_string_literal: true
class PostBookmarkable < BaseBookmarkable
include TopicPostBookmarkableHelper
def self.model
Post
end
def self.serializer
UserPostBookmarkSerializer
end
def self.preload_associations
[{ topic: %i[tags category] }, :user]
end
def self.list_query(user, guardian)
topics = Topic.listable_topics.secured(guardian)
pms = Topic.private_messages_for_user(user)
post_bookmarks =
user
.bookmarks_of_type("Post")
.joins(
"INNER JOIN posts ON posts.id = bookmarks.bookmarkable_id AND bookmarks.bookmarkable_type = 'Post'",
)
.joins("LEFT JOIN topics ON topics.id = posts.topic_id")
.joins("LEFT JOIN topic_users ON topic_users.topic_id = topics.id")
.where("topic_users.user_id = ?", user.id)
guardian.filter_allowed_categories(
post_bookmarks.merge(topics.or(pms)).merge(Post.secured(guardian)),
)
end
def self.search_query(bookmarks, query, ts_query, &bookmarkable_search)
bookmarkable_search.call(
bookmarks.joins(
"LEFT JOIN post_search_data ON post_search_data.post_id = bookmarks.bookmarkable_id AND bookmarks.bookmarkable_type = 'Post'",
),
"#{ts_query} @@ post_search_data.search_data",
)
end
def self.reminder_handler(bookmark)
send_reminder_notification(
bookmark,
topic_id: bookmark.bookmarkable.topic_id,
post_number: bookmark.bookmarkable.post_number,
data: {
title: bookmark.bookmarkable.topic.title,
bookmarkable_url: bookmark.bookmarkable.url,
},
)
end
def self.reminder_conditions(bookmark)
bookmark.bookmarkable.present? && bookmark.bookmarkable.topic.present? &&
self.can_see?(bookmark.user.guardian, bookmark)
end
def self.can_see?(guardian, bookmark)
can_see_bookmarkable?(guardian, bookmark.bookmarkable)
end
def self.can_see_bookmarkable?(guardian, bookmarkable)
guardian.can_see_post?(bookmarkable)
end
def self.bookmark_metadata(bookmark, user)
{
topic_bookmarked: Bookmark.for_user_in_topic(user.id, bookmark.bookmarkable.topic_id).exists?,
}
end
def self.validate_before_create(guardian, bookmarkable)
if bookmarkable.blank? || bookmarkable.topic.blank? ||
!guardian.can_see_topic?(bookmarkable.topic) || !guardian.can_see_post?(bookmarkable)
raise Discourse::InvalidAccess
end
end
def self.after_create(guardian, bookmark, opts)
sync_topic_user_bookmarked(guardian.user, bookmark.bookmarkable.topic, opts)
end
def self.after_destroy(guardian, bookmark, opts)
sync_topic_user_bookmarked(guardian.user, bookmark.bookmarkable.topic, opts)
end
def self.cleanup_deleted
related_topics = DB.query(<<~SQL, grace_time: 3.days.ago)
DELETE FROM bookmarks b
USING topics t, posts p
WHERE t.id = p.topic_id AND b.bookmarkable_id = p.id AND b.bookmarkable_type = 'Post'
AND (t.deleted_at < :grace_time OR p.deleted_at < :grace_time)
RETURNING t.id AS topic_id
SQL
related_topics_ids = related_topics.map(&:topic_id).uniq
related_topics_ids.each do |topic_id|
Jobs.enqueue(:sync_topic_user_bookmarked, topic_id: topic_id)
end
end
end