Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create google analytics 4 compatibility #6815

Merged
merged 5 commits into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .dassie/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ gem 'dalli'
gem 'devise'
gem 'devise-guests', '~> 0.8'
gemspec name: 'hyrax', path: ENV.fetch('HYRAX_ENGINE_PATH', '..')
gem 'google-protobuf', force_ruby_platform: true # required because google-protobuf is not compatible with Alpine linux
gem 'grpc', force_ruby_platform: true # required because google-protobuf is not compatible with Alpine linux
gem 'jbuilder', '~> 2.5'
gem 'jquery-rails'
gem 'pg', '~> 1.3'
Expand Down
2 changes: 2 additions & 0 deletions .koppie/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ gem 'coffee-rails', '~> 4.2'
gem 'dalli'
gem 'devise'
gem 'devise-guests', '~> 0.8'
gem 'google-protobuf', force_ruby_platform: true # required because google-protobuf is not compatible with Alpine linux
gem 'grpc', force_ruby_platform: true # required because google-protobuf is not compatible with Alpine linux
gemspec name: 'hyrax', path: ENV.fetch('HYRAX_ENGINE_PATH', '..')
gem 'jbuilder', '~> 2.5'
gem 'jquery-rails'
Expand Down
70 changes: 47 additions & 23 deletions app/assets/javascripts/hyrax/analytics_events.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,53 @@ class TrackingTags {
}

