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
This commit is contained in:
Sam Saffron 2020-05-29 12:57:46 +10:00
parent ca28ad8f9a
commit 136835370c
No known key found for this signature in database
GPG Key ID: B9606168D2FFD9F5
2 changed files with 55 additions and 0 deletions

View File

@ -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,

View File

@ -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)