# frozen_string_literal: true class SuggestedTopicsBuilder attr_reader :excluded_topic_ids def initialize(topic) @excluded_topic_ids = [topic.id] @category_id = topic.category_id @category_topic_ids = Category.topic_ids @results = [] end def add_results(results, priority = :low) # WARNING .blank? will execute an Active Record query return unless results # Only add results if we don't have those topic ids already results = results.where("topics.id NOT IN (?)", @excluded_topic_ids).where(visible: true) # If limit suggested to category is enabled, restrict to that category if @category_id && SiteSetting.limit_suggested_to_category? results = results.where(category_id: @category_id) end results = results.to_a results.reject! { |topic| @category_topic_ids.include?(topic.id) } unless results.empty? # protect against dupes temp = results results = [] temp.each do |r| if !@excluded_topic_ids.include?(r.id) results << r @excluded_topic_ids << r.id end end results = DiscoursePluginRegistry.apply_modifier(:suggested_topics_add_results, results) splice_results(results, priority) end end def splice_results(results, priority) if priority == :ultra_high @results.insert 0, *results elsif @category_id && priority == :high # Topics from category @category_id need to be first in the list, all others after. other_category_index = @results.index { |r| r.category_id != @category_id } category_results, other_category_results = results.partition { |r| r.category_id == @category_id } if other_category_index @results.insert other_category_index, *category_results else @results.concat category_results end @results.concat other_category_results else @results.concat results end end def results @results.first(SiteSetting.suggested_topics) end def results_left SiteSetting.suggested_topics - @results.size end def full? results_left <= 0 end def category_results_left SiteSetting.suggested_topics - @results.count { |r| r.category_id == @category_id } end def size @results.size end end