From 136835370c414d2836e71d1253fa9e2a20d0db0a Mon Sep 17 00:00:00 2001 From: Sam Saffron Date: Fri, 29 May 2020 12:57:46 +1000 Subject: [PATCH] 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 --- app/models/topic_tracking_state.rb | 20 ++++++++++++++ spec/models/topic_tracking_state_spec.rb | 35 ++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/app/models/topic_tracking_state.rb b/app/models/topic_tracking_state.rb index 244ce472b9f..eb926671b15 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 db0a13f7d2d..3ac528268d9 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)