# frozen_string_literal: true ## # Allows us to query Bookmark records for lists. Used mainly # in the user/activity/bookmarks page. class BookmarkQuery cattr_accessor :preloaded_custom_fields self.preloaded_custom_fields = Set.new def self.on_preload(&blk) (@preload ||= Set.new) << blk end def self.preload(bookmarks, object) if @preload @preload.each { |preload| preload.call(bookmarks, object) } end end def initialize(user:, guardian: nil, params: {}) @user = user @params = params @guardian = guardian || Guardian.new(@user) @page = @params[:page].to_i @limit = @params[:limit].present? ? @params[:limit].to_i : @params[:per_page] end def list_all results = user_bookmarks.order( '(CASE WHEN bookmarks.pinned THEN 0 ELSE 1 END), bookmarks.updated_at DESC' ) topics = Topic.listable_topics.secured(@guardian) pms = Topic.private_messages_for_user(@user) results = results.merge(topics.or(pms)) results = results.merge(Post.secured(@guardian)) if @params[:q].present? term = @params[:q] bookmark_ts_query = Search.ts_query(term: term) results = results .joins("LEFT JOIN post_search_data ON post_search_data.post_id = bookmarks.post_id") .where( "bookmarks.name ILIKE :q OR #{bookmark_ts_query} @@ post_search_data.search_data", q: "%#{term}%" ) end if @page.positive? results = results.offset(@page * @params[:per_page]) end results = results.limit(@limit) if BookmarkQuery.preloaded_custom_fields.any? Topic.preload_custom_fields( results.map(&:topic), BookmarkQuery.preloaded_custom_fields ) end BookmarkQuery.preload(results, self) @guardian.filter_allowed_categories(results) end private def user_bookmarks Bookmark.where(user: @user) .includes(topic: :tags) .includes(post: :user) .references(:topic) .references(:post) end end