diff options
Diffstat (limited to 'extensions/GoogleAnalytics')
8 files changed, 213 insertions, 0 deletions
diff --git a/extensions/GoogleAnalytics/Config.pm b/extensions/GoogleAnalytics/Config.pm new file mode 100644 index 000000000..f4699db37 --- /dev/null +++ b/extensions/GoogleAnalytics/Config.pm @@ -0,0 +1,16 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::GoogleAnalytics; + +use 5.10.1; +use strict; +use warnings; + +use constant NAME => 'GoogleAnalytics'; + +__PACKAGE__->NAME; diff --git a/extensions/GoogleAnalytics/Extension.pm b/extensions/GoogleAnalytics/Extension.pm new file mode 100644 index 000000000..e9b144da4 --- /dev/null +++ b/extensions/GoogleAnalytics/Extension.pm @@ -0,0 +1,23 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::GoogleAnalytics; + +use 5.10.1; +use strict; +use warnings; +use parent qw(Bugzilla::Extension); + +our $VERSION = '0.1'; + +sub config_add_panels { + my ($self, $args) = @_; + my $modules = $args->{panel_modules}; + $modules->{GoogleAnalytics} = "Bugzilla::Extension::GoogleAnalytics::Config"; +} + +__PACKAGE__->NAME; diff --git a/extensions/GoogleAnalytics/lib/Config.pm b/extensions/GoogleAnalytics/lib/Config.pm new file mode 100644 index 000000000..f9e003ce0 --- /dev/null +++ b/extensions/GoogleAnalytics/lib/Config.pm @@ -0,0 +1,41 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::GoogleAnalytics::Config; + +use 5.10.1; +use strict; +use warnings; + +use Bugzilla::Config::Common; + +sub get_param_list { + my ($class) = @_; + + my @params = ( + { + name => 'google_analytics_tracking_id', + type => 't', + default => '', + checker => sub { + my ($tracking_id) = (@_); + + return 'must be like UA-XXXXXX-X' unless $tracking_id =~ m{^(UA-[[:xdigit:]]+-[[:xdigit:]]+)?$}; + return ''; + } + }, + { + name => 'google_analytics_debug', + type => 'b', + default => 0 + }, + ); + + return @params; +} + +1; diff --git a/extensions/GoogleAnalytics/template/en/default/admin/params/googleanalytics.html.tmpl b/extensions/GoogleAnalytics/template/en/default/admin/params/googleanalytics.html.tmpl new file mode 100644 index 000000000..3fdce57e6 --- /dev/null +++ b/extensions/GoogleAnalytics/template/en/default/admin/params/googleanalytics.html.tmpl @@ -0,0 +1,20 @@ +[%# This Source Code Form is subject to the terms of the Mozilla Public + # License, v. 2.0. If a copy of the MPL was not distributed with this + # file, You can obtain one at http://mozilla.org/MPL/2.0/. + # + # This Source Code Form is "Incompatible With Secondary Licenses", as + # defined by the Mozilla Public License, v. 2.0. + #%] + +[% + title = "Google Analytics" + desc = "Configure Google Analytics" +%] + +[% + param_descs = { + google_analytics_tracking_id => "Google Analytics Tracking ID", + google_analytics_debug => "If this option is set, the debug version of the analytics.js " _ + "library will be used.", + } +%] diff --git a/extensions/GoogleAnalytics/template/en/default/hook/global/header-additional_header.html.tmpl b/extensions/GoogleAnalytics/template/en/default/hook/global/header-additional_header.html.tmpl new file mode 100644 index 000000000..fc0ebc480 --- /dev/null +++ b/extensions/GoogleAnalytics/template/en/default/hook/global/header-additional_header.html.tmpl @@ -0,0 +1,24 @@ +[%# This Source Code Form is subject to the terms of the Mozilla Public + # License, v. 2.0. If a copy of the MPL was not distributed with this + # file, You can obtain one at http://mozilla.org/MPL/2.0/. + # + # This Source Code Form is "Incompatible With Secondary Licenses", as + # defined by the Mozilla Public License, v. 2.0. + #%] + +[%# Disable tracking of security group members as well as private bugs #%] +[% RETURN IF !Bugzilla.params.google_analytics_tracking_id || + user.in_group(Param('insidergroup')) || (bug.defined && bug.groups_in.size) %] + +<meta name="google-analytics" content="[% Bugzilla.params.google_analytics_tracking_id FILTER html %]" data-location=" + [%~ urlbase FILTER html %][% template.name.replace('\.html\.tmpl$', '') FILTER html ~%] + " data-title=" + [%~ IF template.name == 'pages/user_activity.html.tmpl' ~%] + User Activity Report + [%~ ELSIF template.name == 'pages/user_profile.html.tmpl' ~%] + User Profile + [%~ ELSE ~%] + [% title FILTER html | collapse %] + [%~ END ~%]"> +<script async src="https://www.google-analytics.com/analytics + [%~ "_debug" IF Bugzilla.params.google_analytics_debug ~%].js"></script> diff --git a/extensions/GoogleAnalytics/template/en/default/hook/global/header-start.html.tmpl b/extensions/GoogleAnalytics/template/en/default/hook/global/header-start.html.tmpl new file mode 100644 index 000000000..27a8587ef --- /dev/null +++ b/extensions/GoogleAnalytics/template/en/default/hook/global/header-start.html.tmpl @@ -0,0 +1,14 @@ +[%# This Source Code Form is subject to the terms of the Mozilla Public + # License, v. 2.0. If a copy of the MPL was not distributed with this + # file, You can obtain one at http://mozilla.org/MPL/2.0/. + # + # This Source Code Form is "Incompatible With Secondary Licenses", as + # defined by the Mozilla Public License, v. 2.0. + #%] + +[% IF !javascript_urls %] + [% javascript_urls = [] %] +[% END %] + +[% javascript_urls.push('extensions/GoogleAnalytics/web/js/analytics.js') %] +[% javascript_urls.push('extensions/GoogleAnalytics/web/js/dnt-helper.js') %] diff --git a/extensions/GoogleAnalytics/web/js/analytics.js b/extensions/GoogleAnalytics/web/js/analytics.js new file mode 100644 index 000000000..25f7d7527 --- /dev/null +++ b/extensions/GoogleAnalytics/web/js/analytics.js @@ -0,0 +1,21 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This Source Code Form is "Incompatible With Secondary Licenses", as + * defined by the Mozilla Public License, v. 2.0. */ + +$(function() { + var meta = $('meta[name="google-analytics"]'); + + if (typeof Mozilla.dntEnabled === 'function' && !Mozilla.dntEnabled() && meta.length) { + // Activate Google Analytics + window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date; + ga('create', meta.attr('content'), 'auto'); + ga('set', 'anonymizeIp', true); + ga('set', 'location', meta.data('location')); + ga('set', 'title', meta.data('title')); + // Track page view + ga('send', 'pageview'); + } +}); diff --git a/extensions/GoogleAnalytics/web/js/dnt-helper.js b/extensions/GoogleAnalytics/web/js/dnt-helper.js new file mode 100644 index 000000000..828fdc7ea --- /dev/null +++ b/extensions/GoogleAnalytics/web/js/dnt-helper.js @@ -0,0 +1,54 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public +* License, v. 2.0. If a copy of the MPL was not distributed with this +* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// create namespace +if (typeof Mozilla === 'undefined') { + var Mozilla = {}; +} + +/** + * Returns true or false based on whether doNotTrack is enabled. It also takes into account the + * anomalies, such as !bugzilla 887703, which effect versions of Fx 31 and lower. It also handles + * IE versions on Windows 7, 8 and 8.1, where the DNT implementation does not honor the spec. + * @see https://bugzilla.mozilla.org/show_bug.cgi?id=1217896 for more details + * @params {string} [dnt] - An optional mock doNotTrack string to ease unit testing. + * @params {string} [ua] - An optional mock userAgent string to ease unit testing. + * @returns {boolean} true if enabled else false + */ +Mozilla.dntEnabled = function(dnt, ua) { + 'use strict'; + + // for old version of IE we need to use the msDoNotTrack property of navigator + // on newer versions, and newer platforms, this is doNotTrack but, on the window object + // Safari also exposes the property on the window object. + var dntStatus = dnt || navigator.doNotTrack || window.doNotTrack || navigator.msDoNotTrack; + var userAgent = ua || navigator.userAgent; + + // List of Windows versions known to not implement DNT according to the standard. + var anomalousWinVersions = ['Windows NT 6.1', 'Windows NT 6.2', 'Windows NT 6.3']; + + var fxMatch = userAgent.match(/Firefox\/(\d+)/); + var ieRegEx = /MSIE|Trident/i; + var isIE = ieRegEx.test(userAgent); + // Matches from Windows up to the first occurance of ; un-greedily + // http://www.regexr.com/3c2el + var platform = userAgent.match(/Windows.+?(?=;)/g); + + // With old versions of IE, DNT did not exist so we simply return false; + if (isIE && typeof Array.prototype.indexOf !== 'function') { + return false; + } else if (fxMatch && parseInt(fxMatch[1], 10) < 32) { + // Can't say for sure if it is 1 or 0, due to Fx bug 887703 + dntStatus = 'Unspecified'; + } else if (isIE && platform && anomalousWinVersions.indexOf(platform.toString()) !== -1) { + // default is on, which does not honor the specification + dntStatus = 'Unspecified'; + } else { + // sets dntStatus to Disabled or Enabled based on the value returned by the browser. + // If dntStatus is undefined, it will be set to Unspecified + dntStatus = { '0': 'Disabled', '1': 'Enabled' }[dntStatus] || 'Unspecified'; + } + + return dntStatus === 'Enabled' ? true : false; +}; |