'#description'=>t('User ID enables the analysis of groups of sessions, across devices, using a unique, persistent, and non-personally identifiable ID string representing a user. <a href="@url">Learn more about the benfits of using User ID</a>.',array('@url'=>'https://support.google.com/analytics/answer/3123663')),
'#description'=>t('User ID enables the analysis of groups of sessions, across devices, using a unique, persistent, and non-personally identifiable ID string representing a user. <a href="@url">Learn more about the benefits of using User ID</a>.',array('@url'=>'https://support.google.com/analytics/answer/3123663')),
);
);
// Link specific configurations.
// Link specific configurations.
...
@@ -213,7 +213,7 @@ function googleanalytics_admin_settings_form($form_state) {
...
@@ -213,7 +213,7 @@ function googleanalytics_admin_settings_form($form_state) {
'#description'=>t('A file extension list separated by the | character that will be tracked as download when clicked. Regular expressions are supported. For example: !extensions',array('!extensions'=>GOOGLEANALYTICS_TRACKFILES_EXTENSIONS)),
'#description'=>t('A file extension list separated by the | character that will be tracked as download when clicked. Regular expressions are supported. For example: !extensions',array('!extensions'=>GOOGLEANALYTICS_TRACKFILES_EXTENSIONS)),
@@ -307,7 +305,7 @@ function googleanalytics_admin_settings_form($form_state) {
...
@@ -307,7 +305,7 @@ function googleanalytics_admin_settings_form($form_state) {
$form['googleanalytics_custom_dimension']=array(
$form['googleanalytics_custom_dimension']=array(
'#collapsed'=>TRUE,
'#collapsed'=>TRUE,
'#collapsible'=>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.',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 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')),
'#title'=>t('Custom dimension value #@index',array('@index'=>$i)),
'#title'=>t('Custom dimension value #@index',array('@index'=>$i)),
...
@@ -346,11 +344,13 @@ function googleanalytics_admin_settings_form($form_state) {
...
@@ -346,11 +344,13 @@ function googleanalytics_admin_settings_form($form_state) {
'#type'=>'item',
'#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'=>'http://www.google.com/analytics/terms/gb.html')),
'#title'=>t('Custom metric value #@index',array('@index'=>$i)),
'#title'=>t('Custom metric value #@index',array('@index'=>$i)),
...
@@ -395,11 +395,13 @@ function googleanalytics_admin_settings_form($form_state) {
...
@@ -395,11 +395,13 @@ function googleanalytics_admin_settings_form($form_state) {
'#type'=>'item',
'#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'=>'http://www.google.com/analytics/terms/gb.html')),
form_set_error('googleanalytics_cross_domains',t('A list of top-level domains is required if <em>Multiple top-level domains</em> has been selected.'));
form_set_error('googleanalytics_cross_domains',t('A list of top-level domains is required if <em>Multiple top-level domains</em> has been selected.'));
}
}
// Clear the domain list if cross domains are disabled.
@@ -748,8 +767,14 @@ function _googleanalytics_validate_create_field_name($name) {
...
@@ -748,8 +767,14 @@ function _googleanalytics_validate_create_field_name($name) {
'legacyCookieDomain',
'legacyCookieDomain',
);
);
if($name=='name'){
returnt('Create only field name %name is a disallowed field name. Changing the <em>Tracker Name</em> is currently not supported.',array('%name'=>$name));
}
if($name=='allowLinker'){
returnt('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(!in_array($name,$create_only_fields)){
if(!in_array($name,$create_only_fields)){
returnt('Field name %name is an unknown field name. 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'));
returnt('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'));
}
}
}
}
...
@@ -763,11 +788,11 @@ function _googleanalytics_validate_create_field_name($name) {
...
@@ -763,11 +788,11 @@ function _googleanalytics_validate_create_field_name($name) {
* The error message if the specified value is invalid, NULL otherwise.
* The error message if the specified value is invalid, NULL otherwise.
'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'))),
'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,
'severity'=>REQUIREMENT_WARNING,
'value'=>$t('Debugging enabled'),
'value'=>$t('Debugging enabled'),
);
);
}
}
}
return$requirements;
return$requirements;
...
@@ -445,7 +443,7 @@ function googleanalytics_update_7200() {
...
@@ -445,7 +443,7 @@ function googleanalytics_update_7200() {
// ga.js code will cause the tracker to break. Remove custom code snippets.
// ga.js code will cause the tracker to break. Remove custom code snippets.
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');
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');
...
@@ -453,7 +451,7 @@ function googleanalytics_update_7200() {
...
@@ -453,7 +451,7 @@ function googleanalytics_update_7200() {
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');
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');
...
@@ -481,3 +479,59 @@ function googleanalytics_update_7202() {
...
@@ -481,3 +479,59 @@ function googleanalytics_update_7202() {
@@ -30,10 +30,10 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
...
@@ -30,10 +30,10 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
}
}
functiontestGoogleAnalyticsConfiguration(){
functiontestGoogleAnalyticsConfiguration(){
// Check if Configure link is available on 'Extend' page.
// Check if Configure link is available on 'Modules' page.
// Requires 'administer modules' permission.
// Requires 'administer modules' permission.
$this->drupalGet('admin/modules');
$this->drupalGet('admin/modules');
$this->assertRaw('admin/config/system/googleanalytics','[testGoogleAnalyticsConfiguration]: Configure link from Extend page to Google Analytics Settings page exists.');
$this->assertRaw('admin/config/system/googleanalytics','[testGoogleAnalyticsConfiguration]: Configure link from Modules page to Google Analytics Settings page exists.');
// Check if Configure link is available on 'Status Reports' page. NOTE: Link is only shown without UA code configured.
// Check if Configure link is available on 'Status Reports' page. NOTE: Link is only shown without UA code configured.
// Requires 'administer site configuration' permission.
// Requires 'administer site configuration' permission.
...
@@ -61,7 +61,7 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
...
@@ -61,7 +61,7 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
// Show tracking on "every page except the listed pages".
// Show tracking on "every page except the listed pages".
$this->assertRaw('ga("create", "'.$ua_code.'", {"allowLinker":true','[testGoogleAnalyticsTrackingCode]: "allowLinker" has been found. Cross domain tracking is active.');
$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("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('ga("linker:autoLink", ["www.example.com","www.example.net"]);','[testGoogleAnalyticsTrackingCode]: "linker:autoLink" has been found. Cross domain tracking is active.');
$this->assertRaw('"trackCrossDomains":["www.example.com","www.example.net"]','[testGoogleAnalyticsTrackingCode]: Cross domain tracking with www.example.com and www.example.net is active.');
$this->assertRaw('"trackCrossDomains":["www.example.com","www.example.net"]','[testGoogleAnalyticsTrackingCode]: Cross domain tracking with www.example.com and www.example.net is active.');
...
@@ -255,11 +255,11 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
...
@@ -255,11 +255,11 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
$this->assertRaw('ga("create", "'.$ua_code.'", {"cookieDomain":"foo.example.com","cookieName":"myNewName","cookieExpires":20000,"allowAnchor":true,"sampleRate":4.3});','[testGoogleAnalyticsTrackingCode]: Create only fields have been found.');
$this->assertRaw('ga("create", "'.$ua_code.'", {"cookieDomain":"foo.example.com","cookieName":"myNewName","cookieExpires":20000,"allowAnchor":true,"sampleRate":4.3});','[testGoogleAnalyticsTrackingCode]: Create only fields have been found.');
$this->assertRaw('ga("set", "forceSSL", true);','[testGoogleAnalyticsTrackingCode]: Before codesnippet will force http pages to also send all beacons using https.');
$this->assertRaw('ga("set", "forceSSL", true);','[testGoogleAnalyticsTrackingCode]: Before codesnippet will force http pages to also send all beacons using https.');
$this->assertRaw('ga("create", "UA-123456-3", {name: "newTracker"});','[testGoogleAnalyticsTrackingCode]: After codesnippet with "newTracker" tracker has been found.');
$this->assertRaw('ga("create", "UA-123456-3", {"name": "newTracker"});','[testGoogleAnalyticsTrackingCode]: After codesnippet with "newTracker" tracker has been found.');
}
}
}
}
...
@@ -292,33 +292,31 @@ class GoogleAnalyticsCustomDimensionsAndMetricsTest extends DrupalWebTestCase {
...
@@ -292,33 +292,31 @@ class GoogleAnalyticsCustomDimensionsAndMetricsTest extends DrupalWebTestCase {
$this->assertRaw('ga("set", '.drupal_json_encode('dimension1').', '.drupal_json_encode("Value: $site_slogan").');','[testGoogleAnalyticsCustomDimensionsAndMetrics]: Tokens have been replaced in dimension value.');
$this->assertRaw('ga("set", '.drupal_json_encode('dimension1').', '.drupal_json_encode("Value: $site_slogan").');','[testGoogleAnalyticsCustomDimensionsAndMetrics]: Tokens have been replaced in dimension value.');
$this->assertRaw('ga("set", '.drupal_json_encode('dimension2').', '.drupal_json_encode($googleanalytics_custom_dimension['indexes']['2']['value']).');','[testGoogleAnalyticsCustomDimensionsAndMetrics]: Random value is shown.');
$this->assertRaw('ga("set", '.drupal_json_encode('dimension2').', '.drupal_json_encode($googleanalytics_custom_dimension['2']['value']).');','[testGoogleAnalyticsCustomDimensionsAndMetrics]: Random value is shown.');
$this->assertNoRaw('ga("set", '.drupal_json_encode('dimension3').', '.drupal_json_encode('').');','[testGoogleAnalyticsCustomDimensionsAndMetrics]: Empty value is not shown.');
$this->assertNoRaw('ga("set", '.drupal_json_encode('dimension3').', '.drupal_json_encode('').');','[testGoogleAnalyticsCustomDimensionsAndMetrics]: Empty value is not shown.');
$this->assertRaw('ga("set", '.drupal_json_encode('dimension4').', '.drupal_json_encode('0').');','[testGoogleAnalyticsCustomDimensionsAndMetrics]: Value 0 is shown.');
}
}
functiontestGoogleAnalyticsCustomMetrics(){
functiontestGoogleAnalyticsCustomMetrics(){
...
@@ -357,65 +359,67 @@ class GoogleAnalyticsCustomDimensionsAndMetricsTest extends DrupalWebTestCase {
...
@@ -357,65 +359,67 @@ class GoogleAnalyticsCustomDimensionsAndMetricsTest extends DrupalWebTestCase {
$this->assertRaw('ga("set", '.drupal_json_encode('metric1').', ','[testGoogleAnalyticsCustomDimensionsAndMetrics]: Tokens have been replaced in metric value.');
$this->assertRaw('ga("set", '.drupal_json_encode('metric1').', ','[testGoogleAnalyticsCustomDimensionsAndMetrics]: Tokens have been replaced in metric value.');
$this->assertRaw('ga("set", '.drupal_json_encode('metric2').', '.drupal_json_encode($googleanalytics_custom_metric['indexes']['2']['value']).');','[testGoogleAnalyticsCustomDimensionsAndMetrics]: Random value is shown.');
$this->assertRaw('ga("set", '.drupal_json_encode('metric2').', '.drupal_json_encode($googleanalytics_custom_metric['2']['value']).');','[testGoogleAnalyticsCustomDimensionsAndMetrics]: Random value is shown.');
$this->assertNoRaw('ga("set", '.drupal_json_encode('metric3').', '.drupal_json_encode('').');','[testGoogleAnalyticsCustomDimensionsAndMetrics]: Empty value is not shown.');
$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.');
}
}
}
}
...
@@ -572,6 +576,8 @@ class GoogleAnalyticsSearchTest extends DrupalWebTestCase {
...
@@ -572,6 +576,8 @@ class GoogleAnalyticsSearchTest extends DrupalWebTestCase {
'access administration pages',
'access administration pages',
'administer google analytics',
'administer google analytics',
'search content',
'search content',
'create page content',
'edit own page content',
);
);
// User to set up google_analytics.
// User to set up google_analytics.
...
@@ -590,16 +596,44 @@ class GoogleAnalyticsSearchTest extends DrupalWebTestCase {
...
@@ -590,16 +596,44 @@ class GoogleAnalyticsSearchTest extends DrupalWebTestCase {
$this->drupalGet('search/node');
$this->drupalGet('search/node');
$this->assertNoRaw('ga("set", "page",','[testGoogleAnalyticsSearch]: Custom url not set.');
$this->assertNoRaw('ga("set", "page",','[testGoogleAnalyticsSearch]: Custom url not set.');
// Enable site search support.
variable_set('googleanalytics_site_search',1);
// Search for random string.
// Search for random string.
$search=array();
$search['keys']=$this->randomName(8);
// Create a node to search for.
$langcode=LANGUAGE_NONE;
$edit=array();
$edit=array();
$edit['keys']=$this->randomName(32);
$edit['title']='This is a test title';
$edit["body[$langcode][0][value]"]='This test content contains '.$search['keys'].' string.';
@@ -48,7 +48,7 @@ Drupal.googleanalytics.test.assertFalse = function (value1, message) {
...
@@ -48,7 +48,7 @@ Drupal.googleanalytics.test.assertFalse = function (value1, message) {
else{
else{
console.error(message);
console.error(message);
}
}
}
};
// Run after the documented is ready or Drupal.settings is undefined.
// Run after the documented is ready or Drupal.settings is undefined.
$(document).ready(function(){
$(document).ready(function(){
...
@@ -86,8 +86,8 @@ $(document).ready(function() {
...
@@ -86,8 +86,8 @@ $(document).ready(function() {
console.groupEnd();
console.groupEnd();
console.group("Test 'getPageUrl':");
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,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+'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(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.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.");
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.");