mirror of
https://github.com/discourse/discourse.git
synced 2024-11-25 18:43:40 +08:00
9638ce17fa
This is necessary when "lazy load categories" feature is enabled to make sure the categories are rendered for topics and posts.
105 lines
3.2 KiB
Ruby
105 lines
3.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class PostBookmarkable < BaseBookmarkable
|
|
include TopicPostBookmarkableHelper
|
|
|
|
def self.model
|
|
Post
|
|
end
|
|
|
|
def self.serializer
|
|
UserPostBookmarkSerializer
|
|
end
|
|
|
|
def self.preload_associations
|
|
[{ topic: [:tags, { category: :parent_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
|