security update for contrib modules
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
|
||||
Module: Google Analytics
|
||||
Author: Alexander Hass <http://drupal.org/user/85918>
|
||||
Author: Alexander Hass <https://drupal.org/user/85918>
|
||||
|
||||
|
||||
Description
|
||||
@@ -12,12 +12,20 @@ Requirements
|
||||
|
||||
* Google Analytics user account
|
||||
|
||||
|
||||
Installation
|
||||
============
|
||||
Copy the 'googleanalytics' module directory in to your Drupal
|
||||
sites/all/modules directory as usual.
|
||||
|
||||
Upgrading from 6.x-3.x and 7.x-1.x
|
||||
==================================
|
||||
If you upgrade from 6.x-3.x and 7.x-1.x (ga.js) to 7.x-2.x (analytics.js) you
|
||||
should verify if you used custom variables. Write down your settings or make a
|
||||
screenshot. You need to re-configure the settings to use custom dimensions or
|
||||
metrics. There is no automatic upgrade path for custom variables feature. All
|
||||
other module settings are upgraded automatically.
|
||||
|
||||
See https://support.google.com/analytics/answer/2795983?hl=en for more details.
|
||||
|
||||
Usage
|
||||
=====
|
||||
@@ -27,12 +35,8 @@ All pages will now have the required JavaScript added to the
|
||||
HTML footer can confirm this by viewing the page source from
|
||||
your browser.
|
||||
|
||||
New approach to page tracking in 5.x-1.5 and 6.x-1.1
|
||||
====================================================
|
||||
With 5.x-1.5 and 6.x-1.1 there are new settings on the settings page at
|
||||
admin/config/system/googleanalytics. The "Page specific tracking" area now
|
||||
comes with an interface that copies Drupal's block visibility settings.
|
||||
|
||||
Page specific tracking
|
||||
======================
|
||||
The default is set to "Add to every page except the listed pages". By
|
||||
default the following pages are listed for exclusion:
|
||||
|
||||
@@ -44,23 +48,24 @@ node/*/*
|
||||
user/*/*
|
||||
|
||||
These defaults are changeable by the website administrator or any other
|
||||
user with 'administer google analytics' permission.
|
||||
user with 'Administer Google Analytics' permission.
|
||||
|
||||
Like the blocks visibility settings in Drupal core, there is now a
|
||||
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.
|
||||
Like the blocks visibility settings in Drupal core, there is a 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 https://drupal.org/node/64135.
|
||||
|
||||
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.
|
||||
1. In the Google Analytics (https://marketingplatform.google.com/about/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.
|
||||
2. Enter the below configuration data into the Drupal 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.
|
||||
|
||||
Index: 1
|
||||
Value: [current-user:role-names]
|
||||
@@ -72,8 +77,28 @@ Advanced Settings
|
||||
=================
|
||||
You can include additional JavaScript snippets in the custom javascript
|
||||
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
|
||||
and a few examples at https://drupal.org/node/248699. Support is not
|
||||
provided for any customisations you include.
|
||||
|
||||
To speed up page loading you may also cache the Google Analytics "analytics.js"
|
||||
file locally.
|
||||
|
||||
Manual JS debugging
|
||||
===================
|
||||
For manual debugging of the JS code you are able to create a test node. This
|
||||
is the example HTML code for this test node. You need to enable debugging mode
|
||||
in your Drupal configuration of Google Analytics settings to see verbose
|
||||
messages in your browsers JS console.
|
||||
|
||||
Title: Google Analytics test page
|
||||
|
||||
Body:
|
||||
<ul>
|
||||
<li><a href="mailto:foo@example.com">Mailto</a></li>
|
||||
<li><a href="/files/test.txt">Download file</a></li>
|
||||
<li><a class="colorbox" href="#">Open colorbox</a></li>
|
||||
<li><a href="https://example.com/">External link</a></li>
|
||||
<li><a href="/go/test">Go link</a></li>
|
||||
</ul>
|
||||
|
||||
Text format: Full HTML
|
||||
|
||||
@@ -18,10 +18,17 @@ function googleanalytics_admin_settings_form($form_state) {
|
||||
'#title' => t('Web Property ID'),
|
||||
'#type' => 'textfield',
|
||||
'#default_value' => variable_get('googleanalytics_account', 'UA-'),
|
||||
'#size' => 15,
|
||||
'#size' => 20,
|
||||
'#maxlength' => 20,
|
||||
'#required' => TRUE,
|
||||
'#description' => t('This ID is unique to each site you want to track separately, and is in the form of UA-xxxxxxx-yy. To get a Web Property ID, <a href="@analytics">register your site with Google Analytics</a>, or if you already have registered your site, go to your Google Analytics Settings page to see the ID next to every site profile. <a href="@webpropertyid">Find more information in the documentation</a>.', array('@analytics' => 'http://www.google.com/analytics/', '@webpropertyid' => url('https://developers.google.com/analytics/resources/concepts/gaConceptsAccounts', array('fragment' => 'webProperty')))),
|
||||
'#description' => t('This ID is unique to each site you want to track separately, and is in the form of UA-xxxxxxx-yy. To get a Web Property ID, <a href="@analytics">register your site with Google Analytics</a>, or if you already have registered your site, go to your Google Analytics Settings page to see the ID next to every site profile. <a href="@webpropertyid">Find more information in the documentation</a>.', array('@analytics' => 'https://marketingplatform.google.com/about/analytics/', '@webpropertyid' => url('https://developers.google.com/analytics/resources/concepts/gaConceptsAccounts', array('fragment' => 'webProperty')))),
|
||||
);
|
||||
|
||||
$form['account']['googleanalytics_premium'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Premium account'),
|
||||
'#description' => t('If you are a Google Analytics Premium customer, you can use up to 200 instead of 20 custom dimensions and metrics.'),
|
||||
'#default_value' => variable_get('googleanalytics_premium', FALSE),
|
||||
);
|
||||
|
||||
// Visibility settings.
|
||||
@@ -169,7 +176,7 @@ function googleanalytics_admin_settings_form($form_state) {
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Users'),
|
||||
);
|
||||
$t_permission = array('%permission' => t('opt-in or out of tracking'));
|
||||
$t_permission = array('%permission' => t('Opt-in or out of tracking'));
|
||||
$form['tracking']['user_vis_settings']['googleanalytics_custom'] = array(
|
||||
'#type' => 'radios',
|
||||
'#title' => t('Allow users to customize tracking on their account page'),
|
||||
@@ -224,6 +231,18 @@ function googleanalytics_admin_settings_form($form_state) {
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$colorbox_dependencies = '<div class="admin-requirements">';
|
||||
$colorbox_dependencies .= t('Requires: !module-list', array('!module-list' => (module_exists('colorbox') ? t('@module (<span class="admin-enabled">enabled</span>)', array('@module' => 'Colorbox')) : t('@module (<span class="admin-disabled">disabled</span>)', array('@module' => 'Colorbox')))));
|
||||
$colorbox_dependencies .= '</div>';
|
||||
|
||||
$form['tracking']['linktracking']['googleanalytics_trackcolorbox'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Track content in colorbox modal dialogs'),
|
||||
'#default_value' => variable_get('googleanalytics_trackcolorbox', 1),
|
||||
'#description' => t('Enable to track the content shown in colorbox modal windows.') . $colorbox_dependencies,
|
||||
'#disabled' => (module_exists('colorbox') ? FALSE : TRUE),
|
||||
);
|
||||
$form['tracking']['linktracking']['googleanalytics_tracklinkid'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Track enhanced link attribution'),
|
||||
@@ -246,7 +265,7 @@ function googleanalytics_admin_settings_form($form_state) {
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => t('Track messages of type'),
|
||||
'#default_value' => variable_get('googleanalytics_trackmessages', array()),
|
||||
'#description' => t('This will track the selected message types shown to users. Tracking of form validation errors may help you identifying usability issues in your site. For each visit (user session), a maximum of approximately 500 combined GATC requests (both events and page views) can be tracked. Every message is tracked as one individual event. Note that - as the number of events in a session approaches the limit - additional events might not be tracked. Messages from excluded pages cannot tracked.'),
|
||||
'#description' => t('This will track the selected message types shown to users. Tracking of form validation errors may help you identifying usability issues in your site. For each visit (user session), a maximum of approximately 500 combined GATC requests (both events and page views) can be tracked. Every message is tracked as one individual event. Note that - as the number of events in a session approaches the limit - additional events might not be tracked. Messages from excluded pages cannot be tracked.'),
|
||||
'#options' => array(
|
||||
'status' => t('Status message'),
|
||||
'warning' => t('Warning message'),
|
||||
@@ -297,7 +316,7 @@ function googleanalytics_admin_settings_form($form_state) {
|
||||
$form['tracking']['privacy']['googleanalytics_privacy_donottrack'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Universal web tracking opt-out'),
|
||||
'#description' => t('If enabled and your server receives the <a href="@donottrack">Do-Not-Track</a> header from the client browser, the Google Analytics module will not embed any tracking code into your site. Compliance with Do Not Track could be purely voluntary, enforced by industry self-regulation, or mandated by state or federal law. Please accept your visitors privacy. If they have opt-out from tracking and advertising, you should accept their personal decision. This feature is currently limited to logged in users and disabled page caching.', array('@donottrack' => 'http://donottrack.us/')),
|
||||
'#description' => t('If enabled and your server receives the <a href="@donottrack">Do-Not-Track</a> header from the client browser, the Google Analytics module will not embed any tracking code into your site. Compliance with Do Not Track could be purely voluntary, enforced by industry self-regulation, or mandated by state or federal law. Please accept your visitors privacy. If they have opt-out from tracking and advertising, you should accept their personal decision. This feature is currently limited to logged in users and disabled page caching.', array('@donottrack' => 'https://www.eff.org/issues/do-not-track')),
|
||||
'#default_value' => variable_get('googleanalytics_privacy_donottrack', 1),
|
||||
);
|
||||
|
||||
@@ -305,7 +324,7 @@ function googleanalytics_admin_settings_form($form_state) {
|
||||
$form['googleanalytics_custom_dimension'] = array(
|
||||
'#collapsed' => TRUE,
|
||||
'#collapsible' => TRUE,
|
||||
'#description' => t('You can set values for Google Analytics <a href="@custom_var_documentation">Custom Dimensions</a> here. You must have already configured your custom dimensions in the <a href="@setup_documentation">Google Analytics Management Interface</a>. You may use tokens. Global and user tokens are always available; on node pages, node tokens are also available. A dimension <em>value</em> is allowed to have a maximum lenght of 150 bytes. Expect longer values to get trimmed.', array('@custom_var_documentation' => 'https://developers.google.com/analytics/devguides/collection/analyticsjs/custom-dims-mets', '@setup_documentation' => 'https://support.google.com/analytics/answer/2709829')),
|
||||
'#description' => t('You can set values for Google Analytics <a href="@custom_var_documentation">Custom Dimensions</a> here. You must have already configured your custom dimensions in the <a href="@setup_documentation">Google Analytics Management Interface</a>. You may use tokens. Global and user tokens are always available; on node pages, node tokens are also available. A dimension <em>value</em> is allowed to have a maximum length of 150 bytes. Expect longer values to get trimmed.', array('@custom_var_documentation' => 'https://developers.google.com/analytics/devguides/collection/analyticsjs/custom-dims-mets', '@setup_documentation' => 'https://support.google.com/analytics/answer/2709829')),
|
||||
'#theme' => 'googleanalytics_admin_custom_var_table',
|
||||
'#title' => t('Custom dimensions'),
|
||||
'#tree' => TRUE,
|
||||
@@ -314,8 +333,10 @@ function googleanalytics_admin_settings_form($form_state) {
|
||||
|
||||
$googleanalytics_custom_dimension = variable_get('googleanalytics_custom_dimension', array());
|
||||
|
||||
// Google Analytics supports up to 20 custom dimensions.
|
||||
for ($i = 1; $i <= 20; $i++) {
|
||||
// Standard Google Analytics accounts support up to 20 custom dimensions,
|
||||
// premium accounts support up to 200 custom dimensions.
|
||||
$limit = (variable_get('googleanalytics_premium', FALSE)) ? 200 : 20;
|
||||
for ($i = 1; $i <= $limit; $i++) {
|
||||
$form['googleanalytics_custom_dimension']['indexes'][$i]['index'] = array(
|
||||
'#default_value' => $i,
|
||||
'#description' => t('Index number'),
|
||||
@@ -342,7 +363,7 @@ function googleanalytics_admin_settings_form($form_state) {
|
||||
|
||||
$form['googleanalytics_custom_dimension']['googleanalytics_description'] = array(
|
||||
'#type' => 'item',
|
||||
'#description' => t('You can supplement Google Analytics\' basic IP address tracking of visitors by segmenting users based on custom dimensions. Section 7 of the <a href="@ga_tos">Google Analytics terms of service</a> requires that You will not (and will not allow any third party to) use the Service to track, collect or upload any data that personally identifies an individual (such as a name, userid, email address or billing information), or other data which can be reasonably linked to such information by Google. You will have and abide by an appropriate Privacy Policy and will comply with all applicable laws and regulations relating to the collection of information from Visitors. You must post a Privacy Policy and that Privacy Policy must provide notice of Your use of cookies that are used to collect traffic data, and You must not circumvent any privacy features (e.g., an opt-out) that are part of the Service.', array('@ga_tos' => 'http://www.google.com/analytics/terms/gb.html')),
|
||||
'#description' => t('You can supplement Google Analytics\' basic IP address tracking of visitors by segmenting users based on custom dimensions. Section 7 of the <a href="@ga_tos">Google Analytics terms of service</a> requires that You will not (and will not allow any third party to) use the Service to track, collect or upload any data that personally identifies an individual (such as a name, userid, email address or billing information), or other data which can be reasonably linked to such information by Google. You will have and abide by an appropriate Privacy Policy and will comply with all applicable laws and regulations relating to the collection of information from Visitors. You must post a Privacy Policy and that Privacy Policy must provide notice of Your use of cookies that are used to collect traffic data, and You must not circumvent any privacy features (e.g., an opt-out) that are part of the Service.', array('@ga_tos' => 'https://www.google.com/analytics/terms/gb.html')),
|
||||
);
|
||||
if (module_exists('token')) {
|
||||
$form['googleanalytics_custom_dimension']['googleanalytics_token_tree'] = array(
|
||||
@@ -365,8 +386,9 @@ function googleanalytics_admin_settings_form($form_state) {
|
||||
|
||||
$googleanalytics_custom_metric = variable_get('googleanalytics_custom_metric', array());
|
||||
|
||||
// Google Analytics supports up to 20 custom metrics.
|
||||
for ($i = 1; $i <= 20; $i++) {
|
||||
// Standard Google Analytics accounts support up to 20 custom metrics,
|
||||
// premium accounts support up to 200 custom metrics.
|
||||
for ($i = 1; $i <= $limit; $i++) {
|
||||
$form['googleanalytics_custom_metric']['indexes'][$i]['index'] = array(
|
||||
'#default_value' => $i,
|
||||
'#description' => t('Index number'),
|
||||
@@ -393,7 +415,7 @@ function googleanalytics_admin_settings_form($form_state) {
|
||||
|
||||
$form['googleanalytics_custom_metric']['googleanalytics_description'] = array(
|
||||
'#type' => 'item',
|
||||
'#description' => t('You can supplement Google Analytics\' basic IP address tracking of visitors by segmenting users based on custom metrics. Section 7 of the <a href="@ga_tos">Google Analytics terms of service</a> requires that You will not (and will not allow any third party to) use the Service to track, collect or upload any data that personally identifies an individual (such as a name, userid, email address or billing information), or other data which can be reasonably linked to such information by Google. You will have and abide by an appropriate Privacy Policy and will comply with all applicable laws and regulations relating to the collection of information from Visitors. You must post a Privacy Policy and that Privacy Policy must provide notice of Your use of cookies that are used to collect traffic data, and You must not circumvent any privacy features (e.g., an opt-out) that are part of the Service.', array('@ga_tos' => 'http://www.google.com/analytics/terms/gb.html')),
|
||||
'#description' => t('You can supplement Google Analytics\' basic IP address tracking of visitors by segmenting users based on custom metrics. Section 7 of the <a href="@ga_tos">Google Analytics terms of service</a> requires that You will not (and will not allow any third party to) use the Service to track, collect or upload any data that personally identifies an individual (such as a name, userid, email address or billing information), or other data which can be reasonably linked to such information by Google. You will have and abide by an appropriate Privacy Policy and will comply with all applicable laws and regulations relating to the collection of information from Visitors. You must post a Privacy Policy and that Privacy Policy must provide notice of Your use of cookies that are used to collect traffic data, and You must not circumvent any privacy features (e.g., an opt-out) that are part of the Service.', array('@ga_tos' => 'https://www.google.com/analytics/terms/gb.html')),
|
||||
);
|
||||
if (module_exists('token')) {
|
||||
$form['googleanalytics_custom_metric']['googleanalytics_token_tree'] = array(
|
||||
@@ -428,12 +450,14 @@ function googleanalytics_admin_settings_form($form_state) {
|
||||
);
|
||||
}
|
||||
|
||||
$user_access_add_js_snippets = !user_access('add JS snippets for google analytics');
|
||||
$user_access_add_js_snippets_permission_warning = $user_access_add_js_snippets ? ' <em>' . t('This field has been disabled because you do not have sufficient permissions to edit it.') . '</em>' : '';
|
||||
$form['advanced']['codesnippet'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Custom JavaScript code'),
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => TRUE,
|
||||
'#description' => t('You can add custom Google Analytics <a href="@snippets">code snippets</a> here. These will be added every time tracking is in effect. Before you add your custom code, you should read the <a href="@ga_concepts_overview">Google Analytics Tracking Code - Functional Overview</a> and the <a href="@ga_js_api">Google Analytics Tracking API</a> documentation. <strong>Do not include the <script> tags</strong>, and always end your code with a semicolon (;).', array('@snippets' => 'http://drupal.org/node/248699', '@ga_concepts_overview' => 'https://developers.google.com/analytics/resources/concepts/gaConceptsTrackingOverview', '@ga_js_api' => 'https://developers.google.com/analytics/devguides/collection/analyticsjs/method-reference')),
|
||||
'#description' => t('You can add custom Google Analytics <a href="@snippets">code snippets</a> here. These will be added every time tracking is in effect. Before you add your custom code, you should read the <a href="@ga_concepts_overview">Google Analytics Tracking Code - Functional Overview</a> and the <a href="@ga_js_api">Google Analytics Tracking API</a> documentation. <strong>Do not include the <script> tags</strong>, and always end your code with a semicolon (;).', array('@snippets' => 'https://drupal.org/node/248699', '@ga_concepts_overview' => 'https://developers.google.com/analytics/resources/concepts/gaConceptsTrackingOverview', '@ga_js_api' => 'https://developers.google.com/analytics/devguides/collection/analyticsjs/method-reference')),
|
||||
);
|
||||
$form['advanced']['codesnippet']['googleanalytics_codesnippet_create'] = array(
|
||||
'#type' => 'textarea',
|
||||
@@ -447,15 +471,17 @@ function googleanalytics_admin_settings_form($form_state) {
|
||||
'#type' => 'textarea',
|
||||
'#title' => t('Code snippet (before)'),
|
||||
'#default_value' => variable_get('googleanalytics_codesnippet_before', ''),
|
||||
'#disabled' => $user_access_add_js_snippets,
|
||||
'#rows' => 5,
|
||||
'#description' => t('Code in this textarea will be added <strong>before</strong> <code>ga("send", "pageview");</code>.'),
|
||||
'#description' => t('Code in this textarea will be added <strong>before</strong> <code>ga("send", "pageview");</code>.') . $user_access_add_js_snippets_permission_warning,
|
||||
);
|
||||
$form['advanced']['codesnippet']['googleanalytics_codesnippet_after'] = array(
|
||||
'#type' => 'textarea',
|
||||
'#title' => t('Code snippet (after)'),
|
||||
'#default_value' => variable_get('googleanalytics_codesnippet_after', ''),
|
||||
'#disabled' => $user_access_add_js_snippets,
|
||||
'#rows' => 5,
|
||||
'#description' => t('Code in this textarea will be added <strong>after</strong> <code>ga("send", "pageview");</code>. This is useful if you\'d like to track a site in two accounts.'),
|
||||
'#description' => t('Code in this textarea will be added <strong>after</strong> <code>ga("send", "pageview");</code>. This is useful if you\'d like to track a site in two accounts.') . $user_access_add_js_snippets_permission_warning,
|
||||
);
|
||||
|
||||
$form['advanced']['googleanalytics_debug'] = array(
|
||||
@@ -541,6 +567,12 @@ function googleanalytics_admin_settings_form_validate($form, &$form_state) {
|
||||
|
||||
/**
|
||||
* Layout for the custom variables table in the admin settings form.
|
||||
*
|
||||
* @param array $variables
|
||||
* An array contains the form elements.
|
||||
*
|
||||
* @return string
|
||||
* The rendered output.
|
||||
*/
|
||||
function theme_googleanalytics_admin_custom_var_table($variables) {
|
||||
$form = $variables['form'];
|
||||
@@ -551,7 +583,7 @@ function theme_googleanalytics_admin_custom_var_table($variables) {
|
||||
);
|
||||
|
||||
$rows = array();
|
||||
foreach (element_children($form['indexes']) as $key => $id) {
|
||||
foreach (element_children($form['indexes']) as $id) {
|
||||
$rows[] = array(
|
||||
'data' => array(
|
||||
drupal_render($form['indexes'][$id]['index']),
|
||||
@@ -600,11 +632,18 @@ function googleanalytics_token_element_validate(&$element, &$form_state) {
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $value
|
||||
* An array of token values.
|
||||
*
|
||||
* @return array
|
||||
* A unique array of invalid tokens.
|
||||
*/
|
||||
function _googleanalytics_get_forbidden_tokens($value) {
|
||||
$invalid_tokens = array();
|
||||
$value_tokens = is_string($value) ? token_scan($value) : $value;
|
||||
|
||||
foreach ($value_tokens as $type => $tokens) {
|
||||
foreach ($value_tokens as $tokens) {
|
||||
if (array_filter($tokens, '_googleanalytics_contains_forbidden_token')) {
|
||||
$invalid_tokens = array_merge($invalid_tokens, array_values($tokens));
|
||||
}
|
||||
@@ -617,8 +656,9 @@ function _googleanalytics_get_forbidden_tokens($value) {
|
||||
/**
|
||||
* Validate if a string contains forbidden tokens not allowed by privacy rules.
|
||||
*
|
||||
* @param $token_string
|
||||
* @param string $token_string
|
||||
* A string with one or more tokens to be validated.
|
||||
*
|
||||
* @return boolean
|
||||
* TRUE if blacklisted token has been found, otherwise FALSE.
|
||||
*/
|
||||
@@ -724,7 +764,7 @@ function _googleanalytics_extract_create_field_values($string) {
|
||||
$list = array_map('trim', $list);
|
||||
$list = array_filter($list, 'strlen');
|
||||
|
||||
foreach ($list as $position => $text) {
|
||||
foreach ($list as $text) {
|
||||
// Check for an explicit key.
|
||||
$matches = array();
|
||||
if (preg_match('/(.*)\|(.*)/', $text, $matches)) {
|
||||
@@ -755,16 +795,18 @@ function _googleanalytics_validate_create_field_name($name) {
|
||||
// List of supported field names:
|
||||
// https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#create
|
||||
$create_only_fields = array(
|
||||
'clientId',
|
||||
'userId',
|
||||
'sampleRate',
|
||||
'siteSpeedSampleRate',
|
||||
'alwaysSendReferrer',
|
||||
'allowAnchor',
|
||||
'alwaysSendReferrer',
|
||||
'clientId',
|
||||
'cookieName',
|
||||
'cookieDomain',
|
||||
'cookieExpires',
|
||||
'legacyCookieDomain',
|
||||
'legacyHistoryImport',
|
||||
'sampleRate',
|
||||
'siteSpeedSampleRate',
|
||||
'storage',
|
||||
'useAmpClientId',
|
||||
);
|
||||
|
||||
if ($name == 'name') {
|
||||
@@ -773,6 +815,9 @@ function _googleanalytics_validate_create_field_name($name) {
|
||||
if ($name == 'allowLinker') {
|
||||
return t('Create only field name %name is a disallowed field name. Please select <em>Multiple top-level domains</em> under <em>What are you tracking</em> to enable cross domain tracking.', array('%name' => $name));
|
||||
}
|
||||
if ($name == 'userId') {
|
||||
return t('Create only field name %name is a disallowed field name. Please enable <em>Track User ID</em> under <em>Tracking scope > Users</em>.', array('%name' => $name));
|
||||
}
|
||||
if (!in_array($name, $create_only_fields)) {
|
||||
return t('Create only field name %name is an unknown field name. Field names are case sensitive. Please see <a href="@url">create only fields</a> documentation for supported field names.', array('%name' => $name, '@url' => 'https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#create'));
|
||||
}
|
||||
|
||||
@@ -65,6 +65,15 @@ Drupal.behaviors.trackingSettingsSummary = {
|
||||
if ($('input#edit-googleanalytics-trackfiles', context).is(':checked')) {
|
||||
vals.push(Drupal.t('Downloads'));
|
||||
}
|
||||
if ($('input#edit-googleanalytics-trackcolorbox', context).is(':checked')) {
|
||||
vals.push(Drupal.t('Colorbox'));
|
||||
}
|
||||
if ($('input#edit-googleanalytics-tracklinkid', context).is(':checked')) {
|
||||
vals.push(Drupal.t('Link attribution'));
|
||||
}
|
||||
if ($('input#edit-googleanalytics-trackurlfragments', context).is(':checked')) {
|
||||
vals.push(Drupal.t('URL fragments'));
|
||||
}
|
||||
if (!vals.length) {
|
||||
return Drupal.t('Not tracked');
|
||||
}
|
||||
|
||||
@@ -8,16 +8,16 @@ $(document).ready(function() {
|
||||
// clicks on all elements.
|
||||
$(document.body).bind("mousedown keyup touchstart", function(event) {
|
||||
console.group("Running Google Analytics for Drupal.");
|
||||
console.info(event);
|
||||
console.info("Event '%s' has been detected.", event.type);
|
||||
|
||||
// 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);
|
||||
console.info("Closest element '%o' has been found. URL '%s' extracted.", 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')) {
|
||||
if ($(this).is('.colorbox') && (Drupal.settings.googleanalytics.trackColorbox)) {
|
||||
// Do nothing here. The custom event will handle all tracking.
|
||||
console.info("Click on .colorbox item has been detected.");
|
||||
}
|
||||
@@ -25,12 +25,22 @@ $(document).ready(function() {
|
||||
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));
|
||||
ga("send", {
|
||||
"hitType": "event",
|
||||
"eventCategory": "Downloads",
|
||||
"eventAction": Drupal.googleanalytics.getDownloadExtension(this.href).toUpperCase(),
|
||||
"eventLabel": Drupal.googleanalytics.getPageUrl(this.href),
|
||||
"transport": "beacon"
|
||||
});
|
||||
}
|
||||
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) });
|
||||
ga("send", {
|
||||
"hitType": "pageview",
|
||||
"page": Drupal.googleanalytics.getPageUrl(this.href),
|
||||
"transport": "beacon"
|
||||
});
|
||||
}
|
||||
else {
|
||||
// e.g. anchor in same page or other internal page link
|
||||
@@ -41,13 +51,25 @@ $(document).ready(function() {
|
||||
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));
|
||||
ga("send", {
|
||||
"hitType": "event",
|
||||
"eventCategory": "Mails",
|
||||
"eventAction": "Click",
|
||||
"eventLabel": this.href.substring(7),
|
||||
"transport": "beacon"
|
||||
});
|
||||
}
|
||||
else if (Drupal.settings.googleanalytics.trackOutbound && this.href.match(/^\w+:\/\//i)) {
|
||||
if (Drupal.settings.googleanalytics.trackDomainMode != 2 || (Drupal.settings.googleanalytics.trackDomainMode == 2 && !Drupal.googleanalytics.isCrossDomain(this.hostname, Drupal.settings.googleanalytics.trackCrossDomains))) {
|
||||
if (Drupal.settings.googleanalytics.trackDomainMode !== 2 || (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);
|
||||
ga("send", {
|
||||
"hitType": "event",
|
||||
"eventCategory": "Outbound links",
|
||||
"eventAction": "Click",
|
||||
"eventLabel": this.href,
|
||||
"transport": "beacon"
|
||||
});
|
||||
}
|
||||
else {
|
||||
console.info("Internal link '%s' clicked, not tracked.", this.href);
|
||||
@@ -63,19 +85,27 @@ $(document).ready(function() {
|
||||
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);
|
||||
}
|
||||
ga("send", {
|
||||
"hitType": "pageview",
|
||||
"page": 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) });
|
||||
}
|
||||
});
|
||||
if (Drupal.settings.googleanalytics.trackColorbox) {
|
||||
$(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", {
|
||||
"hitType": "pageview",
|
||||
"page": Drupal.googleanalytics.getPageUrl(href)
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -92,7 +122,7 @@ $(document).ready(function() {
|
||||
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,
|
||||
* `null` or `undefined`, https://bugs.jquery.com/ticket/10076,
|
||||
* https://github.com/jquery/jquery/commit/a839af034db2bd934e4d4fa6758a3fed8de74174
|
||||
*
|
||||
* @todo: Remove/Refactor in D8
|
||||
@@ -151,8 +181,8 @@ Drupal.googleanalytics.isInternalSpecial = function (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
|
||||
* - https://mydomain.com/node/1 -> /node/1
|
||||
* - https://example.com/foo/bar -> https://example.com/foo/bar
|
||||
*
|
||||
* @param string url
|
||||
* The web url to check.
|
||||
|
||||
@@ -5,9 +5,8 @@ package = Statistics
|
||||
configure = admin/config/system/googleanalytics
|
||||
files[] = googleanalytics.test
|
||||
test_dependencies[] = token
|
||||
; Information added by Drupal.org packaging script on 2014-11-29
|
||||
version = "7.x-2.1"
|
||||
; Information added by Drupal.org packaging script on 2019-01-31
|
||||
version = "7.x-2.6"
|
||||
core = "7.x"
|
||||
project = "google_analytics"
|
||||
datestamp = "1417276982"
|
||||
|
||||
datestamp = "1548968597"
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
function googleanalytics_uninstall() {
|
||||
variable_del('googleanalytics_account');
|
||||
variable_del('googleanalytics_premium');
|
||||
variable_del('googleanalytics_cache');
|
||||
variable_del('googleanalytics_codesnippet_create');
|
||||
variable_del('googleanalytics_codesnippet_before');
|
||||
@@ -25,6 +26,7 @@ function googleanalytics_uninstall() {
|
||||
variable_del('googleanalytics_roles');
|
||||
variable_del('googleanalytics_site_search');
|
||||
variable_del('googleanalytics_trackadsense');
|
||||
variable_del('googleanalytics_trackcolorbox');
|
||||
variable_del('googleanalytics_trackdoubleclick');
|
||||
variable_del('googleanalytics_tracker_anonymizeip');
|
||||
variable_del('googleanalytics_trackfiles');
|
||||
@@ -40,7 +42,7 @@ function googleanalytics_uninstall() {
|
||||
variable_del('googleanalytics_visibility_roles');
|
||||
variable_del('googleanalytics_privacy_donottrack');
|
||||
|
||||
// Remove backup variables if exist. Remove this code in D8.
|
||||
// Remove backup variables if they exist. Remove this code in D8.
|
||||
variable_del('googleanalytics_codesnippet_after_backup_7200');
|
||||
variable_del('googleanalytics_codesnippet_before_backup_7200');
|
||||
}
|
||||
@@ -87,7 +89,8 @@ function googleanalytics_requirements($phase) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade old extension variable to new and use old name as enabled/disabled flag.
|
||||
* Upgrade old extension variable to new and use old name as enabled/disabled
|
||||
* flag.
|
||||
*/
|
||||
function googleanalytics_update_6000() {
|
||||
variable_set('googleanalytics_trackfiles_extensions', variable_get('googleanalytics_trackfiles', '7z|aac|avi|csv|doc|exe|flv|gif|gz|jpe?g|js|mp(3|4|e?g)|mov|pdf|phps|png|ppt|rar|sit|tar|torrent|txt|wma|wmv|xls|xml|zip'));
|
||||
@@ -100,7 +103,8 @@ function googleanalytics_update_6000() {
|
||||
function googleanalytics_update_6001() {
|
||||
variable_set('googleanalytics_visibility', 0);
|
||||
|
||||
// Remove tracking from all administrative pages, see http://drupal.org/node/34970.
|
||||
// Remove tracking from all administrative pages, see:
|
||||
// https://drupal.org/node/34970.
|
||||
$pages = array(
|
||||
'admin*',
|
||||
'user*',
|
||||
@@ -113,11 +117,12 @@ function googleanalytics_update_6001() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade role settings and per user tracking settings
|
||||
* of "User 1" and remove outdated tracking variables.
|
||||
* Upgrade role settings and per user tracking settings of "User 1" and remove
|
||||
* outdated tracking variables.
|
||||
*/
|
||||
function googleanalytics_update_6002() {
|
||||
// Upgrade enabled/disabled roles to new logic (correct for upgrades from 5.x-1.4 and 6.x-1.0).
|
||||
// Upgrade enabled/disabled roles to new logic (correct for upgrades from
|
||||
// 5.x-1.4 and 6.x-1.0).
|
||||
$roles = array();
|
||||
$messages = array();
|
||||
foreach (user_roles() as $rid => $name) {
|
||||
@@ -136,7 +141,7 @@ function googleanalytics_update_6002() {
|
||||
if (!$track_user1 = variable_get('googleanalytics_track__user1', 1)) {
|
||||
variable_set('googleanalytics_custom', 1);
|
||||
|
||||
// Load user 1 object, set appropriate value and save new user settings back.
|
||||
// Load user 1 object, set appropriate value and save new user settings.
|
||||
$account = user_load(1);
|
||||
$account = user_save($account, array('data' => array('googleanalytics' => array('custom' => 0))), 'account');
|
||||
$messages[] = t('Disabled user specific page tracking for site administrator.');
|
||||
@@ -151,11 +156,11 @@ function googleanalytics_update_6002() {
|
||||
}
|
||||
|
||||
/**
|
||||
* #262468: Clear menu cache to solve stale menu data in 5.x-1.5 and 6.x-1.1
|
||||
* #262468: Clear menu cache to solve stale menu data in 5.x-1.5 and 6.x-1.1.
|
||||
*/
|
||||
function googleanalytics_update_6003() {
|
||||
menu_rebuild();
|
||||
return t('Menu has been rebuild.');
|
||||
return t('Menu has been rebuilt.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -230,8 +235,9 @@ function googleanalytics_update_6006() {
|
||||
/**
|
||||
* Remove "User identifier" and "User name" from segmentation fields.
|
||||
*
|
||||
* This is a data protection and privacy law change. For more information see Google Analytics
|
||||
* terms of use section 8.1 (http://www.google.com/analytics/en-GB/tos.html).
|
||||
* This is a data protection and privacy law change. For more information see
|
||||
* Google Analytics terms of use section 8.1:
|
||||
* https://www.google.com/analytics/en-GB/tos.html
|
||||
*/
|
||||
function googleanalytics_update_6007() {
|
||||
$profile_fields = variable_get('googleanalytics_segmentation', array());
|
||||
@@ -292,15 +298,15 @@ function googleanalytics_update_6300() {
|
||||
$messages[] = t('Upgraded custom "before" code snippet.');
|
||||
}
|
||||
|
||||
// Upgrade of AFTER code snippet.
|
||||
// We cannot update this code snippet automatically. Show message that the upgrade has been skipped.
|
||||
// Upgrade of AFTER code snippet. We cannot update this code snippet
|
||||
// automatically. Show message that the upgrade has been skipped.
|
||||
$code_after = variable_get('googleanalytics_codesnippet_after', '');
|
||||
if (!empty($code_after)) {
|
||||
drupal_set_message(Database::getConnection()->prefixTables("Automatic upgrade of Google Analytics custom 'after' code snippet has been skipped. Backup of previous code snippet has been saved in database table '{variable}' as 'googleanalytics_codesnippet_after_backup_6300'. You need to manually upgrade the custom 'after' code snippet."), 'error');
|
||||
$messages[] = t('Skipped custom "after" code snippet.');
|
||||
}
|
||||
|
||||
return empty($messages) ? t('No custom code snipped found. Nothing to do.') : implode(' ', $messages);
|
||||
return empty($messages) ? t('No custom code snippet found. Nothing to do.') : implode(' ', $messages);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -355,18 +361,20 @@ function googleanalytics_update_7002() {
|
||||
$googleanalytics_custom_vars['slots'][1]['slot'] = 1;
|
||||
$googleanalytics_custom_vars['slots'][1]['name'] = 'User roles';
|
||||
$googleanalytics_custom_vars['slots'][1]['value'] = '[current-user:role-names]';
|
||||
$googleanalytics_custom_vars['slots'][1]['scope'] = 1; // Sets the scope to visitor-level.
|
||||
// Sets the scope to visitor-level.
|
||||
$googleanalytics_custom_vars['slots'][1]['scope'] = 1;
|
||||
|
||||
variable_set('googleanalytics_custom_var', $googleanalytics_custom_vars);
|
||||
return t('The deprecated profile segmentation setting for "User roles" has been added to custom variables. You need to deselect all selected profile fields in <a href="@admin">Google Analytics settings</a> and upgrade other profile fields manually or you may loose tracking data in future! See Google Analytics <a href="@customvar">Custom Variables</a> for more information.', array('@customvar' => 'https://developers.google.com/analytics/devguides/collection/gajs/gaTrackingCustomVariables', '@admin' => url('admin/config/system/googleanalytics')));
|
||||
return t('The deprecated profile segmentation setting for "User roles" has been added to custom variables. You need to deselect all selected profile fields in <a href="@admin">Google Analytics settings</a> and upgrade other profile fields manually or you may lose tracking data in future! See Google Analytics <a href="@customvar">Custom Variables</a> for more information.', array('@customvar' => 'https://developers.google.com/analytics/devguides/collection/gajs/gaTrackingCustomVariables', '@admin' => url('admin/config/system/googleanalytics')));
|
||||
}
|
||||
else {
|
||||
return t('You need to deselect all selected profile fields in <a href="@admin">Google Analytics settings</a> and upgrade other profile fields manually or you may loose tracking data in future! See Google Analytics <a href="@customvar">Custom Variables</a> for more information.', array('@customvar' => 'https://developers.google.com/analytics/devguides/collection/gajs/gaTrackingCustomVariables', '@admin' => url('admin/config/system/googleanalytics')));
|
||||
return t('You need to deselect all selected profile fields in <a href="@admin">Google Analytics settings</a> and upgrade other profile fields manually or you may lose tracking data in future! See Google Analytics <a href="@customvar">Custom Variables</a> for more information.', array('@customvar' => 'https://developers.google.com/analytics/devguides/collection/gajs/gaTrackingCustomVariables', '@admin' => url('admin/config/system/googleanalytics')));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename googleanalytics_trackoutgoing variable to googleanalytics_trackoutbound.
|
||||
* Rename googleanalytics_trackoutgoing variable to
|
||||
* googleanalytics_trackoutbound.
|
||||
*/
|
||||
function googleanalytics_update_7003() {
|
||||
variable_set('googleanalytics_trackoutbound', variable_get('googleanalytics_trackoutgoing', 1));
|
||||
@@ -376,7 +384,8 @@ function googleanalytics_update_7003() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename googleanalytics_visibility variable to googleanalytics_visibility_pages for consistency.
|
||||
* Rename googleanalytics_visibility variable to
|
||||
* googleanalytics_visibility_pages for consistency.
|
||||
*/
|
||||
function googleanalytics_update_7004() {
|
||||
variable_set('googleanalytics_visibility_pages', variable_get('googleanalytics_visibility', 1));
|
||||
@@ -400,7 +409,7 @@ function googleanalytics_update_7005() {
|
||||
|
||||
$diff = array_diff($pages, preg_split('/(\r\n?|\n)/', variable_get('googleanalytics_pages', implode("\n", $pages))));
|
||||
if (empty($diff)) {
|
||||
// No diff to previous settings found. Update with new settings.
|
||||
// No difference to previous settings found. Update with new settings.
|
||||
$pages = array(
|
||||
'admin',
|
||||
'admin/*',
|
||||
@@ -436,7 +445,8 @@ function googleanalytics_update_7007() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete custom ga.js code snipptes to prevent malfunctions in new Universal Analytics tracker. A backup of your snippets will be created.
|
||||
* Delete custom ga.js code snippets to prevent malfunctions in new Universal
|
||||
* Analytics tracker. A backup of your snippets will be created.
|
||||
*/
|
||||
function googleanalytics_update_7200() {
|
||||
$messages = array();
|
||||
@@ -446,23 +456,24 @@ function googleanalytics_update_7200() {
|
||||
if (!empty($googleanalytics_codesnippet_before) && stristr($googleanalytics_codesnippet_before, '_gaq.push(')) {
|
||||
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.');
|
||||
drupal_set_message(Database::getConnection()->prefixTables("A backup of your previous Google Analytics code snippet (ga.js) has been saved in database table '{variable}' as 'googleanalytics_codesnippet_before_backup_7200'. You need to manually upgrade the custom 'before' code snippet to analytics.js API."), 'warning');
|
||||
$messages[] = t('Manual upgrade of custom "before" code snippet from ja.js to analytics.js API is required.');
|
||||
}
|
||||
|
||||
$googleanalytics_codesnippet_after = variable_get('googleanalytics_codesnippet_after', '');
|
||||
if (!empty($googleanalytics_codesnippet_after) && stristr($googleanalytics_codesnippet_after, '_gaq.push(')) {
|
||||
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.');
|
||||
drupal_set_message(Database::getConnection()->prefixTables("A backup of your previous Google Analytics code snippet (ga.js) has been saved in database table '{variable}' as 'googleanalytics_codesnippet_after_backup_7200'. You need to manually upgrade the custom 'after' code snippet to analytics.js API."), 'warning');
|
||||
$messages[] = t('Manual upgrade of custom "after" code snippet from ja.js to analytics.js API is required.');
|
||||
}
|
||||
|
||||
return empty($messages) ? t('No custom code snipped found. Nothing to do.') : implode(' ', $messages);
|
||||
return empty($messages) ? t('No custom code snippet found. Nothing to do.') : implode(' ', $messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete obsolete custom variables. Custom variables are now custom dimensions and metrics.
|
||||
* Delete obsolete custom variables. Custom variables are now custom dimensions
|
||||
* and metrics.
|
||||
*/
|
||||
function googleanalytics_update_7201() {
|
||||
variable_del('googleanalytics_custom_var');
|
||||
@@ -474,7 +485,7 @@ function googleanalytics_update_7201() {
|
||||
* Delete obsolete JavaScript scope variable.
|
||||
*/
|
||||
function googleanalytics_update_7202() {
|
||||
// Remove obsolete scope variable
|
||||
// Remove obsolete scope variable.
|
||||
variable_del('googleanalytics_js_scope');
|
||||
|
||||
return t('Removed obsolete JavaScript scope variable.');
|
||||
|
||||
@@ -14,29 +14,51 @@ $(document).ready(function() {
|
||||
// Is the clicked URL internal?
|
||||
if (Drupal.googleanalytics.isInternal(this.href)) {
|
||||
// Skip 'click' tracking, if custom tracking events are bound.
|
||||
if ($(this).is('.colorbox')) {
|
||||
if ($(this).is('.colorbox') && (Drupal.settings.googleanalytics.trackColorbox)) {
|
||||
// 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.
|
||||
ga("send", "event", "Downloads", Drupal.googleanalytics.getDownloadExtension(this.href).toUpperCase(), Drupal.googleanalytics.getPageUrl(this.href));
|
||||
ga("send", {
|
||||
"hitType": "event",
|
||||
"eventCategory": "Downloads",
|
||||
"eventAction": Drupal.googleanalytics.getDownloadExtension(this.href).toUpperCase(),
|
||||
"eventLabel": Drupal.googleanalytics.getPageUrl(this.href),
|
||||
"transport": "beacon"
|
||||
});
|
||||
}
|
||||
else if (Drupal.googleanalytics.isInternalSpecial(this.href)) {
|
||||
// Keep the internal URL for Google Analytics website overlay intact.
|
||||
ga("send", "pageview", { "page": Drupal.googleanalytics.getPageUrl(this.href) });
|
||||
ga("send", {
|
||||
"hitType": "pageview",
|
||||
"page": Drupal.googleanalytics.getPageUrl(this.href),
|
||||
"transport": "beacon"
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (Drupal.settings.googleanalytics.trackMailto && $(this).is("a[href^='mailto:'],area[href^='mailto:']")) {
|
||||
// Mailto link clicked.
|
||||
ga("send", "event", "Mails", "Click", this.href.substring(7));
|
||||
ga("send", {
|
||||
"hitType": "event",
|
||||
"eventCategory": "Mails",
|
||||
"eventAction": "Click",
|
||||
"eventLabel": this.href.substring(7),
|
||||
"transport": "beacon"
|
||||
});
|
||||
}
|
||||
else if (Drupal.settings.googleanalytics.trackOutbound && this.href.match(/^\w+:\/\//i)) {
|
||||
if (Drupal.settings.googleanalytics.trackDomainMode != 2 || (Drupal.settings.googleanalytics.trackDomainMode == 2 && !Drupal.googleanalytics.isCrossDomain(this.hostname, Drupal.settings.googleanalytics.trackCrossDomains))) {
|
||||
if (Drupal.settings.googleanalytics.trackDomainMode !== 2 || (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);
|
||||
ga("send", {
|
||||
"hitType": "event",
|
||||
"eventCategory": "Outbound links",
|
||||
"eventAction": "Click",
|
||||
"eventLabel": this.href,
|
||||
"transport": "beacon"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,18 +68,26 @@ $(document).ready(function() {
|
||||
// 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);
|
||||
}
|
||||
ga("send", {
|
||||
"hitType": "pageview",
|
||||
"page": 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) {
|
||||
ga("send", "pageview", { "page": Drupal.googleanalytics.getPageUrl(href) });
|
||||
}
|
||||
});
|
||||
if (Drupal.settings.googleanalytics.trackColorbox) {
|
||||
$(document).bind("cbox_complete", function () {
|
||||
var href = $.colorbox.element().attr("href");
|
||||
if (href) {
|
||||
ga("send", {
|
||||
"hitType": "pageview",
|
||||
"page": Drupal.googleanalytics.getPageUrl(href)
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -74,7 +104,7 @@ $(document).ready(function() {
|
||||
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,
|
||||
* `null` or `undefined`, https://bugs.jquery.com/ticket/10076,
|
||||
* https://github.com/jquery/jquery/commit/a839af034db2bd934e4d4fa6758a3fed8de74174
|
||||
*
|
||||
* @todo: Remove/Refactor in D8
|
||||
@@ -133,8 +163,8 @@ Drupal.googleanalytics.isInternalSpecial = function (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
|
||||
* - https://mydomain.com/node/1 -> /node/1
|
||||
* - https://example.com/foo/bar -> https://example.com/foo/bar
|
||||
*
|
||||
* @param string url
|
||||
* The web url to check.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Adds the required Javascript to all your Drupal pages to allow tracking by
|
||||
* the Google Analytics statistics package.
|
||||
*
|
||||
* @author: Alexander Hass <http://drupal.org/user/85918>
|
||||
* @author: Alexander Hass <https://drupal.org/user/85918>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -17,7 +17,7 @@ define('GOOGLEANALYTICS_TRACKFILES_EXTENSIONS', '7z|aac|arc|arj|asf|asx|avi|bin|
|
||||
|
||||
/**
|
||||
* Define default path exclusion list to remove tracking from admin pages,
|
||||
* see http://drupal.org/node/34970 for more information.
|
||||
* see https://drupal.org/node/34970 for more information.
|
||||
*/
|
||||
define('GOOGLEANALYTICS_PAGES', "admin\nadmin/*\nbatch\nnode/add*\nnode/*/*\nuser/*/*");
|
||||
|
||||
@@ -36,7 +36,7 @@ function googleanalytics_api() {
|
||||
function googleanalytics_help($path, $arg) {
|
||||
switch ($path) {
|
||||
case 'admin/config/system/googleanalytics':
|
||||
return t('<a href="@ga_url">Google Analytics</a> is a free (registration required) website traffic and marketing effectiveness service.', array('@ga_url' => 'http://www.google.com/analytics/'));
|
||||
return t('<a href="@ga_url">Google Analytics</a> is a free (registration required) website traffic and marketing effectiveness service.', array('@ga_url' => 'https://marketingplatform.google.com/about/analytics/'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +69,11 @@ function googleanalytics_permission() {
|
||||
'description' => t('Enter PHP code in the field for tracking visibility settings.'),
|
||||
'restrict access' => TRUE,
|
||||
),
|
||||
'add JS snippets for google analytics' => array(
|
||||
'title' => t('Add JavaScript snippets'),
|
||||
'description' => 'Enter JavaScript code snippets for advanced Google Analytics functionality.',
|
||||
'restrict access' => TRUE,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -93,7 +98,7 @@ function googleanalytics_menu() {
|
||||
* Implements hook_page_alter() to insert JavaScript to the appropriate scope/region of the page.
|
||||
*/
|
||||
function googleanalytics_page_alter(&$page) {
|
||||
global $user;
|
||||
global $base_path, $user;
|
||||
|
||||
$id = variable_get('googleanalytics_account', '');
|
||||
|
||||
@@ -125,8 +130,11 @@ function googleanalytics_page_alter(&$page) {
|
||||
$link_settings['trackDownload'] = $track_download;
|
||||
$link_settings['trackDownloadExtensions'] = $trackfiles_extensions;
|
||||
}
|
||||
if (module_exists('colorbox') && ($track_colorbox = variable_get('googleanalytics_trackcolorbox', 1))) {
|
||||
$link_settings['trackColorbox'] = $track_colorbox;
|
||||
}
|
||||
if ($track_domain_mode = variable_get('googleanalytics_domain_mode', 0)) {
|
||||
$link_settings['trackDomainMode'] = $track_domain_mode;
|
||||
$link_settings['trackDomainMode'] = (int) $track_domain_mode;
|
||||
}
|
||||
if ($track_cross_domains = variable_get('googleanalytics_cross_domains', '')) {
|
||||
$link_settings['trackCrossDomains'] = preg_split('/(\r\n?|\n)/', $track_cross_domains);
|
||||
@@ -193,11 +201,23 @@ function googleanalytics_page_alter(&$page) {
|
||||
|
||||
// Track access denied (403) and file not found (404) pages.
|
||||
if ($status == '403 Forbidden') {
|
||||
// See http://www.google.com/support/analytics/bin/answer.py?answer=86927
|
||||
$url_custom = '"/403.html?page=" + document.location.pathname + document.location.search + "&from=" + document.referrer';
|
||||
// See https://www.google.com/support/analytics/bin/answer.py?answer=86927
|
||||
$url_custom = '"' . $base_path . '403.html?page=" + document.location.pathname + document.location.search + "&from=" + document.referrer';
|
||||
}
|
||||
elseif ($status == '404 Not Found') {
|
||||
$url_custom = '"/404.html?page=" + document.location.pathname + document.location.search + "&from=" + document.referrer';
|
||||
$url_custom = '"' . $base_path . '404.html?page=" + document.location.pathname + document.location.search + "&from=" + document.referrer';
|
||||
}
|
||||
|
||||
// #2693595: User has entered an invalid login and clicked on forgot
|
||||
// password link. This link contains the username or email address and may
|
||||
// get send to Google if we do not override it. Override only if 'name'
|
||||
// query param exists. Last custom url condition, this need to win.
|
||||
//
|
||||
// URLs to protect are:
|
||||
// - user/password?name=username
|
||||
// - user/password?name=foo@example.com
|
||||
if (arg(0) == 'user' && arg(1) == 'password' && array_key_exists('name', drupal_get_query_parameters())) {
|
||||
$url_custom = '"' . $base_path . 'user/password"';
|
||||
}
|
||||
|
||||
// Add custom dimensions and metrics.
|
||||
@@ -248,11 +268,10 @@ function googleanalytics_page_alter(&$page) {
|
||||
$script .= '})(window,document,"script",';
|
||||
|
||||
// Which version of the tracking library should be used?
|
||||
$library_tracker_url = '//www.google-analytics.com/' . ($debug ? 'analytics_debug.js' : 'analytics.js');
|
||||
$library_cache_url = 'http:' . $library_tracker_url;
|
||||
$library_tracker_url = 'https://www.google-analytics.com/' . ($debug ? 'analytics_debug.js' : 'analytics.js');
|
||||
|
||||
// Should a local cached copy of analytics.js be used?
|
||||
if (variable_get('googleanalytics_cache', 0) && $url = _googleanalytics_cache($library_cache_url)) {
|
||||
if (variable_get('googleanalytics_cache', 0) && $url = _googleanalytics_cache($library_tracker_url)) {
|
||||
// A dummy query-string is added to filenames, to gain control over
|
||||
// browser-caching. The string changes on every update or full cache
|
||||
// flush, forcing browsers to load a new copy of the files, as the
|
||||
@@ -294,10 +313,7 @@ function googleanalytics_page_alter(&$page) {
|
||||
|
||||
// Track logged in users across all devices.
|
||||
if (variable_get('googleanalytics_trackuserid', 0) && user_is_logged_in()) {
|
||||
// The USER_ID value should be a unique, persistent, and non-personally
|
||||
// identifiable string identifier that represents a user or signed-in
|
||||
// account across devices.
|
||||
$create_only_fields['userId'] = drupal_hmac_base64($user->uid, drupal_get_private_key() . drupal_get_hash_salt());
|
||||
$create_only_fields['userId'] = google_analytics_user_id_hash($user->uid);
|
||||
}
|
||||
|
||||
// Create a tracker.
|
||||
@@ -352,13 +368,30 @@ function googleanalytics_page_alter(&$page) {
|
||||
// Custom tracking. Prepend before all other JavaScript.
|
||||
// @TODO: https://support.google.com/adsense/answer/98142
|
||||
// sounds like it could be appended to $script.
|
||||
drupal_add_js($googleanalytics_adsense_script, array('type' => 'inline', 'group' => JS_LIBRARY-1));
|
||||
drupal_add_js($googleanalytics_adsense_script, array('type' => 'inline', 'group' => JS_LIBRARY-1, 'requires_jquery' => FALSE));
|
||||
}
|
||||
|
||||
drupal_add_js($script, array('scope' => 'header', 'type' => 'inline'));
|
||||
drupal_add_js($script, array('scope' => 'header', 'type' => 'inline', 'requires_jquery' => FALSE));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate user id hash to implement USER_ID.
|
||||
*
|
||||
* The USER_ID value should be a unique, persistent, and non-personally
|
||||
* identifiable string identifier that represents a user or signed-in
|
||||
* account across devices.
|
||||
*
|
||||
* @param int $uid
|
||||
* User id.
|
||||
*
|
||||
* @return string
|
||||
* User id hash.
|
||||
*/
|
||||
function google_analytics_user_id_hash($uid) {
|
||||
return drupal_hmac_base64($uid, drupal_get_private_key() . drupal_get_hash_salt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_extra_fields().
|
||||
*/
|
||||
@@ -440,7 +473,7 @@ function googleanalytics_user_presave(&$edit, $account, $category) {
|
||||
function googleanalytics_cron() {
|
||||
// Regenerate the tracking code file every day.
|
||||
if (REQUEST_TIME - variable_get('googleanalytics_last_cache', 0) >= 86400 && variable_get('googleanalytics_cache', 0)) {
|
||||
_googleanalytics_cache('http://www.google-analytics.com/analytics.js', TRUE);
|
||||
_googleanalytics_cache('https://www.google-analytics.com/analytics.js', TRUE);
|
||||
variable_set('googleanalytics_last_cache', REQUEST_TIME);
|
||||
}
|
||||
}
|
||||
@@ -456,14 +489,14 @@ function googleanalytics_preprocess_search_results(&$variables) {
|
||||
// found. But the pager item mumber can tell the number of search results.
|
||||
global $pager_total_items;
|
||||
|
||||
drupal_add_js('window.googleanalytics_search_results = ' . intval($pager_total_items[0]) . ';', array('type' => 'inline', 'group' => JS_LIBRARY-1));
|
||||
drupal_add_js('window.googleanalytics_search_results = ' . intval($pager_total_items[0]) . ';', array('type' => 'inline', 'group' => JS_LIBRARY-1, 'requires_jquery' => FALSE));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for grabbing search keys. Function is missing in D7.
|
||||
*
|
||||
* http://api.drupal.org/api/function/search_get_keys/6
|
||||
* https://api.drupal.org/api/function/search_get_keys/6
|
||||
*/
|
||||
function googleanalytics_search_get_keys() {
|
||||
static $return;
|
||||
@@ -504,6 +537,10 @@ function _googleanalytics_cache($location, $synchronize = FALSE) {
|
||||
if ($data_hash_local != $data_hash_remote && file_prepare_directory($path)) {
|
||||
// Save updated tracking code file to disk.
|
||||
file_unmanaged_save_data($result->data, $file_destination, FILE_EXISTS_REPLACE);
|
||||
// Based on Drupal Core drupal_build_css_cache().
|
||||
if (variable_get('css_gzip_compression', TRUE) && variable_get('clean_url', 0) && extension_loaded('zlib')) {
|
||||
file_unmanaged_save_data(gzencode($result->data, 9, FORCE_GZIP), $file_destination . '.gz', FILE_EXISTS_REPLACE);
|
||||
}
|
||||
watchdog('googleanalytics', 'Locally cached tracking code file has been updated.', array(), WATCHDOG_INFO);
|
||||
|
||||
// Change query-strings on css/js files to enforce reload for all users.
|
||||
@@ -516,6 +553,10 @@ function _googleanalytics_cache($location, $synchronize = FALSE) {
|
||||
// There is no need to flush JS here as core refreshes JS caches
|
||||
// automatically, if new files are added.
|
||||
file_unmanaged_save_data($result->data, $file_destination, FILE_EXISTS_REPLACE);
|
||||
// Based on Drupal Core drupal_build_css_cache().
|
||||
if (variable_get('css_gzip_compression', TRUE) && variable_get('clean_url', 0) && extension_loaded('zlib')) {
|
||||
file_unmanaged_save_data(gzencode($result->data, 9, FORCE_GZIP), $file_destination . '.gz', FILE_EXISTS_REPLACE);
|
||||
}
|
||||
watchdog('googleanalytics', 'Locally cached tracking code file has been saved.', array(), WATCHDOG_INFO);
|
||||
|
||||
// Return the local JS file path.
|
||||
|
||||
@@ -6,6 +6,13 @@
|
||||
*/
|
||||
class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
|
||||
|
||||
/**
|
||||
* User without permissions to edit snippets.
|
||||
*
|
||||
* @var \StdClass
|
||||
*/
|
||||
protected $noSnippetUser;
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Google Analytics basic tests',
|
||||
@@ -25,6 +32,8 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
|
||||
);
|
||||
|
||||
// User to set up google_analytics.
|
||||
$this->noSnippetUser = $this->drupalCreateUser($permissions);
|
||||
$permissions[] = 'add JS snippets for google analytics';
|
||||
$this->admin_user = $this->drupalCreateUser($permissions);
|
||||
$this->drupalLogin($this->admin_user);
|
||||
}
|
||||
@@ -48,13 +57,33 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
|
||||
$edit['googleanalytics_account'] = $this->randomName(2);
|
||||
$this->drupalPost('admin/config/system/googleanalytics', $edit, t('Save configuration'));
|
||||
$this->assertRaw(t('A valid Google Analytics Web Property ID is case sensitive and formatted like UA-xxxxxxx-yy.'), '[testGoogleAnalyticsConfiguration]: Invalid Web Property ID number validated.');
|
||||
|
||||
// User should have access to code snippets.
|
||||
$this->assertFieldByName('googleanalytics_codesnippet_create');
|
||||
$this->assertFieldByName('googleanalytics_codesnippet_before');
|
||||
$this->assertFieldByName('googleanalytics_codesnippet_after');
|
||||
$this->assertNoFieldByXPath("//textarea[@name='googleanalytics_codesnippet_create' and @disabled='disabled']", NULL, '"Create only fields" is enabled.');
|
||||
$this->assertNoFieldByXPath("//textarea[@name='googleanalytics_codesnippet_before' and @disabled='disabled']", NULL, '"Code snippet (before)" is enabled.');
|
||||
$this->assertNoFieldByXPath("//textarea[@name='googleanalytics_codesnippet_after' and @disabled='disabled']", NULL, '"Code snippet (after)" is enabled.');
|
||||
|
||||
// Login as user without JS permissions.
|
||||
$this->drupalLogin($this->noSnippetUser);
|
||||
$this->drupalGet('admin/config/system/googleanalytics');
|
||||
|
||||
// User should *not* have access to snippets, but create fields.
|
||||
$this->assertFieldByName('googleanalytics_codesnippet_create');
|
||||
$this->assertFieldByName('googleanalytics_codesnippet_before');
|
||||
$this->assertFieldByName('googleanalytics_codesnippet_after');
|
||||
$this->assertNoFieldByXPath("//textarea[@name='googleanalytics_codesnippet_create' and @disabled='disabled']", NULL, '"Create only fields" is enabled.');
|
||||
$this->assertFieldByXPath("//textarea[@name='googleanalytics_codesnippet_before' and @disabled='disabled']", NULL, '"Code snippet (before)" is disabled.');
|
||||
$this->assertFieldByXPath("//textarea[@name='googleanalytics_codesnippet_after' and @disabled='disabled']", NULL, '"Code snippet (after)" is disabled.');
|
||||
}
|
||||
|
||||
function testGoogleAnalyticsPageVisibility() {
|
||||
// Verify that no tracking code is embedded into the webpage; if there is
|
||||
// only the module installed, but UA code not configured. See #2246991.
|
||||
$this->drupalGet('');
|
||||
$this->assertNoRaw('//www.google-analytics.com/analytics.js', '[testGoogleAnalyticsPageVisibility]: Tracking code is not displayed without UA code configured.');
|
||||
$this->assertNoRaw('https://www.google-analytics.com/analytics.js', '[testGoogleAnalyticsPageVisibility]: Tracking code is not displayed without UA code configured.');
|
||||
|
||||
$ua_code = 'UA-123456-1';
|
||||
variable_set('googleanalytics_account', $ua_code);
|
||||
@@ -75,7 +104,7 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
|
||||
$this->assertNoRaw($ua_code, '[testGoogleAnalyticsPageVisibility]: Tracking code is not displayed on admin page.');
|
||||
$this->drupalGet('admin/config/system/googleanalytics');
|
||||
// Checking for tracking code URI here, as $ua_code is displayed in the form.
|
||||
$this->assertNoRaw('//www.google-analytics.com/analytics.js', '[testGoogleAnalyticsPageVisibility]: Tracking code is not displayed on admin subpage.');
|
||||
$this->assertNoRaw('https://www.google-analytics.com/analytics.js', '[testGoogleAnalyticsPageVisibility]: Tracking code is not displayed on admin subpage.');
|
||||
|
||||
// Test whether tracking code display is properly flipped.
|
||||
variable_set('googleanalytics_visibility_pages', 1);
|
||||
@@ -83,7 +112,7 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
|
||||
$this->assertRaw($ua_code, '[testGoogleAnalyticsPageVisibility]: Tracking code is displayed on admin page.');
|
||||
$this->drupalGet('admin/config/system/googleanalytics');
|
||||
// Checking for tracking code URI here, as $ua_code is displayed in the form.
|
||||
$this->assertRaw('//www.google-analytics.com/analytics.js', '[testGoogleAnalyticsPageVisibility]: Tracking code is displayed on admin subpage.');
|
||||
$this->assertRaw('https://www.google-analytics.com/analytics.js', '[testGoogleAnalyticsPageVisibility]: Tracking code is displayed on admin subpage.');
|
||||
$this->drupalGet('');
|
||||
$this->assertNoRaw($ua_code, '[testGoogleAnalyticsPageVisibility]: Tracking code is NOT displayed on front page.');
|
||||
|
||||
@@ -97,13 +126,15 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
|
||||
// Enable tracking code for all user roles.
|
||||
variable_set('googleanalytics_roles', array());
|
||||
|
||||
$base_path = base_path();
|
||||
|
||||
// Test whether 403 forbidden tracking code is shown if user has no access.
|
||||
$this->drupalGet('admin');
|
||||
$this->assertRaw('/403.html', '[testGoogleAnalyticsPageVisibility]: 403 Forbidden tracking code shown if user has no access.');
|
||||
$this->assertRaw($base_path . '403.html', '[testGoogleAnalyticsPageVisibility]: 403 Forbidden tracking code shown if user has no access.');
|
||||
|
||||
// Test whether 404 not found tracking code is shown on non-existent pages.
|
||||
$this->drupalGet($this->randomName(64));
|
||||
$this->assertRaw('/404.html', '[testGoogleAnalyticsPageVisibility]: 404 Not Found tracking code shown on non-existent page.');
|
||||
$this->assertRaw($base_path . '404.html', '[testGoogleAnalyticsPageVisibility]: 404 Not Found tracking code shown on non-existent page.');
|
||||
|
||||
// DNT Tests:
|
||||
// Enable system internal page cache for anonymous users.
|
||||
@@ -139,7 +170,7 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
|
||||
(function(q,u,i,c,k){window['GoogleAnalyticsObject']=q;
|
||||
window[q]=window[q]||function(){(window[q].q=window[q].q||[]).push(arguments)},
|
||||
window[q].l=1*new Date();c=i.createElement(u),k=i.getElementsByTagName(u)[0];
|
||||
c.async=true;c.src='//www.google-analytics.com/analytics.js';
|
||||
c.async=true;c.src='https://www.google-analytics.com/analytics.js';
|
||||
k.parentNode.insertBefore(c,k)})('ga','script',document);
|
||||
ga('create', 'UA-123456-7');
|
||||
ga('send', 'pageview');
|
||||
@@ -150,7 +181,7 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
|
||||
// Test whether tracking code uses latest JS.
|
||||
variable_set('googleanalytics_cache', 0);
|
||||
$this->drupalGet('');
|
||||
$this->assertRaw('//www.google-analytics.com/analytics.js', '[testGoogleAnalyticsTrackingCode]: Latest tracking code used.');
|
||||
$this->assertRaw('https://www.google-analytics.com/analytics.js', '[testGoogleAnalyticsTrackingCode]: Latest tracking code used.');
|
||||
|
||||
// Test whether anonymize visitors IP address feature has been enabled.
|
||||
variable_set('googleanalytics_tracker_anonymizeip', 0);
|
||||
@@ -227,13 +258,14 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
|
||||
$this->assertRaw('ga("create", "' . $ua_code . '", {"cookieDomain":"auto","allowLinker":true', '[testGoogleAnalyticsTrackingCode]: "allowLinker" has been found. Cross domain tracking is active.');
|
||||
$this->assertRaw('ga("require", "linker");', '[testGoogleAnalyticsTrackingCode]: Require linker has been found. Cross domain tracking is active.');
|
||||
$this->assertRaw('ga("linker:autoLink", ["www.example.com","www.example.net"]);', '[testGoogleAnalyticsTrackingCode]: "linker:autoLink" has been found. Cross domain tracking is active.');
|
||||
$this->assertRaw('"trackDomainMode":2,', '[testGoogleAnalyticsTrackingCode]: Domain mode value is of type integer.');
|
||||
$this->assertRaw('"trackCrossDomains":["www.example.com","www.example.net"]', '[testGoogleAnalyticsTrackingCode]: Cross domain tracking with www.example.com and www.example.net is active.');
|
||||
variable_set('googleanalytics_domain_mode', 0);
|
||||
|
||||
// Test whether debugging script has been enabled.
|
||||
variable_set('googleanalytics_debug', 1);
|
||||
$this->drupalGet('');
|
||||
$this->assertRaw('//www.google-analytics.com/analytics_debug.js', '[testGoogleAnalyticsTrackingCode]: Google debugging script has been enabled.');
|
||||
$this->assertRaw('https://www.google-analytics.com/analytics_debug.js', '[testGoogleAnalyticsTrackingCode]: Google debugging script has been enabled.');
|
||||
|
||||
// Check if text and link is shown on 'Status Reports' page.
|
||||
// Requires 'administer site configuration' permission.
|
||||
@@ -243,7 +275,7 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
|
||||
// Test whether debugging script has been disabled.
|
||||
variable_set('googleanalytics_debug', 0);
|
||||
$this->drupalGet('');
|
||||
$this->assertRaw('//www.google-analytics.com/analytics.js', '[testGoogleAnalyticsTrackingCode]: Google debugging script has been disabled.');
|
||||
$this->assertRaw('https://www.google-analytics.com/analytics.js', '[testGoogleAnalyticsTrackingCode]: Google debugging script has been disabled.');
|
||||
|
||||
// Test whether the CREATE and BEFORE and AFTER code is added to the tracker.
|
||||
$codesnippet_create = array(
|
||||
@@ -284,6 +316,7 @@ class GoogleAnalyticsCustomDimensionsAndMetricsTest extends DrupalWebTestCase {
|
||||
|
||||
// User to set up google_analytics.
|
||||
$this->admin_user = $this->drupalCreateUser($permissions);
|
||||
$this->drupalLogin($this->admin_user);
|
||||
}
|
||||
|
||||
function testGoogleAnalyticsCustomDimensions() {
|
||||
@@ -362,34 +395,30 @@ class GoogleAnalyticsCustomDimensionsAndMetricsTest extends DrupalWebTestCase {
|
||||
1 => array(
|
||||
'index' => 1,
|
||||
'value' => '6',
|
||||
'value_expected' => 6,
|
||||
),
|
||||
2 => array(
|
||||
'index' => 2,
|
||||
'value' => '8000',
|
||||
'value_expected' => 8000,
|
||||
),
|
||||
3 => array(
|
||||
'index' => 3,
|
||||
'value' => '7.8654',
|
||||
'value_expected' => 7.8654,
|
||||
),
|
||||
4 => array(
|
||||
'index' => 4,
|
||||
'value' => '1123.4',
|
||||
'value_expected' => 1123.4,
|
||||
),
|
||||
5 => array(
|
||||
'index' => 5,
|
||||
'value' => '5,67',
|
||||
'value_expected' => 5,
|
||||
),
|
||||
);
|
||||
|
||||
variable_set('googleanalytics_custom_metric', $googleanalytics_custom_metric);
|
||||
$this->drupalGet('');
|
||||
|
||||
foreach ($googleanalytics_custom_metric as $metric) {
|
||||
$this->assertRaw('ga("set", ' . drupal_json_encode('metric' . $metric['index']) . ', ' . drupal_json_encode($metric['value_expected']) . ');', '[testGoogleAnalyticsCustomDimensionsAndMetrics]: Metric #' . $metric['index'] . ' is shown.');
|
||||
$this->assertRaw('ga("set", ' . drupal_json_encode('metric' . $metric['index']) . ', ' . drupal_json_encode((float) $metric['value']) . ');', '[testGoogleAnalyticsCustomDimensionsAndMetrics]: Metric #' . $metric['index'] . ' is shown.');
|
||||
}
|
||||
|
||||
// Test whether tokens are replaced in custom metric values.
|
||||
@@ -421,6 +450,75 @@ class GoogleAnalyticsCustomDimensionsAndMetricsTest extends DrupalWebTestCase {
|
||||
$this->assertNoRaw('ga("set", ' . drupal_json_encode('metric3') . ', ' . drupal_json_encode('') . ');', '[testGoogleAnalyticsCustomDimensionsAndMetrics]: Empty value is not shown.');
|
||||
$this->assertRaw('ga("set", ' . drupal_json_encode('metric4') . ', ' . drupal_json_encode(0) . ');', '[testGoogleAnalyticsCustomDimensionsAndMetrics]: Value 0 is shown.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if Custom Dimensions token form validation works.
|
||||
*/
|
||||
public function testGoogleAnalyticsCustomDimensionsTokenFormValidation() {
|
||||
$ua_code = 'UA-123456-1';
|
||||
|
||||
// Check form validation.
|
||||
$edit['googleanalytics_account'] = $ua_code;
|
||||
$edit['googleanalytics_custom_dimension[indexes][1][value]'] = '[current-user:name]';
|
||||
$edit['googleanalytics_custom_dimension[indexes][2][value]'] = '[current-user:edit-url]';
|
||||
$edit['googleanalytics_custom_dimension[indexes][3][value]'] = '[user:name]';
|
||||
$edit['googleanalytics_custom_dimension[indexes][4][value]'] = '[term:name]';
|
||||
$edit['googleanalytics_custom_dimension[indexes][5][value]'] = '[term:tid]';
|
||||
|
||||
$this->drupalPost('admin/config/system/googleanalytics', $edit, t('Save configuration'));
|
||||
|
||||
$this->assertRaw(t('The %element-title is using the following forbidden tokens with personal identifying information: @invalid-tokens.', array('%element-title' => t('Custom dimension value #@index', array('@index' => 1)), '@invalid-tokens' => implode(', ', array('[current-user:name]')))));
|
||||
$this->assertRaw(t('The %element-title is using the following forbidden tokens with personal identifying information: @invalid-tokens.', array('%element-title' => t('Custom dimension value #@index', array('@index' => 2)), '@invalid-tokens' => implode(', ', array('[current-user:edit-url]')))));
|
||||
$this->assertRaw(t('The %element-title is using the following forbidden tokens with personal identifying information: @invalid-tokens.', array('%element-title' => t('Custom dimension value #@index', array('@index' => 3)), '@invalid-tokens' => implode(', ', array('[user:name]')))));
|
||||
// BUG #2037595
|
||||
//$this->assertNoRaw(t('The %element-title is using the following forbidden tokens with personal identifying information: @invalid-tokens.', array('%element-title' => t('Custom dimension value #@index', array('@index' => 4)), '@invalid-tokens' => implode(', ', array('[term:name]')))));
|
||||
//$this->assertNoRaw(t('The %element-title is using the following forbidden tokens with personal identifying information: @invalid-tokens.', array('%element-title' => t('Custom dimension value #@index', array('@index' => 5)), '@invalid-tokens' => implode(', ', array('[term:tid]')))));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test custom url functionality of Google Analytics module.
|
||||
*/
|
||||
class GoogleAnalyticsCustomUrls extends DrupalWebTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Google Analytics custom url tests',
|
||||
'description' => 'Test custom url functionality of Google Analytics module.',
|
||||
'group' => 'Google Analytics',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('googleanalytics');
|
||||
|
||||
$permissions = array(
|
||||
'access administration pages',
|
||||
'administer google analytics',
|
||||
);
|
||||
|
||||
// User to set up google_analytics.
|
||||
$this->admin_user = $this->drupalCreateUser($permissions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if user password page urls are overridden.
|
||||
*/
|
||||
public function testGoogleAnalyticsUserPasswordPage() {
|
||||
$base_path = base_path();
|
||||
$ua_code = 'UA-123456-4';
|
||||
variable_set('googleanalytics_account', $ua_code);
|
||||
|
||||
$this->drupalGet('user/password', array('query' => array('name' => 'foo')));
|
||||
$this->assertRaw('ga("set", "page", "' . $base_path . 'user/password"');
|
||||
|
||||
$this->drupalGet('user/password', array('query' => array('name' => 'foo@example.com')));
|
||||
$this->assertRaw('ga("set", "page", "' . $base_path . 'user/password"');
|
||||
|
||||
$this->drupalGet('user/password');
|
||||
$this->assertNoRaw('ga("set", "page",', '[testGoogleAnalyticsCustomUrls]: Custom url not set.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class GoogleAnalyticsStatusMessagesTest extends DrupalWebTestCase {
|
||||
@@ -460,7 +558,7 @@ class GoogleAnalyticsStatusMessagesTest extends DrupalWebTestCase {
|
||||
//drupal_set_message('Example status message.', 'status');
|
||||
//drupal_set_message('Example warning message.', 'warning');
|
||||
//drupal_set_message('Example error message.', 'error');
|
||||
//drupal_set_message('Example error <em>message</em> with html tags and <a href="http://example.com/">link</a>.', 'error');
|
||||
//drupal_set_message('Example error <em>message</em> with html tags and <a href="https://example.com/">link</a>.', 'error');
|
||||
//$this->drupalGet('');
|
||||
//$this->assertNoRaw('ga("send", "event", "Messages", "Status message", "Example status message.");', '[testGoogleAnalyticsStatusMessages]: Example status message is not enabled for tracking.');
|
||||
//$this->assertNoRaw('ga("send", "event", "Messages", "Warning message", "Example warning message.");', '[testGoogleAnalyticsStatusMessages]: Example warning message is not enabled for tracking.');
|
||||
@@ -684,13 +782,13 @@ class GoogleAnalyticsPhpFilterTest extends DrupalWebTestCase {
|
||||
// Check tracking code visibility.
|
||||
variable_set('googleanalytics_pages', '<?php return TRUE; ?>');
|
||||
$this->drupalGet('');
|
||||
$this->assertRaw('//www.google-analytics.com/analytics.js', '[testGoogleAnalyticsPhpFilter]: Tracking is displayed on frontpage page.');
|
||||
$this->assertRaw('https://www.google-analytics.com/analytics.js', '[testGoogleAnalyticsPhpFilter]: Tracking is displayed on frontpage page.');
|
||||
$this->drupalGet('admin');
|
||||
$this->assertRaw('//www.google-analytics.com/analytics.js', '[testGoogleAnalyticsPhpFilter]: Tracking is displayed on admin page.');
|
||||
$this->assertRaw('https://www.google-analytics.com/analytics.js', '[testGoogleAnalyticsPhpFilter]: Tracking is displayed on admin page.');
|
||||
|
||||
variable_set('googleanalytics_pages', '<?php return FALSE; ?>');
|
||||
$this->drupalGet('');
|
||||
$this->assertNoRaw('//www.google-analytics.com/analytics.js', '[testGoogleAnalyticsPhpFilter]: Tracking is not displayed on frontpage page.');
|
||||
$this->assertNoRaw('https://www.google-analytics.com/analytics.js', '[testGoogleAnalyticsPhpFilter]: Tracking is not displayed on frontpage page.');
|
||||
|
||||
// Test administration form.
|
||||
variable_set('googleanalytics_pages', '<?php return TRUE; ?>');
|
||||
|
||||
@@ -77,7 +77,7 @@ $(document).ready(function() {
|
||||
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.");
|
||||
Drupal.googleanalytics.test.assertFalse(Drupal.googleanalytics.isInternal('https://example.com/node/3'), "Link 'https://example.com/node/3' has been detected as external link.");
|
||||
console.groupEnd();
|
||||
|
||||
console.group("Test 'isInternalSpecial':");
|
||||
@@ -86,9 +86,11 @@ $(document).ready(function() {
|
||||
console.groupEnd();
|
||||
|
||||
console.group("Test 'getPageUrl':");
|
||||
Drupal.googleanalytics.test.assertSame(base_path, 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 + "'.");
|
||||
Drupal.googleanalytics.test.assertSame(base_path, Drupal.googleanalytics.getPageUrl(Drupal.settings.basePath + 'node/1'), "Absolute internal URL '" + Drupal.settings.basePath + "node/1' has been extracted from absolute url '" + base_path + "'.");
|
||||
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.google_analytics.test.assertSame(base_path, Drupal.google_analytics.getPageUrl(window.location.href), "Absolute internal URL '" + base_path + "' has been extracted from full qualified url '" + window.location.href + "'.");
|
||||
Drupal.google_analytics.test.assertSame(base_path, Drupal.google_analytics.getPageUrl(base_path), "Absolute internal URL '" + base_path + "' has been extracted from absolute url '" + base_path + "'.");
|
||||
//Drupal.googleanalytics.test.assertSame(base_path, 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 + "'.");
|
||||
//Drupal.googleanalytics.test.assertSame(base_path, Drupal.googleanalytics.getPageUrl(Drupal.settings.basePath + 'node/1'), "Absolute internal URL '" + Drupal.settings.basePath + "node/1' has been extracted from absolute url '" + base_path + "'.");
|
||||
Drupal.googleanalytics.test.assertSame('https://example.com/node/2', Drupal.googleanalytics.getPageUrl('https://example.com/node/2'), "Full qualified external url 'https://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();
|
||||
|
||||
@@ -105,9 +107,9 @@ $(document).ready(function() {
|
||||
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.assertTrue(Drupal.googleanalytics.isCrossDomain('example.net', Drupal.settings.googleanalytics.trackCrossDomains), "URL 'example.net' 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.");
|
||||
Drupal.googleanalytics.test.assertFalse(Drupal.googleanalytics.isCrossDomain('www.example.net', Drupal.settings.googleanalytics.trackCrossDomains), "URL 'www.example.net' not found in cross domain list.");
|
||||
}
|
||||
else {
|
||||
console.warn('Cross domain tracking is not enabled. Tests skipped.');
|
||||
|
||||
@@ -13,7 +13,7 @@ function googleanalytics_variable_info($options) {
|
||||
'type' => 'string',
|
||||
'title' => t('Web Property ID', array(), $options),
|
||||
'default' => 'UA-',
|
||||
'description' => t('This ID is unique to each site you want to track separately, and is in the form of UA-xxxxxxx-yy. To get a Web Property ID, <a href="@analytics">register your site with Google Analytics</a>, or if you already have registered your site, go to your Google Analytics Settings page to see the ID next to every site profile. <a href="@webpropertyid">Find more information in the documentation</a>.', array('@analytics' => 'http://www.google.com/analytics/', '@webpropertyid' => url('https://developers.google.com/analytics/resources/concepts/gaConceptsAccounts', array('fragment' => 'webProperty'))), $options),
|
||||
'description' => t('This ID is unique to each site you want to track separately, and is in the form of UA-xxxxxxx-yy. To get a Web Property ID, <a href="@analytics">register your site with Google Analytics</a>, or if you already have registered your site, go to your Google Analytics Settings page to see the ID next to every site profile. <a href="@webpropertyid">Find more information in the documentation</a>.', array('@analytics' => 'https://marketingplatform.google.com/about/analytics/', '@webpropertyid' => url('https://developers.google.com/analytics/resources/concepts/gaConceptsAccounts', array('fragment' => 'webProperty'))), $options),
|
||||
'required' => TRUE,
|
||||
'group' => 'googleanalytics',
|
||||
'localize' => TRUE,
|
||||
@@ -40,6 +40,10 @@ function googleanalytics_variable_group_info() {
|
||||
|
||||
/**
|
||||
* Validate Web Property ID variable.
|
||||
*
|
||||
* @param array $variable
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function googleanalytics_validate_googleanalytics_account($variable) {
|
||||
// Replace all type of dashes (n-dash, m-dash, minus) with the normal dashes.
|
||||
|
||||
Reference in New Issue
Block a user