discourse/app/models/concerns/reports/topic_view_stats.rb
Martin Brennan e58cf24fcc
FEATURE: Topic view stats report (#27760)
Adds a report to show the top 100 most viewed topics in a date range,
combining logged in and anonymous views. Can be filtered by category.

This is a followup to 527f02e99f
and d1191b7f5f. We are also going to
be able to see this data in a new topic map, but this admin report
helps to see an overview across the forum for a date range.
2024-07-09 15:39:10 +10:00

76 lines
2.2 KiB
Ruby

# frozen_string_literal: true
module Reports::TopicViewStats
extend ActiveSupport::Concern
class_methods do
def report_topic_view_stats(report)
report.modes = [:table]
category_id, include_subcategories = report.add_category_filter
category_ids = include_subcategories ? Category.subcategory_ids(category_id) : [category_id]
sql = <<~SQL
SELECT
topic_view_stats.topic_id,
topics.title AS topic_title,
SUM(topic_view_stats.anonymous_views) AS total_anonymous_views,
SUM(topic_view_stats.logged_in_views) AS total_logged_in_views,
SUM(topic_view_stats.anonymous_views + topic_view_stats.logged_in_views) AS total_views
FROM topic_view_stats
INNER JOIN topics ON topics.id = topic_view_stats.topic_id
WHERE viewed_at BETWEEN :start_date AND :end_date
#{category_ids.any? ? "AND topics.category_id IN (:category_ids)" : ""}
GROUP BY topic_view_stats.topic_id, topics.title
ORDER BY total_views DESC
LIMIT 100
SQL
data =
DB.query(
sql,
start_date: report.start_date,
end_date: report.end_date,
category_ids: category_ids,
)
report.labels = [
{
type: :topic,
properties: {
title: :topic_title,
id: :topic_id,
},
title: I18n.t("reports.topic_view_stats.labels.topic"),
},
{
property: :total_anonymous_views,
type: :number,
title: I18n.t("reports.topic_view_stats.labels.anon_views"),
},
{
property: :total_logged_in_views,
type: :number,
title: I18n.t("reports.topic_view_stats.labels.logged_in_views"),
},
{
property: :total_views,
type: :number,
title: I18n.t("reports.topic_view_stats.labels.total_views"),
},
]
report.data =
data.map do |row|
{
topic_id: row.topic_id,
topic_title: row.topic_title,
total_anonymous_views: row.total_anonymous_views,
total_logged_in_views: row.total_logged_in_views,
total_views: row.total_views,
}
end
end
end
end