Commit ef36339a authored by Pietro Albini's avatar Pietro Albini

Merge branch 'master' of code.ubuntu-it.org:ubuntu-it-web/www-test

parents e107f1a6 aeec080b
No preview for this file type
#!/bin/bash
#
# Script to create a complete dump of a Drupal Postgresql database, keeping two backups at
# the same time, one for yesterday and one for today.
#
# You have to specify the folder where backups have to be saved and the name of
# the database.
# The script uses pg_dump
# Suggestion: indicate the complete path.
#
# Use as ./backup.sh ~/backupFolder databaseName
#
# Copyright (C) 2014 Riccardo Padovani <riccardo@rpadovani.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
# Backup directory
DIR=${1}
DBNAME=${2}
# Check if the directory exists, if not, create it
if [ ! -d "$DIR" ]; then
mkdir "$DIR"
fi
# If there is yesterday backup, then delete it
if [ -f "$DIR"/yesterday.tar.gz ]; then
rm -f "$DIR"/yesterday.tar.gz
fi
# If there is a backup of today, move it to yesterday
if [ -f "$DIR"/today.tar.gz ]; then
mv "$DIR"/today.tar.gz "$DIR"/yesterday.tar.gz
fi
# Create the backup
pg_dump "$DBNAME" > "$DIR"/today.sql
tar -cvzf "$DIR"/today.tar.gz "$DIR"/today.sql
# Remove the temp file
rm "$DIR"/today.sql
-- SQL file to strip out private informations from wwwtest.ubuntu-it.org
-- database that should be not around on developer systems, disable modules
-- that shouldn't be enabled and set admin password to one easy to use for
-- developing purposes
--
-- All our tables have 'drupal' as prepend
--
-- Copyright (C) 2014 Riccardo Padovani <riccardo@rpadovani.com>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
-- In drupal_authname there are all users authentication names.
-- We use OpenID, so there are only links to OpenID profiles.
-- If classic authentication is used, decomment the following lines
-- UPDATE drupal_authmap SET authname = CONCAT(aid, '@localhost');
-- In drupal_users there are some interesting informations:
-- Anyway, we don't want to use in local same users we use on test server,
-- because we disable OpenID module, otherwise no one could access but
-- ubuntu-it-www members
-- So we truncate the table and insert a new admin user with pass admin
TRUNCATE drupal_users;
INSERT INTO drupal_users(uid, name, pass, mail, timezone, language, status, init)
VALUES (1, 'admin', '434c3264048726754ee0e07e508d867e', 'admin@localhost', 'Europe/Berlin', 'it', 1, 'admin@localhost');
-- Turnoff modules
DELETE FROM drupal_system WHERE name IN ('tweet_button', 'openid_test', 'openid_launchpad', 'openid_teams', 'googleanalytics', 'google_plusone', 'openid', 'fblikebutton', 'disqus');
-- Delete emails from comments
UPDATE drupal_comment SET name='Anonymous', mail='anonymous@localhost', homepage='http://www.ubuntu-it.org' WHERE uid=0;
-- Truncate tables with sensitive data
TRUNCATE drupal_authmap;
TRUNCATE drupal_cache;
TRUNCATE drupal_cache_block;
TRUNCATE drupal_cache_bootstrap;
TRUNCATE drupal_cache_field;
TRUNCATE drupal_cache_filter;
TRUNCATE drupal_cache_form;
TRUNCATE drupal_cache_image;
TRUNCATE drupal_cache_l10n_update;
TRUNCATE drupal_cache_menu;
TRUNCATE drupal_cache_page;
TRUNCATE drupal_cache_panels;
TRUNCATE drupal_cache_path;
TRUNCATE drupal_cache_token;
TRUNCATE drupal_cache_update;
TRUNCATE drupal_cache_views;
TRUNCATE drupal_cache_views_data;
TRUNCATE drupal_disqus;
TRUNCATE drupal_flood;
TRUNCATE drupal_history;
TRUNCATE drupal_openid_association;
TRUNCATE drupal_openid_nonce;
TRUNCATE drupal_openid_teams_roles;
TRUNCATE drupal_openid_teams_trusted;
TRUNCATE drupal_search_dataset;
TRUNCATE drupal_search_index;
TRUNCATE drupal_search_node_links;
TRUNCATE drupal_search_total;
TRUNCATE drupal_sessions;
TRUNCATE drupal_watchdog;
-- Delete sensitive variables
DELETE FROM drupal_variable WHERE name IN ('drupal_secret_key', 'cron_key');
DELETE FROM drupal_variable WHERE name LIKE 'openid_%';
DELETE FROM drupal_variable WHERE name LIKE 'disqus_%';
#!/bin/bash
#
# Script to create a scrubbed version of a pgsql 9.x database dump using a temp database
# as intermediary.
#
# You need a file named 'scrub.sql' with querys to scrub the db
#
# Use as ./sql_scrub_dump.sh dump_file_input.tar.gz dump_file_output.tar.gz
# Of course you need to launch it with a user which has a role to create
# database in Postgresql
#
# The input and the output dump have to be .tar.gz.
#
# Copyright (C) 2014 Riccardo Padovani <riccardo@rpadovani.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Some params
local_db='temp_scrub'
dump_input=${1}
dump_output=${2}
# Destroy previous temp database and create a new one
dropdb "$local_db"
createdb "$local_db"
# If there is yesterday backup, then delete it
if [ -f "$dump_output" ]; then
rm -f "$dump_output"
fi
# Extract the file and import in psql
tar -xOvf "$dump_input" | psql "$local_db"
# Scrub the database
psql "$local_db" < scrub.sql
# Export the db
pg_dump "$local_db" > scrubbed-db.sql
tar -cvzf "$dump_output" scrubbed-db.sql
# Removed temporary files
dropdb "$local_db"
rm -f scrubbed-db.sql
......@@ -15,7 +15,7 @@ Requirements
Installation
============
* Copy the 'googleanalytics' module directory in to your Drupal
Copy the 'googleanalytics' module directory in to your Drupal
sites/all/modules directory as usual.
......@@ -51,19 +51,22 @@ choice for "Add if the following PHP code returns TRUE." Sample PHP snippets
that can be used in this textarea can be found on the handbook page
"Overview-approach to block visibility" at http://drupal.org/node/64135.
Custom variables
=================
One example for custom variables tracking is the "User roles" tracking. Enter
the below configuration data into the custom variables settings form under
admin/config/system/googleanalytics.
Custom dimensions and metrics
=============================
One example for custom dimensions tracking is the "User roles" tracking.
1. In the Google Analytics Management Interface you need to setup Dimension #1
with name e.g. "User roles". This step is required. Do not miss it, please.
2. Enter the below configuration data into the custom dimensions settings form
under admin/config/system/googleanalytics. You can also choose another index,
but keep it always in sync with the index used in step #1.
Slot: 1
Name: User roles
Value: [current-user:role-names]
Scope: Visitor
Index: 1
Value: [current-user:role-names]
More details about Custom variables can be found in the Google API documentation at
http://code.google.com/intl/en/apis/analytics/docs/tracking/gaTrackingCustomVariables.html
More details about custom dimensions and metrics can be found in the Google API
documentation at https://developers.google.com/analytics/devguides/collection/analyticsjs/custom-dims-mets
Advanced Settings
=================
......@@ -72,5 +75,5 @@ code textarea. These can be found on the official Google Analytics pages
and a few examples at http://drupal.org/node/248699. Support is not
provided for any customisations you include.
To speed up page loading you may also cache the Analytics ga.js
To speed up page loading you may also cache the Google Analytics "analytics.js"
file locally.
......@@ -91,7 +91,7 @@ Drupal.behaviors.trackingSettingsSummary = {
vals.push(Drupal.t('AdSense ads'));
}
if ($('input#edit-googleanalytics-trackdoubleclick', context).is(':checked')) {
vals.push(Drupal.t('DoubleClick data'));
vals.push(Drupal.t('Display features'));
}
if (!vals.length) {
return Drupal.t('Not tracked');
......
(function ($) {
Drupal.googleanalytics = {};
$(document).ready(function() {
// Attach mousedown, keyup, touchstart events to document only and catch
// clicks on all elements.
$(document.body).bind("mousedown keyup touchstart", function(event) {
console.group("Running Google Analytics for Drupal.");
console.info(event);
// Catch the closest surrounding link of a clicked element.
$(event.target).closest("a,area").each(function() {
console.info("Element '%o' has been detected. Link '%s' found.", this, this.href);
// Is the clicked URL internal?
if (Drupal.googleanalytics.isInternal(this.href)) {
// Skip 'click' tracking, if custom tracking events are bound.
if ($(this).is('.colorbox')) {
// Do nothing here. The custom event will handle all tracking.
console.info("Click on .colorbox item has been detected.");
}
// Is download tracking activated and the file extension configured for download tracking?
else if (Drupal.settings.googleanalytics.trackDownload && Drupal.googleanalytics.isDownload(this.href)) {
// Download link clicked.
console.info("Download url '%s' has been found. Tracked download as extension '%s'.", Drupal.googleanalytics.getPageUrl(this.href), Drupal.googleanalytics.getDownloadExtension(this.href).toUpperCase());
ga("send", "event", "Downloads", Drupal.googleanalytics.getDownloadExtension(this.href).toUpperCase(), Drupal.googleanalytics.getPageUrl(this.href));
}
else if (Drupal.googleanalytics.isInternalSpecial(this.href)) {
// Keep the internal URL for Google Analytics website overlay intact.
console.info("Click on internal special link '%s' has been tracked.", Drupal.googleanalytics.getPageUrl(this.href));
ga("send", "pageview", { page: Drupal.googleanalytics.getPageUrl(this.href) });
}
else {
// e.g. anchor in same page or other internal page link
console.info("Click on internal link '%s' detected, but not tracked by click.", this.href);
}
}
else {
if (Drupal.settings.googleanalytics.trackMailto && $(this).is("a[href^='mailto:'],area[href^='mailto:']")) {
// Mailto link clicked.
console.info("Click on e-mail '%s' has been tracked.", this.href.substring(7));
ga("send", "event", "Mails", "Click", this.href.substring(7));
}
else if (Drupal.settings.googleanalytics.trackOutbound && this.href.match(/^\w+:\/\//i)) {
if (Drupal.settings.googleanalytics.trackDomainMode != 2 && !Drupal.googleanalytics.isCrossDomain(this.hostname, Drupal.settings.googleanalytics.trackCrossDomains)) {
// External link clicked / No top-level cross domain clicked.
console.info("Outbound link '%s' has been tracked.", this.href);
ga("send", "event", "Outbound links", "Click", this.href);
}
else {
console.info("Internal link '%s' clicked, not tracked.", this.href);
}
}
}
});
console.groupEnd();
});
// Track hash changes as unique pageviews, if this option has been enabled.
if (Drupal.settings.googleanalytics.trackUrlFragments) {
window.onhashchange = function() {
console.info("Track URL '%s' as pageview. Hash '%s' has changed.", location.pathname + location.search + location.hash, location.hash);
ga('send', 'pageview', location.pathname + location.search + location.hash);
}
}
// Colorbox: This event triggers when the transition has completed and the
// newly loaded content has been revealed.
$(document).bind("cbox_complete", function () {
var href = $.colorbox.element().attr("href");
if (href) {
console.info("Colorbox transition to url '%s' has been tracked.", Drupal.googleanalytics.getPageUrl(href));
ga("send", "pageview", { page: Drupal.googleanalytics.getPageUrl(href) });
}
});
});
/**
* Check whether the hostname is part of the cross domains or not.
*
* @param string hostname
* The hostname of the clicked URL.
* @param array crossDomains
* All cross domain hostnames as JS array.
*
* @return boolean
*/
Drupal.googleanalytics.isCrossDomain = function (hostname, crossDomains) {
/**
* jQuery < 1.6.3 bug: $.inArray crushes IE6 and Chrome if second argument is
* `null` or `undefined`, http://bugs.jquery.com/ticket/10076,
* https://github.com/jquery/jquery/commit/a839af034db2bd934e4d4fa6758a3fed8de74174
*
* @todo: Remove/Refactor in D8
*/
if (!crossDomains) {
return false;
}
else {
return $.inArray(hostname, crossDomains) > -1 ? true : false;
}
}
/**
* Check whether this is a download URL or not.
*
* @param string url
* The web url to check.
*
* @return boolean
*/
Drupal.googleanalytics.isDownload = function (url) {
var isDownload = new RegExp("\\.(" + Drupal.settings.googleanalytics.trackDownloadExtensions + ")([\?#].*)?$", "i");
return isDownload.test(url);
}
/**
* Check whether this is an absolute internal URL or not.
*
* @param string url
* The web url to check.
*
* @return boolean
*/
Drupal.googleanalytics.isInternal = function (url) {
var isInternal = new RegExp("^(https?):\/\/" + window.location.host, "i");
return isInternal.test(url);
}
/**
* Check whether this is a special URL or not.
*
* URL types:
* - gotwo.module /go/* links.
*
* @param string url
* The web url to check.
*
* @return boolean
*/
Drupal.googleanalytics.isInternalSpecial = function (url) {
var isInternalSpecial = new RegExp("(\/go\/.*)$", "i");
return isInternalSpecial.test(url);
}
/**
* Extract the relative internal URL from an absolute internal URL.
*
* Examples:
* - http://mydomain.com/node/1 -> /node/1
* - http://example.com/foo/bar -> http://example.com/foo/bar
*
* @param string url
* The web url to check.
*
* @return string
* Internal website URL
*/
Drupal.googleanalytics.getPageUrl = function (url) {
var extractInternalUrl = new RegExp("^(https?):\/\/" + window.location.host, "i");
return url.replace(extractInternalUrl, '');
}
/**
* Extract the download file extension from the URL.
*
* @param string url
* The web url to check.
*
* @return string
* The file extension of the passed url. e.g. "zip", "txt"
*/
Drupal.googleanalytics.getDownloadExtension = function (url) {
var extractDownloadextension = new RegExp("\\.(" + Drupal.settings.googleanalytics.trackDownloadExtensions + ")([\?#].*)?$", "i");
var extension = extractDownloadextension.exec(url);
return (extension === null) ? '' : extension[1];
}
})(jQuery);
......@@ -5,9 +5,9 @@ package = Statistics
configure = admin/config/system/googleanalytics
files[] = googleanalytics.test
test_dependencies[] = token
; Information added by drupal.org packaging script on 2013-10-17
version = "7.x-1.4"
; Information added by Drupal.org packaging script on 2014-07-01
version = "7.x-2.0"
core = "7.x"
project = "google_analytics"
datestamp = "1382021586"
datestamp = "1404257628"
......@@ -5,33 +5,21 @@
* Installation file for Google Analytics module.
*/
/**
* Implements hook_install().
*/
function googleanalytics_install() {
// By German laws it's always best to enable the anonymizing of IP addresses.
// NOTE: If this is also an important default setting in other countries, please let us know!
$countries = array(
'DE',
);
if (in_array(variable_get('site_default_country', ''), $countries)) {
variable_set('googleanalytics_tracker_anonymizeip', 1);
}
}
/**
* Implements hook_uninstall().
*/
function googleanalytics_uninstall() {
variable_del('googleanalytics_account');
variable_del('googleanalytics_cache');
variable_del('googleanalytics_codesnippet_create');
variable_del('googleanalytics_codesnippet_before');
variable_del('googleanalytics_codesnippet_after');
variable_del('googleanalytics_cross_domains');
variable_del('googleanalytics_custom');
variable_del('googleanalytics_custom_var');
variable_del('googleanalytics_custom_dimension');
variable_del('googleanalytics_custom_metric');
variable_del('googleanalytics_debug');
variable_del('googleanalytics_domain_mode');
variable_del('googleanalytics_js_scope');
variable_del('googleanalytics_last_cache');
variable_del('googleanalytics_pages');
variable_del('googleanalytics_roles');
......@@ -41,6 +29,9 @@ function googleanalytics_uninstall() {
variable_del('googleanalytics_tracker_anonymizeip');
variable_del('googleanalytics_trackfiles');
variable_del('googleanalytics_trackfiles_extensions');
variable_del('googleanalytics_tracklinkid');
variable_del('googleanalytics_trackurlfragments');
variable_del('googleanalytics_trackuserid');
variable_del('googleanalytics_trackmailto');
variable_del('googleanalytics_trackmessages');
variable_del('googleanalytics_trackoutbound');
......@@ -52,6 +43,8 @@ function googleanalytics_uninstall() {
// Remove backup variables if exist. Remove this code in D8.
variable_del('googleanalytics_codesnippet_after_backup_6300');
variable_del('googleanalytics_codesnippet_before_backup_6300');
variable_del('googleanalytics_codesnippet_after_backup_7200');
variable_del('googleanalytics_codesnippet_before_backup_7200');
variable_del('googleanalytics_segmentation');
}
......@@ -73,8 +66,8 @@ function googleanalytics_requirements($phase) {
if ($phase == 'runtime') {
// Raise warning if Google user account has not been set yet.
if (!preg_match('/^UA-\d{4,}-\d+$/', variable_get('googleanalytics_account', 'UA-'))) {
$requirements['googleanalytics'] = array(
if (!preg_match('/^UA-\d+-\d+$/', variable_get('googleanalytics_account', 'UA-'))) {
$requirements['googleanalytics_account'] = array(
'title' => $t('Google Analytics module'),
'description' => $t('Google Analytics module has not been configured yet. Please configure its settings from the <a href="@url">Google Analytics settings page</a>.', array('@url' => url('admin/config/system/googleanalytics'))),
'severity' => REQUIREMENT_WARNING,
......@@ -82,6 +75,15 @@ function googleanalytics_requirements($phase) {
);
}
}
// Raise warning if debugging is enabled.
if (variable_get('googleanalytics_debug', 0)) {
$requirements['google_analytics_debugging'] = array(
'title' => $t('Google Analytics module'),
'description' => $t('Google Analytics module has debugging enabled. Please disable debugging setting in production sites from the <a href="@url">Google Analytics settings page</a>.', array('@url' => url('admin/config/system/googleanalytics'))),
'severity' => REQUIREMENT_WARNING,
'value' => $t('Debugging enabled'),
);
}
return $requirements;
}
......@@ -427,10 +429,55 @@ function googleanalytics_update_7006() {
}
/**
* Delete obsolete googleanalytics_trackpageloadtime variable.
*/
* Delete obsolete googleanalytics_trackpageloadtime variable.
*/
function googleanalytics_update_7007() {
variable_del('googleanalytics_trackpageloadtime');
return t('Deleted obsolete googleanalytics_trackpageloadtime variable.');
}
/**
* Delete custom ga.js code snipptes to prevent malfunctions in new Universal Analytics tracker. A backup of your snippets will be created.
*/
function googleanalytics_update_7200() {
$messages = array();
// ga.js code will cause the tracker to break. Remove custom code snippets.
$googleanalytics_codesnippet_before = variable_get('googleanalytics_codesnippet_before', '');
if (!empty($googleanalytics_codesnippet_before)) {
variable_set('googleanalytics_codesnippet_before_backup_7200', $googleanalytics_codesnippet_before);
variable_del('googleanalytics_codesnippet_before');
drupal_set_message(Database::getConnection()->prefixTables("A backup of your previous Google Analytics code snippet has been saved in database table '{variable}' as 'googleanalytics_codesnippet_before_backup_7200'. You need to manually upgrade the custom 'before' code snippet."), 'warning');
$messages[] = t('Manual upgrade of custom "before" code snippet is required.');
}
$googleanalytics_codesnippet_after = variable_get('googleanalytics_codesnippet_after', '');
if (!empty($googleanalytics_codesnippet_after)) {
variable_set('googleanalytics_codesnippet_after_backup_7200', $googleanalytics_codesnippet_after);
variable_del('googleanalytics_codesnippet_after');
drupal_set_message(Database::getConnection()->prefixTables("A backup of your previous Google Analytics code snippet has been saved in database table '{variable}' as 'googleanalytics_codesnippet_before_backup_7200'. You need to manually upgrade the custom 'before' code snippet."), 'warning');
$messages[] = t('Manual upgrade of custom "after" code snippet is required.');
}
return empty($messages) ? t('No custom code snipped found. Nothing to do.') : implode(' ', $messages);
}
/**
* Delete obsolete custom variables. Custom variables are now custom dimensions and metrics.
*/
function googleanalytics_update_7201() {
variable_del('googleanalytics_custom_var');
return t('Deleted obsolete custom variables. Custom variables are now custom dimensions and metrics and you need to manually configure them!');
}
/**
* Delete obsolete JavaScript scope variable.
*/
function googleanalytics_update_7202() {
// Remove obsolete scope variable
variable_del('googleanalytics_js_scope');
return t('Removed obsolete JavaScript scope variable.');
}
(function ($) {
Drupal.googleanalytics = {};
$(document).ready(function() {
// Expression to check for absolute internal links.
var isInternal = new RegExp("^(https?):\/\/" + window.location.host, "i");
// Attach mousedown, keyup, touchstart events to document only and catch
// clicks on all elements.
$(document.body).bind("mousedown keyup touchstart", function(event) {
// Attach onclick event to document only and catch clicks on all elements.
$(document.body).click(function(event) {
// Catch the closest surrounding link of a clicked element.
$(event.target).closest("a,area").each(function() {
var ga = Drupal.settings.googleanalytics;
// Expression to check for special links like gotwo.module /go/* links.
var isInternalSpecial = new RegExp("(\/go\/.*)$", "i");
// Expression to check for download links.
var isDownload = new RegExp("\\.(" + ga.trackDownloadExtensions + ")$", "i");
// Is the clicked URL internal?
if (isInternal.test(this.href)) {
if (Drupal.googleanalytics.isInternal(this.href)) {
// Skip 'click' tracking, if custom tracking events are bound.
if ($(this).is('.colorbox')) {
// Do nothing here. The custom event will handle all tracking.
//console.info("Click on .colorbox item has been detected.");
}
// Is download tracking activated and the file extension configured for download tracking?
else if (ga.trackDownload && isDownload.test(this.href)) {
else if (Drupal.settings.googleanalytics.trackDownload && Drupal.googleanalytics.isDownload(this.href)) {
// Download link clicked.
var extension = isDownload.exec(this.href);
_gaq.push(["_trackEvent", "Downloads", extension[1].toUpperCase(), this.href.replace(isInternal, '')]);
ga("send", "event", "Downloads", Drupal.googleanalytics.getDownloadExtension(this.href).toUpperCase(), Drupal.googleanalytics.getPageUrl(this.href));
}
else if (isInternalSpecial.test(this.href)) {
else if (Drupal.googleanalytics.isInternalSpecial(this.href)) {
// Keep the internal URL for Google Analytics website overlay intact.
_gaq.push(["_trackPageview", this.href.replace(isInternal, '')]);
ga("send", "pageview", { page: Drupal.googleanalytics.getPageUrl(this.href) });
}
}
else {
if (ga.trackMailto && $(this).is("a[href^='mailto:'],area[href^='mailto:']")) {
if (Drupal.settings.googleanalytics.trackMailto && $(this).is("a[href^='mailto:'],area[href^='mailto:']")) {
// Mailto link clicked.
_gaq.push(["_trackEvent", "Mails", "Click", this.href.substring(7)]);
ga("send", "event", "Mails", "Click", this.href.substring(7));
}
else if (ga.trackOutbound && this.href.match(/^\w+:\/\//i)) {
if (ga.trackDomainMode == 2 && isCrossDomain(this.hostname, ga.trackCrossDomains)) {
// Top-level cross domain clicked. document.location is handled by _link internally.
event.preventDefault();
_gaq.push(["_link", this.href]);
}
else {
// External link clicked.
_gaq.push(["_trackEvent", "Outbound links", "Click", this.href]);
else if (Drupal.settings.googleanalytics.trackOutbound && this.href.match(/^\w+:\/\//i)) {
if (Drupal.settings.googleanalytics.trackDomainMode != 2 && !Drupal.googleanalytics.isCrossDomain(this.hostname, Drupal.settings.googleanalytics.trackCrossDomains)) {
// External link clicked / No top-level cross domain clicked.
ga("send", "event", "Outbound links", "Click", this.href);
}
}
}
});
});
// Track hash changes as unique pageviews, if this option has been enabled.
if (Drupal.settings.googleanalytics.trackUrlFragments) {
window.onhashchange = function() {
ga('send', 'pageview', location.pathname + location.search + location.hash);
}
}
// Colorbox: This event triggers when the transition has completed and the
// newly loaded content has been revealed.
$(document).bind("cbox_complete", function() {
$(document).bind("cbox_complete", function () {
var href = $.colorbox.element().attr("href");
if (href) {
_gaq.push(["_trackPageview", href.replace(isInternal, '')]);
ga("send", "pageview", { page: Drupal.googleanalytics.getPageUrl(href) });
}
});
......@@ -74,7 +71,7 @@ $(document).ready(function() {
*
* @return boolean
*/
function isCrossDomain(hostname, crossDomains) {
Drupal.googleanalytics.isCrossDomain = function (hostname, crossDomains) {
/**
* jQuery < 1.6.3 bug: $.inArray crushes IE6 and Chrome if second argument is
* `null` or `undefined`, http://bugs.jquery.com/ticket/10076,
......@@ -90,4 +87,79 @@ function isCrossDomain(hostname, crossDomains) {
}
}
/**
* Check whether this is a download URL or not.
*
* @param string url
* The web url to check.
*
* @return boolean
*/
Drupal.googleanalytics.isDownload = function (url) {
var isDownload = new RegExp("\\.(" + Drupal.settings.googleanalytics.trackDownloadExtensions + ")([\?#].*)?$", "i");
return isDownload.test(url);
}
/**
* Check whether this is an absolute internal URL or not.
*
* @param string url
* The web url to check.
*
* @return boolean
*/
Drupal.googleanalytics.isInternal = function (url) {
var isInternal = new RegExp("^(https?):\/\/" + window.location.host, "i");
return isInternal.test(url);
}
/**
* Check whether this is a special URL or not.
*
* URL types:
* - gotwo.module /go/* links.
*
* @param string url
* The web url to check.
*
* @return boolean
*/
Drupal.googleanalytics.isInternalSpecial = function (url) {
var isInternalSpecial = new RegExp("(\/go\/.*)$", "i");
return isInternalSpecial.test(url);
}
/**
* Extract the relative internal URL from an absolute internal URL.
*
* Examples:
* - http://mydomain.com/node/1 -> /node/1
* - http://example.com/foo/bar -> http://example.com/foo/bar
*
* @param string url
* The web url to check.
*
* @return string
* Internal website URL
*/
Drupal.googleanalytics.getPageUrl = function (url) {
var extractInternalUrl = new RegExp("^(https?):\/\/" + window.location.host, "i");
return url.replace(extractInternalUrl, '');
}
/**
* Extract the download file extension from the URL.
*
* @param string url
* The web url to check.
*
* @return string
* The file extension of the passed url. e.g. "zip", "txt"
*/
Drupal.googleanalytics.getDownloadExtension = function (url) {
var extractDownloadextension = new RegExp("\\.(" + Drupal.settings.googleanalytics.trackDownloadExtensions + ")([\?#].*)?$", "i");
var extension = extractDownloadextension.exec(url);
return (extension === null) ? '' : extension[1];
}
})(jQuery);
(function ($) {
/**
* This file is for developers only.
*
* This tests are made for the javascript functions used in GA module.
* These tests verify if the return values are properly working.
*
* Hopefully this can be added somewhere else once Drupal core has JavaScript
* unit testing integrated.
*/
"use strict";
Drupal.googleanalytics.test = {};
Drupal.googleanalytics.test.assertSame = function (value1, value2, message) {
if (value1 === value2) {
console.info(message);
}
else {
console.error(message);
}
}
Drupal.googleanalytics.test.assertNotSame = function (value1, value2, message) {
if (value1 !== value2) {
console.info(message);
}
else {
console.error(message);
}
}
Drupal.googleanalytics.test.assertTrue = function (value1, message) {
if (value1 === true) {
console.info(message);
}
else {
console.error(message);
}
}
Drupal.googleanalytics.test.assertFalse = function (value1, message) {
if (value1 === false) {
console.info(message);
}
else {
console.error(message);
}
}
// Run after the documented is ready or Drupal.settings is undefined.
$(document).ready(function() {
/**
* Run javascript tests against the GA module.
*/
// JavaScript debugging
var base_url = window.location.protocol + '//' + window.location.host;
var base_path = window.location.pathname;
console.dir(Drupal);
console.group("Test 'isDownload':");
Drupal.googleanalytics.test.assertFalse(Drupal.googleanalytics.isDownload(base_url + Drupal.settings.basePath + 'node/8'), "Verify that '/node/8' url is not detected as file download.");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isDownload(base_url + Drupal.settings.basePath + 'files/foo1.zip'), "Verify that '/files/foo1.zip' url is detected as a file download.");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isDownload(base_url + Drupal.settings.basePath + 'files/foo1.zip#foo'), "Verify that '/files/foo1.zip#foo' url is detected as a file download.");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isDownload(base_url + Drupal.settings.basePath + 'files/foo1.zip?foo=bar'), "Verify that '/files/foo1.zip?foo=bar' url is detected as a file download.");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isDownload(base_url + Drupal.settings.basePath + 'files/foo1.zip?foo=bar#foo'), "Verify that '/files/foo1.zip?foo=bar#foo' url is detected as a file download.");
Drupal.googleanalytics.test.assertFalse(Drupal.googleanalytics.isDownload(base_url + Drupal.settings.basePath + 'files/foo2.ddd'), "Verify that '/files/foo2.ddd' url is not detected as file download.");
console.groupEnd();
console.group("Test 'isInternal':");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isInternal(base_url + Drupal.settings.basePath + 'node/1'), "Link '" + base_url + Drupal.settings.basePath + "node/2' has been detected as internal link.");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isInternal(base_url + Drupal.settings.basePath + 'node/1#foo'), "Link '" + base_url + Drupal.settings.basePath + "node/1#foo' has been detected as internal link.");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isInternal(base_url + Drupal.settings.basePath + 'node/1?foo=bar'), "Link '" + base_url + Drupal.settings.basePath + "node/1?foo=bar' has been detected as internal link.");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isInternal(base_url + Drupal.settings.basePath + 'node/1?foo=bar#foo'), "Link '" + base_url + Drupal.settings.basePath + "node/1?foo=bar#foo' has been detected as internal link.");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isInternal(base_url + Drupal.settings.basePath + 'go/foo'), "Link '" + base_url + Drupal.settings.basePath + "go/foo' has been detected as internal link.");
Drupal.googleanalytics.test.assertFalse(Drupal.googleanalytics.isInternal('http://example.com/node/3'), "Link 'http://example.com/node/3' has been detected as external link.");
console.groupEnd();
console.group("Test 'isInternalSpecial':");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isInternalSpecial(base_url + Drupal.settings.basePath + 'go/foo'), "Link '" + base_url + Drupal.settings.basePath + "go/foo' has been detected as special internal link.");
Drupal.googleanalytics.test.assertFalse(Drupal.googleanalytics.isInternalSpecial(base_url + Drupal.settings.basePath + 'node/1'), "Link '" + base_url + Drupal.settings.basePath + "node/1' has been detected as special internal link.");
console.groupEnd();
console.group("Test 'getPageUrl':");
Drupal.googleanalytics.test.assertSame(base_path + 'node/1', Drupal.googleanalytics.getPageUrl(base_url + Drupal.settings.basePath + 'node/1'), "Absolute internal URL '" + Drupal.settings.basePath + "node/1' has been extracted from full qualified url '" + base_url + base_path + "node/1'.");
Drupal.googleanalytics.test.assertSame(base_path + 'node/1', Drupal.googleanalytics.getPageUrl(Drupal.settings.basePath + 'node/1'), "Absolute internal URL '" + Drupal.settings.basePath + "node/1' has been extracted from absolute url '" + base_path + "node/1'.");
Drupal.googleanalytics.test.assertSame('http://example.com/node/2', Drupal.googleanalytics.getPageUrl('http://example.com/node/2'), "Full qualified external url 'http://example.com/node/2' has been extracted.");
Drupal.googleanalytics.test.assertSame('//example.com/node/2', Drupal.googleanalytics.getPageUrl('//example.com/node/2'), "Full qualified external url '//example.com/node/2' has been extracted.");
console.groupEnd();
console.group("Test 'getDownloadExtension':");
Drupal.googleanalytics.test.assertSame('zip', Drupal.googleanalytics.getDownloadExtension(base_url + Drupal.settings.basePath + '/files/foo1.zip'), "Download extension 'zip' has been found in '" + base_url + Drupal.settings.basePath + "files/foo1.zip'.");
Drupal.googleanalytics.test.assertSame('zip', Drupal.googleanalytics.getDownloadExtension(base_url + Drupal.settings.basePath + '/files/foo1.zip#foo'), "Download extension 'zip' has been found in '" + base_url + Drupal.settings.basePath + "files/foo1.zip#foo'.");
Drupal.googleanalytics.test.assertSame('zip', Drupal.googleanalytics.getDownloadExtension(base_url + Drupal.settings.basePath + '/files/foo1.zip?foo=bar'), "Download extension 'zip' has been found in '" + base_url + Drupal.settings.basePath + "files/foo1.zip?foo=bar'.");
Drupal.googleanalytics.test.assertSame('zip', Drupal.googleanalytics.getDownloadExtension(base_url + Drupal.settings.basePath + '/files/foo1.zip?foo=bar#foo'), "Download extension 'zip' has been found in '" + base_url + Drupal.settings.basePath + "files/foo1.zip?foo=bar'.");
Drupal.googleanalytics.test.assertSame('', Drupal.googleanalytics.getDownloadExtension(base_url + Drupal.settings.basePath + '/files/foo2.dddd'), "No download extension found in '" + base_url + Drupal.settings.basePath + "files/foo2.dddd'.");
console.groupEnd();
// List of top-level domains: example.com, example.net
console.group("Test 'isCrossDomain' (requires cross domain configuration with 'example.com' and 'example.net'):");
if (Drupal.settings.googleanalytics.trackCrossDomains) {
console.dir(Drupal.settings.googleanalytics.trackCrossDomains);
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isCrossDomain('example.com', Drupal.settings.googleanalytics.trackCrossDomains), "URL 'example.com' has been found in cross domain list.");
Drupal.googleanalytics.test.assertTrue(Drupal.googleanalytics.isCrossDomain('example.net', Drupal.settings.googleanalytics.trackCrossDomains), "URL 'example.com' has been found in cross domain list.");
Drupal.googleanalytics.test.assertFalse(Drupal.googleanalytics.isCrossDomain('www.example.com', Drupal.settings.googleanalytics.trackCrossDomains), "URL 'www.example.com' not found in cross domain list.");
Drupal.googleanalytics.test.assertFalse(Drupal.googleanalytics.isCrossDomain('www.example.net', Drupal.settings.googleanalytics.trackCrossDomains), "URL 'www.example.com' not found in cross domain list.");
}
else {
console.warn('Cross domain tracking is not enabled. Tests skipped.');
}
console.groupEnd();
});
})(jQuery);
......@@ -45,7 +45,7 @@ function googleanalytics_validate_googleanalytics_account($variable) {
// Replace all type of dashes (n-dash, m-dash, minus) with the normal dashes.
$variable['value'] = str_replace(array('–', '—', '−'), '-', $variable['value']);
if (!preg_match('/^UA-\d{4,}-\d+$/', $variable['value'])) {
if (!preg_match('/^UA-\d+-\d+$/', $variable['value'])) {
return t('A valid Google Analytics Web Property ID is case sensitive and formatted like UA-xxxxxxx-yy.');
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment