| 
									
										
										
										
											2019-05-03 08:17:27 +10:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-30 11:42:26 -04:00
										 |  |  | class CategoryList | 
					
						
							| 
									
										
										
										
											2024-01-17 17:18:01 +02:00
										 |  |  |   CATEGORIES_PER_PAGE = 20
 | 
					
						
							|  |  |  |   SUBCATEGORIES_PER_CATEGORY = 5
 | 
					
						
							| 
									
										
										
										
											2023-12-11 17:58:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-30 11:42:26 -04:00
										 |  |  |   include ActiveModel::Serialization | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 17:26:03 +09:00
										 |  |  |   cattr_accessor :preloaded_topic_custom_fields | 
					
						
							|  |  |  |   self.preloaded_topic_custom_fields = Set.new | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-28 21:15:30 -04:00
										 |  |  |   attr_accessor :categories, :uncategorized | 
					
						
							| 
									
										
										
										
											2013-02-05 14:16:51 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-23 12:39:38 -05:00
										 |  |  |   def self.register_included_association(association) | 
					
						
							|  |  |  |     @included_assocations ||= [] | 
					
						
							|  |  |  |     @included_assocations << association if !@included_assocations.include?(association) | 
					
						
							| 
									
										
										
										
											2023-03-22 15:12:08 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-23 12:39:38 -05:00
										 |  |  |   def self.included_associations | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |       :uploaded_background, | 
					
						
							| 
									
										
										
										
											2023-10-20 09:48:06 -03:00
										 |  |  |       :uploaded_background_dark, | 
					
						
							| 
									
										
										
										
											2023-03-23 12:39:38 -05:00
										 |  |  |       :uploaded_logo, | 
					
						
							|  |  |  |       :uploaded_logo_dark, | 
					
						
							|  |  |  |       :topic_only_relative_url, | 
					
						
							|  |  |  |       subcategories: [:topic_only_relative_url], | 
					
						
							|  |  |  |     ].concat(@included_assocations || []) | 
					
						
							| 
									
										
										
										
											2023-03-22 15:12:08 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-17 23:23:16 +02:00
										 |  |  |   def initialize(guardian = nil, options = {}) | 
					
						
							| 
									
										
										
										
											2013-05-28 14:54:00 -04:00
										 |  |  |     @guardian = guardian || Guardian.new | 
					
						
							| 
									
										
										
										
											2013-10-17 17:44:56 +11:00
										 |  |  |     @options = options | 
					
						
							| 
									
										
										
										
											2013-05-28 14:54:00 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     find_categories | 
					
						
							| 
									
										
										
										
											2024-02-29 12:19:04 +08:00
										 |  |  |     find_relevant_topics if options[:include_topics] | 
					
						
							| 
									
										
										
										
											2016-08-19 01:47:00 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     prune_empty | 
					
						
							|  |  |  |     find_user_data | 
					
						
							|  |  |  |     sort_unpinned | 
					
						
							|  |  |  |     trim_results | 
					
						
							| 
									
										
										
										
											2020-03-17 15:33:15 -05:00
										 |  |  |     demote_muted | 
					
						
							| 
									
										
										
										
											2017-08-01 17:26:03 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if preloaded_topic_custom_fields.present? | 
					
						
							| 
									
										
										
										
											2017-08-01 17:57:26 +09:00
										 |  |  |       displayable_topics = @categories.map(&:displayable_topics) | 
					
						
							|  |  |  |       displayable_topics.flatten! | 
					
						
							|  |  |  |       displayable_topics.compact! | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if displayable_topics.present? | 
					
						
							|  |  |  |         Topic.preload_custom_fields(displayable_topics, preloaded_topic_custom_fields) | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2017-08-01 17:26:03 +09:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-08-17 23:23:16 +02:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-05-28 15:56:46 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-17 23:23:16 +02:00
										 |  |  |   def preload_key | 
					
						
							| 
									
										
										
										
											2020-04-30 16:48:34 +10:00
										 |  |  |     "categories_list" | 
					
						
							| 
									
										
										
										
											2013-05-28 14:54:00 -04:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-25 11:07:19 +02:00
										 |  |  |   def self.order_categories(categories) | 
					
						
							|  |  |  |     if SiteSetting.fixed_category_positions | 
					
						
							|  |  |  |       categories.order(:position, :id) | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       categories | 
					
						
							|  |  |  |         .left_outer_joins(:featured_topics) | 
					
						
							| 
									
										
										
										
											2024-01-09 02:19:37 +02:00
										 |  |  |         .where("topics.category_id IS NULL OR topics.category_id IN (?)", categories.select(:id)) | 
					
						
							| 
									
										
										
										
											2019-04-25 11:07:19 +02:00
										 |  |  |         .group("categories.id") | 
					
						
							|  |  |  |         .order("max(topics.bumped_at) DESC NULLS LAST") | 
					
						
							|  |  |  |         .order("categories.id ASC") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-28 14:54:00 -04:00
										 |  |  |   private | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-27 16:32:45 -03:00
										 |  |  |   def relevant_topics_query | 
					
						
							| 
									
										
										
										
											2022-12-23 04:29:49 +08:00
										 |  |  |     @all_topics = | 
					
						
							| 
									
										
										
										
											2024-02-29 12:19:04 +08:00
										 |  |  |       Topic | 
					
						
							|  |  |  |         .secured(@guardian) | 
					
						
							|  |  |  |         .joins( | 
					
						
							|  |  |  |           "INNER JOIN category_featured_topics ON topics.id = category_featured_topics.topic_id", | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         .where("category_featured_topics.category_id IN (?)", categories_with_descendants.map(&:id)) | 
					
						
							|  |  |  |         .select( | 
					
						
							|  |  |  |           "topics.*, category_featured_topics.category_id AS category_featured_topic_category_id", | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         .includes(:shared_draft, :category, { topic_thumbnails: %i[optimized_image upload] }) | 
					
						
							|  |  |  |         .order("category_featured_topics.rank") | 
					
						
							| 
									
										
										
										
											2021-10-29 17:52:23 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-17 11:51:02 -05:00
										 |  |  |     @all_topics = @all_topics.joins(:tags).where(tags: { name: @options[:tag] }) if @options[ | 
					
						
							|  |  |  |       :tag | 
					
						
							|  |  |  |     ].present? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-29 17:52:23 +03:00
										 |  |  |     if @guardian.authenticated? | 
					
						
							|  |  |  |       @all_topics = | 
					
						
							| 
									
										
										
										
											2023-06-29 11:25:58 +10:00
										 |  |  |         @all_topics | 
					
						
							|  |  |  |           .joins( | 
					
						
							|  |  |  |             "LEFT JOIN topic_users tu ON topics.id = tu.topic_id AND tu.user_id = #{@guardian.user.id.to_i}", | 
					
						
							|  |  |  |           ) | 
					
						
							|  |  |  |           .joins( | 
					
						
							|  |  |  |             "LEFT JOIN category_users ON category_users.category_id = topics.category_id AND category_users.user_id = #{@guardian.user.id}", | 
					
						
							|  |  |  |           ) | 
					
						
							|  |  |  |           .where( | 
					
						
							|  |  |  |             "COALESCE(tu.notification_level,1) > :muted", | 
					
						
							|  |  |  |             muted: TopicUser.notification_levels[:muted], | 
					
						
							|  |  |  |           ) | 
					
						
							| 
									
										
										
										
											2021-10-29 17:52:23 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-17 11:51:02 -05:00
										 |  |  |     @all_topics = TopicQuery.remove_muted_tags(@all_topics, @guardian.user).includes(:last_poster) | 
					
						
							| 
									
										
										
										
											2024-03-27 16:32:45 -03:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2024-02-29 12:19:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-27 16:32:45 -03:00
										 |  |  |   def find_relevant_topics | 
					
						
							| 
									
										
										
										
											2024-02-29 12:19:04 +08:00
										 |  |  |     featured_topics_by_category_id = Hash.new { |h, k| h[k] = [] } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-27 16:32:45 -03:00
										 |  |  |     relevant_topics_query.each do |t| | 
					
						
							| 
									
										
										
										
											2016-08-22 23:01:43 +02:00
										 |  |  |       # hint for the serializer | 
					
						
							| 
									
										
										
										
											2022-08-17 11:51:02 -05:00
										 |  |  |       t.include_last_poster = true | 
					
						
							| 
									
										
										
										
											2021-03-05 09:04:19 +11:00
										 |  |  |       t.dismissed = dismissed_topic?(t) | 
					
						
							| 
									
										
										
										
											2024-02-29 12:19:04 +08:00
										 |  |  |       featured_topics_by_category_id[t.category_featured_topic_category_id] << t | 
					
						
							| 
									
										
										
										
											2016-08-22 23:01:43 +02:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-08-19 01:47:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-29 12:19:04 +08:00
										 |  |  |     categories_with_descendants.each do |category| | 
					
						
							|  |  |  |       category.displayable_topics = featured_topics_by_category_id[category.id] | 
					
						
							| 
									
										
										
										
											2016-08-19 01:47:00 +02:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-06-07 13:28:18 +08:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2016-08-19 01:47:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-05 09:04:19 +11:00
										 |  |  |   def dismissed_topic?(topic) | 
					
						
							|  |  |  |     if @guardian.current_user | 
					
						
							|  |  |  |       @dismissed_topic_users_lookup ||= | 
					
						
							|  |  |  |         DismissedTopicUser.lookup_for(@guardian.current_user, @all_topics) | 
					
						
							|  |  |  |       @dismissed_topic_users_lookup.include?(topic.id) | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       false | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-28 14:54:00 -04:00
										 |  |  |   def find_categories | 
					
						
							| 
									
										
										
										
											2023-05-30 18:41:50 -03:00
										 |  |  |     query = Category.includes(CategoryList.included_associations).secured(@guardian) | 
					
						
							| 
									
										
										
										
											2023-01-09 12:20:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-30 18:41:50 -03:00
										 |  |  |     query = | 
					
						
							|  |  |  |       query.where( | 
					
						
							| 
									
										
										
										
											2016-08-22 23:01:43 +02:00
										 |  |  |         "categories.parent_category_id = ?", | 
					
						
							|  |  |  |         @options[:parent_category_id].to_i, | 
					
						
							|  |  |  |       ) if @options[:parent_category_id].present? | 
					
						
							| 
									
										
										
										
											2018-06-07 13:28:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-30 18:41:50 -03:00
										 |  |  |     query = self.class.order_categories(query) | 
					
						
							| 
									
										
										
										
											2023-12-11 17:58:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-28 18:19:09 +02:00
										 |  |  |     page = [1, @options[:page].to_i].max | 
					
						
							| 
									
										
										
										
											2024-03-21 21:39:14 +02:00
										 |  |  |     if @guardian.can_lazy_load_categories? && @options[:parent_category_id].blank? | 
					
						
							| 
									
										
										
										
											2024-01-17 17:18:01 +02:00
										 |  |  |       query = | 
					
						
							|  |  |  |         query | 
					
						
							|  |  |  |           .where(parent_category_id: nil) | 
					
						
							|  |  |  |           .limit(CATEGORIES_PER_PAGE) | 
					
						
							|  |  |  |           .offset((page - 1) * CATEGORIES_PER_PAGE) | 
					
						
							| 
									
										
										
										
											2024-03-28 18:19:09 +02:00
										 |  |  |     elsif page > 1
 | 
					
						
							|  |  |  |       # Pagination is supported only when lazy load is enabled. If it is not, | 
					
						
							|  |  |  |       # everything is returned on page 1. | 
					
						
							|  |  |  |       query = query.none | 
					
						
							| 
									
										
										
										
											2023-12-11 17:58:45 +02:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-30 18:41:50 -03:00
										 |  |  |     query = | 
					
						
							|  |  |  |       DiscoursePluginRegistry.apply_modifier(:category_list_find_categories_query, query, self) | 
					
						
							| 
									
										
										
										
											2013-05-28 14:54:00 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-30 18:41:50 -03:00
										 |  |  |     @categories = query.to_a | 
					
						
							| 
									
										
										
										
											2015-09-07 18:52:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:39:14 +02:00
										 |  |  |     if @guardian.can_lazy_load_categories? && @options[:parent_category_id].blank? | 
					
						
							| 
									
										
										
										
											2024-01-17 17:18:01 +02:00
										 |  |  |       categories_with_rownum = | 
					
						
							|  |  |  |         Category | 
					
						
							|  |  |  |           .secured(@guardian) | 
					
						
							|  |  |  |           .select(:id, "ROW_NUMBER() OVER (PARTITION BY parent_category_id) rownum") | 
					
						
							|  |  |  |           .where(parent_category_id: @categories.map { |c| c.id }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       @categories += | 
					
						
							| 
									
										
										
										
											2024-02-09 11:48:26 -06:00
										 |  |  |         Category.includes(CategoryList.included_associations).where( | 
					
						
							| 
									
										
										
										
											2024-01-17 17:18:01 +02:00
										 |  |  |           "id IN (WITH cte AS (#{categories_with_rownum.to_sql}) SELECT id FROM cte WHERE rownum <= ?)", | 
					
						
							|  |  |  |           SUBCATEGORIES_PER_CATEGORY, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-09 18:23:24 +02:00
										 |  |  |     if Site.preloaded_category_custom_fields.any? | 
					
						
							|  |  |  |       Category.preload_custom_fields(@categories, Site.preloaded_category_custom_fields) | 
					
						
							| 
									
										
										
										
											2023-10-26 21:34:23 +08:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 12:12:31 -06:00
										 |  |  |     include_subcategories = @options[:include_subcategories] == true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-14 09:45:14 +10:00
										 |  |  |     notification_levels = CategoryUser.notification_levels_for(@guardian.user) | 
					
						
							| 
									
										
										
										
											2019-11-08 08:28:11 +05:30
										 |  |  |     default_notification_level = CategoryUser.default_notification_level | 
					
						
							| 
									
										
										
										
											2015-09-15 14:58:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-17 20:26:51 +02:00
										 |  |  |     if @guardian.can_lazy_load_categories? | 
					
						
							| 
									
										
										
										
											2023-12-18 16:46:09 +02:00
										 |  |  |       subcategory_ids = {} | 
					
						
							|  |  |  |       Category | 
					
						
							|  |  |  |         .secured(@guardian) | 
					
						
							|  |  |  |         .where(parent_category_id: @categories.map(&:id)) | 
					
						
							|  |  |  |         .pluck(:id, :parent_category_id) | 
					
						
							|  |  |  |         .each { |id, parent_id| (subcategory_ids[parent_id] ||= []) << id } | 
					
						
							|  |  |  |       @categories.each { |c| c.subcategory_ids = subcategory_ids[c.id] || [] } | 
					
						
							|  |  |  |     elsif @options[:parent_category_id].blank? | 
					
						
							| 
									
										
										
										
											2021-10-05 12:12:31 -06:00
										 |  |  |       subcategory_ids = {} | 
					
						
							|  |  |  |       subcategory_list = {} | 
					
						
							| 
									
										
										
										
											2016-08-22 23:01:43 +02:00
										 |  |  |       to_delete = Set.new | 
					
						
							|  |  |  |       @categories.each do |c| | 
					
						
							|  |  |  |         if c.parent_category_id.present? | 
					
						
							| 
									
										
										
										
											2021-10-05 12:12:31 -06:00
										 |  |  |           subcategory_ids[c.parent_category_id] ||= [] | 
					
						
							|  |  |  |           subcategory_ids[c.parent_category_id] << c.id | 
					
						
							|  |  |  |           if include_subcategories | 
					
						
							|  |  |  |             subcategory_list[c.parent_category_id] ||= [] | 
					
						
							|  |  |  |             subcategory_list[c.parent_category_id] << c | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2016-08-22 23:01:43 +02:00
										 |  |  |           to_delete << c | 
					
						
							| 
									
										
										
										
											2014-01-15 14:11:19 -05:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2013-05-28 14:54:00 -04:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2021-10-05 12:12:31 -06:00
										 |  |  |       @categories.each do |c| | 
					
						
							|  |  |  |         c.subcategory_ids = subcategory_ids[c.id] || [] | 
					
						
							|  |  |  |         c.subcategory_list = subcategory_list[c.id] || [] if include_subcategories | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-08-22 23:01:43 +02:00
										 |  |  |       @categories.delete_if { |c| to_delete.include?(c) } | 
					
						
							| 
									
										
										
										
											2018-06-07 13:28:18 +08:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2013-05-28 14:54:00 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-25 11:56:32 -05:00
										 |  |  |     Category.preload_user_fields!(@guardian, categories_with_descendants) | 
					
						
							| 
									
										
										
										
											2018-06-07 13:28:18 +08:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2016-08-19 01:47:00 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   def prune_empty | 
					
						
							|  |  |  |     return if SiteSetting.allow_uncategorized_topics | 
					
						
							| 
									
										
										
										
											2021-05-04 06:05:08 +03:00
										 |  |  |     @categories.delete_if { |c| c.uncategorized? } | 
					
						
							| 
									
										
										
										
											2016-08-19 01:47:00 +02:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # Attach some data for serialization to each topic | 
					
						
							|  |  |  |   def find_user_data | 
					
						
							|  |  |  |     if @guardian.current_user && @all_topics.present? | 
					
						
							|  |  |  |       topic_lookup = TopicUser.lookup_for(@guardian.current_user, @all_topics) | 
					
						
							|  |  |  |       @all_topics.each { |ft| ft.user_data = topic_lookup[ft.id] } | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-06-07 13:28:18 +08:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2016-08-19 01:47:00 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   # Put unpinned topics at the end of the list | 
					
						
							|  |  |  |   def sort_unpinned | 
					
						
							|  |  |  |     if @guardian.current_user && @all_topics.present? | 
					
						
							| 
									
										
										
										
											2022-03-04 21:11:59 +00:00
										 |  |  |       categories_with_descendants.each do |c| | 
					
						
							| 
									
										
										
										
											2017-03-01 12:03:12 -05:00
										 |  |  |         next if c.displayable_topics.blank? || c.displayable_topics.size <= c.num_featured_topics | 
					
						
							| 
									
										
										
										
											2016-08-19 01:47:00 +02:00
										 |  |  |         unpinned = [] | 
					
						
							|  |  |  |         c.displayable_topics.each do |t| | 
					
						
							|  |  |  |           unpinned << t if t.pinned_at && PinnedCheck.unpinned?(t, t.user_data) | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         c.displayable_topics = (c.displayable_topics - unpinned) + unpinned unless unpinned.empty? | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-06-07 13:28:18 +08:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2016-08-19 01:47:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-17 15:33:15 -05:00
										 |  |  |   def demote_muted | 
					
						
							|  |  |  |     muted_categories = @categories.select { |category| category.notification_level == 0 } | 
					
						
							|  |  |  |     @categories = @categories.reject { |category| category.notification_level == 0 } | 
					
						
							|  |  |  |     @categories.concat muted_categories | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 01:47:00 +02:00
										 |  |  |   def trim_results | 
					
						
							| 
									
										
										
										
											2022-03-04 21:11:59 +00:00
										 |  |  |     categories_with_descendants.each do |c| | 
					
						
							| 
									
										
										
										
											2016-08-19 01:47:00 +02:00
										 |  |  |       next if c.displayable_topics.blank? | 
					
						
							| 
									
										
										
										
											2017-03-01 12:03:12 -05:00
										 |  |  |       c.displayable_topics = c.displayable_topics[0, c.num_featured_topics] | 
					
						
							| 
									
										
										
										
											2016-08-19 01:47:00 +02:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-06-07 13:28:18 +08:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2016-08-19 01:47:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-04 21:11:59 +00:00
										 |  |  |   def categories_with_descendants(categories = @categories) | 
					
						
							|  |  |  |     return @categories_with_children if @categories_with_children && (categories == @categories) | 
					
						
							|  |  |  |     return nil if categories.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     result = categories.flat_map { |c| [c, *categories_with_descendants(c.subcategory_list)] } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @categories_with_children = result if categories == @categories | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     result | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-02-05 14:16:51 -05:00
										 |  |  | end |