FEATURE: optionally allow tags in topic tracking state

FEATURE: optionally allow tags in topic tracking state

This feature allows certain plugins to output tag information to topic tracking state, this allows per tag stats which can be used by sidebars and other plugins that need per tag stats

Not enabled by default cause this would add cost to a critical query

diff --git a/app/models/topic_tracking_state.rb b/app/models/topic_tracking_state.rb
index 244ce47..eb92667 100644
--- a/app/models/topic_tracking_state.rb
+++ b/app/models/topic_tracking_state.rb
@@ -186,6 +186,14 @@ class TopicTrackingState
               ).where_clause.send(:predicates)[0]
   end
 
+  def self.include_tags_in_report?
+    @include_tags_in_report
+  end
+
+  def self.include_tags_in_report=(v)
+    @include_tags_in_report = v
+  end
+
   def self.report(user, topic_id = nil)
     # Sam: this is a hairy report, in particular I need custom joins and fancy conditions
     #  Dropping to sql_builder so I can make sense of it.
@@ -220,6 +228,18 @@ class TopicTrackingState
       muted_tag_ids: tag_ids
     )
 
+    if SiteSetting.tagging_enabled && TopicTrackingState.include_tags_in_report?
+      sql = <<~SQL
+        WITH X AS (#{sql})
+        SELECT *, (
+          SELECT ARRAY_AGG(name) from topic_tags
+             JOIN tags on tags.id = topic_tags.tag_id
+             WHERE topic_id = X.topic_id
+          ) tags
+        FROM X
+      SQL
+    end
+
     DB.query(
       sql,
         user_id: user.id,
diff --git a/spec/models/topic_tracking_state_spec.rb b/spec/models/topic_tracking_state_spec.rb
index db0a13f..3ac5282 100644
--- a/spec/models/topic_tracking_state_spec.rb
+++ b/spec/models/topic_tracking_state_spec.rb
@@ -548,6 +548,41 @@ describe TopicTrackingState do
 
   end
 
+  context "tag support" do
+    after do
+      # this is a bit of an odd hook, but this is a global change
+      # used by plugins that leverage tagging heavily and need
+      # tag information in topic tracking state
+      TopicTrackingState.include_tags_in_report = false
+    end
+
+    it "correctly handles tags" do
+      SiteSetting.tagging_enabled = true
+
+      post.topic.notifier.watch_topic!(post.topic.user_id)
+
+      DiscourseTagging.tag_topic_by_names(
+        post.topic,
+        Guardian.new(Discourse.system_user),
+        ['bananas', 'apples']
+      )
+
+      TopicTrackingState.include_tags_in_report = true
+
+      report = TopicTrackingState.report(user)
+      expect(report.length).to eq(1)
+      row = report[0]
+      expect(row.tags).to contain_exactly("apples", "bananas")
+
+      TopicTrackingState.include_tags_in_report = false
+
+      report = TopicTrackingState.report(user)
+      expect(report.length).to eq(1)
+      row = report[0]
+      expect(row.respond_to? :tags).to eq(false)
+    end
+  end
+
   it "correctly gets the tracking state" do
     report = TopicTrackingState.report(user)
     expect(report.length).to eq(0)

GitHub sha: 13683537

2 Likes