analytics() {
if(this.provider === "matomo") {
switch(this.provider) {
case "matomo":
return _paq;
}
else {
case "ga4":
return dataLayer;
default:
return _gaq;
}
}

pageView() {
if(this.provider === "matomo") {
return 'trackPageView'
} else {
return '_trackPageview'
switch(this.provider) {
case "matomo":
return 'trackPageView';
case "ga4":
return 'event';
default:
return '_trackPageview';
}
}

trackEvent() {
if(this.provider === "matomo") {
return 'trackEvent'
} else {
return '_trackEvent'
switch(this.provider) {
case "matomo":
return 'trackEvent';
case "ga4":
return 'event';
default:
return '_trackEvent';
}
}
}

function trackPageView() {
window.trackingTags.analytics().push([window.trackingTags.pageView()]);
function trackPageView(provider) {
if(provider !== 'ga4'){
window.trackingTags.analytics().push([window.trackingTags.pageView()]);
}
}

function trackAnalyticsEvents() {
function trackAnalyticsEvents(provider) {
$('span.analytics-event').each(function(){
var eventSpan = $(this)
window.trackingTags.analytics().push([window.trackingTags.trackEvent(), eventSpan.data('category'), eventSpan.data('action'), eventSpan.data('name')]);
if(provider !== 'ga4') {
window.trackingTags.analytics().push([window.trackingTags.trackEvent(), eventSpan.data('category'), eventSpan.data('action'), eventSpan.data('name')]);
} else {
gtag('event', eventspan.data('action'), { 'content_type': eventspan.data('category'), 'content_id': eventspan.data('name')})
}
})
}

Expand All @@ -46,8 +60,8 @@ function setupTracking() {
return;
}
window.trackingTags = new TrackingTags(provider)
trackPageView()
trackAnalyticsEvents()
trackPageView(provider)
trackAnalyticsEvents(provider)
}

if (typeof Turbolinks !== 'undefined') {
Expand All @@ -66,10 +80,20 @@ $(document).on('click', '#file_download', function(e) {
return;
}
window.trackingTags = new TrackingTags(provider)
window.trackingTags.analytics().push([trackingTags.trackEvent(), 'file-set', 'file-set-download', $(this).data('label')]);
window.trackingTags.analytics().push([trackingTags.trackEvent(), 'file-set-in-work', 'file-set-in-work-download', $(this).data('work-id')]);
$(this).data('collection-ids').forEach(function (collection) {
window.trackingTags.analytics().push([trackingTags.trackEvent(), 'file-set-in-collection', 'file-set-in-collection-download', collection]);
window.trackingTags.analytics().push([trackingTags.trackEvent(), 'work-in-collection', 'work-in-collection-download', collection]);
});

if(provider !== 'ga4') {
window.trackingTags.analytics().push([trackingTags.trackEvent(), 'file-set', 'file-set-download', $(this).data('label')]);
window.trackingTags.analytics().push([trackingTags.trackEvent(), 'file-set-in-work', 'file-set-in-work-download', $(this).data('work-id')]);
$(this).data('collection-ids').forEach(function (collection) {
window.trackingTags.analytics().push([trackingTags.trackEvent(), 'file-set-in-collection', 'file-set-in-collection-download', collection]);
window.trackingTags.analytics().push([trackingTags.trackEvent(), 'work-in-collection', 'work-in-collection-download', collection]);
});
} else {
gtag('event', 'file-set-download', { 'content-type': 'file-set', 'content-id': $(this).data('label')})
gtag('event', 'file-set-in-work-download', { 'content-type': 'file-set-in-work', 'content-id': $(this).data('work-id')})
$(this).data('collection-ids').forEach(function (collection) {
gtag('event', 'file-set-in-collection-download', { 'content-type': 'file-set-in-collection', 'content-id': collection })
gtag('event', 'work-in-collection-download', { 'content-type': 'work-in-collection', 'content-id': collection })
});
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@ module SingularSubresourceController

included do
before_action :find_work, only: :work
before_action :find_file_set, only: :file
load_and_authorize_resource :work, only: :work
load_and_authorize_resource :file, class: 'FileSet', only: :file, id_param: :id
load_and_authorize_resource :file, only: :file
end

def find_work
@work = Hyrax::WorkRelation.new.find(params[:id])
@work = Hyrax.query_service.find_by(id: params[:id])
end

def find_file_set
@file = Hyrax.query_service.find_by(id: params[:id])
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def show
private

def accessible_works
models = Hyrax.config.curation_concerns.map { |m| "\"#{m}\"" }
models = Hyrax::ModelRegistry.work_rdf_representations.map { |m| "\"#{m}\"" }
if current_user.ability.admin?
Hyrax::SolrService.query("has_model_ssim:(#{models.join(' OR ')})",
fl: 'title_tesim, id, member_of_collections',
Expand All @@ -54,15 +54,16 @@ def accessible_works
end

def accessible_file_sets
file_set_model_clause = "has_model_ssim:\"#{Hyrax::ModelRegistry.file_set_rdf_representations.join('" OR "')}\""
if current_user.ability.admin?
Hyrax::SolrService.query(
"has_model_ssim:FileSet",
file_set_model_clause,
fl: 'title_tesim, id',
rows: 50_000
)
else
Hyrax::SolrService.query(
"edit_access_person_ssim:#{current_user} AND has_model_ssim:FileSet",
"edit_access_person_ssim:#{current_user} AND #{file_set_model_clause}",
fl: 'title_tesim, id',
rows: 50_000
)
Expand Down
2 changes: 1 addition & 1 deletion app/models/file_download_stat.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def ga_statistics(start_date, file)

# this is called by the parent class
def filter(file)
{ file_id: file.id }
{ file_id: file.id.to_s }
end
end
end
2 changes: 1 addition & 1 deletion app/models/file_view_stat.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class FileViewStat < Hyrax::Statistic
class << self
# this is called by the parent class
def filter(file)
{ file_id: file.id }
{ file_id: file.id.to_s }
end
end
end
22 changes: 3 additions & 19 deletions app/models/hyrax/statistic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,6 @@ def statistics(object, start_date, user_id = nil)
combined_stats object, start_date, cache_column, event_type, user_id
end

# Hyrax::Download is sent to Hyrax::Analytics.profile as #hyrax__download
# see Legato::ProfileMethods.method_name_from_klass
def ga_statistics(start_date, object)
path = polymorphic_path(object)
profile = Hyrax::Analytics.profile
unless profile
Hyrax.logger.error("Google Analytics profile has not been established. Unable to fetch statistics.")
return []
end
profile.hyrax__pageview(sort: 'date',
start_date: start_date,
end_date: Date.yesterday,
limit: 10_000)
.for_path(path)
end

def query_works(query)
models = Hyrax.config.curation_concerns.map { |m| "\"#{m}\"" }
Hyrax::SolrService.query("has_model_ssim:(#{models.join(' OR ')})", fl: query, rows: 100_000)
Expand Down Expand Up @@ -80,10 +64,10 @@ def combined_stats(object, start_date, object_method, ga_key, user_id = nil)
stat_cache_info = cached_stats(object, start_date, object_method)
stats = stat_cache_info[:cached_stats]
if stat_cache_info[:ga_start_date] < Time.zone.today
ga_stats = ga_statistics(stat_cache_info[:ga_start_date], object)
ga_stats.each do |stat|
page_stats = Hyrax::Analytics.page_statistics(stat_cache_info[:ga_start_date], object)
page_stats.each do |stat|
lstat = build_for(object, date: stat[:date], object_method => stat[ga_key], user_id: user_id)
lstat.save unless Date.parse(stat[:date]) == Time.zone.today
lstat.save unless stat[:date].to_date == Time.zone.today
stats << lstat
end
end
Expand Down
2 changes: 1 addition & 1 deletion app/presenters/hyrax/file_usage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module Hyrax
# and prepares it for visualization in /app/views/stats/file.html.erb
class FileUsage < StatsUsagePresenter
def initialize(id)
self.model = ::FileSet.find(id)
self.model = Hyrax.query_service.find_by(id: id)
end

alias file model
Expand Down
1 change: 1 addition & 0 deletions app/presenters/hyrax/stats_usage_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def date_for_analytics
end

def string_to_date(date_str)
return date_str if date_str.is_a?(Date)
Time.zone.parse(date_str)
rescue ArgumentError, TypeError
nil
Expand Down
Loading
Loading