Google Analyticator - Version 5.2

Version Description

  • Adds support for deauthorizing with Google Analytics.
  • Increases checks on the memory limit and now prevents the memory intensive functionality from running if there is insufficient memory.
  • Adds authentication compatibility modes for users having issues with cURL and PHP Streams.
  • Improves detection of Google Accounts that are not linked to Analytics accounts.
  • Improves detection of accounts without stats.
  • Cleans up the authentication URL, preventing the malformed URL error that Google would sometimes display.
  • Removes hosted Google accounts from Google's authentication page.
  • Adds an error message to the settings page if Google authentication fails.
Download this release

Release Info

Developer cavemonkey50
Plugin Icon 128x128 Google Analyticator
Version 5.2
Comparing to
See all releases

Code changes from version 5.1 to 5.2

class.analytics.stats.php CHANGED
@@ -26,17 +26,30 @@ class GoogleAnalyticsStats
26
  * @param token - a one-time use token to be exchanged for a real token
27
  **/
28
  function GoogleAnalyticsStats($token = false)
29
- {
30
- # Increase the memory limit to prevent blank page errors
31
- ini_set('memory_limit', '64M');
32
-
33
  # If we need to request a permanent token
34
  if ( $token ) {
35
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  $this->token = $token;
37
 
38
  # Request authentication with Google
39
- $response = $this->http('https://www.google.com/accounts/AuthSubSessionToken', $post);
40
 
41
  # Get the authentication token
42
  $this->token = substr(strstr($response, "Token="), 6);
@@ -88,6 +101,14 @@ class GoogleAnalyticsStats
88
  # Disable the fopen transport since it doesn't work with the Google API
89
  add_filter('use_fopen_transport', create_function('$a', 'return false;'));
90
 
 
 
 
 
 
 
 
 
91
  # Make the connection
92
  if ( $post )
93
  $response = wp_remote_post($url, $args);
26
  * @param token - a one-time use token to be exchanged for a real token
27
  **/
28
  function GoogleAnalyticsStats($token = false)
29
+ {
 
 
 
30
  # If we need to request a permanent token
31
  if ( $token ) {
32
 
33
+ # Check if we're deauthorizing an account
34
+ if ( $token == 'deauth' ) {
35
+
36
+ # Get the current token
37
+ $this->token = get_option('ga_google_token');
38
+
39
+ # Revoke the current token
40
+ $response = $this->http('https://www.google.com/accounts/AuthSubRevokeToken');
41
+
42
+ # Remove the current token
43
+ update_option('ga_google_token', '');
44
+
45
+ return '';
46
+
47
+ }
48
+
49
  $this->token = $token;
50
 
51
  # Request authentication with Google
52
+ $response = $this->http('https://www.google.com/accounts/AuthSubSessionToken');
53
 
54
  # Get the authentication token
55
  $this->token = substr(strstr($response, "Token="), 6);
101
  # Disable the fopen transport since it doesn't work with the Google API
102
  add_filter('use_fopen_transport', create_function('$a', 'return false;'));
103
 
104
+ # Check compatibility mode settings
105
+ if ( get_option('ga_compatibility') == 'level1' ) {
106
+ add_filter('use_curl_transport', create_function('$a', 'return false;'));
107
+ } elseif ( get_option('ga_compatibility') == 'level2' ) {
108
+ add_filter('use_curl_transport', create_function('$a', 'return false;'));
109
+ add_filter('use_streams_transport', create_function('$a', 'return false;'));
110
+ }
111
+
112
  # Make the connection
113
  if ( $post )
114
  $response = wp_remote_post($url, $args);
google-analyticator.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
  /*
3
  * Plugin Name: Google Analyticator
4
- * Version: 5.1
5
  * Plugin URI: http://plugins.spiralwebconsulting.com/analyticator.html
6
  * Description: Adds the necessary JavaScript code to enable <a href="http://www.google.com/analytics/">Google's Analytics</a>. After enabling this plugin visit <a href="options-general.php?page=google-analyticator.php">the settings page</a> and enter your Google Analytics' UID and enable logging.
7
  * Author: Spiral Web Consulting
@@ -9,7 +9,7 @@
9
  * Text Domain: google-analyticator
10
  */
11
 
12
- define('GOOGLE_ANALYTICATOR_VERSION', '5.1');
13
 
14
  // Constants for enabled/disabled state
15
  define("ga_enabled", "enabled", true);
@@ -68,19 +68,40 @@ add_option(key_ga_footer, ga_footer_default, 'If Google Analyticator is outputti
68
  add_option(key_ga_specify_http, ga_specify_http_default, 'Automatically detect the http/https settings');
69
  add_option(key_ga_widgets, ga_widgets_default, 'If the widgets are enabled or disabled');
70
  add_option('ga_google_token', '', 'The token used to authenticate with Google');
 
71
 
72
  # Check if we have a version of WordPress greater than 2.8
73
  if ( function_exists('register_widget') ) {
74
 
 
 
 
 
 
 
 
 
 
75
  # Check if widgets are enabled
76
  if ( get_option(key_ga_widgets) == 'enabled' ) {
 
 
 
 
 
 
 
 
 
 
 
 
77
 
78
- # Include Google Analytics Stats widget
79
- require_once('google-analytics-stats-widget.php');
80
-
81
- # Include the Google Analytics Summary widget
82
- require_once('google-analytics-summary-widget.php');
83
- $google_analytics_summary = new GoogleAnalyticsSummary();
84
 
85
  }
86
 
@@ -242,6 +263,12 @@ function ga_options_page() {
242
  if (($ga_widgets != ga_enabled) && ($ga_widgets != ga_disabled))
243
  $ga_widgets = ga_widgets_default;
244
  update_option(key_ga_widgets, $ga_widgets);
 
 
 
 
 
 
245
 
246
  // Give an updated message
247
  echo "<div class='updated fade'><p><strong>" . __('Google Analyticator settings saved.', 'google-analyticator') . "</strong></p></div>";
@@ -305,8 +332,10 @@ function ga_options_page() {
305
  </td>
306
  </tr>
307
  <?php
308
- # Check if we have a version of WordPress greater than 2.8
309
- if ( function_exists('register_widget') ) {
 
 
310
  ?>
311
  <?php
312
  # Get the list of accounts if available
@@ -318,9 +347,17 @@ function ga_options_page() {
318
  </th>
319
  <td>
320
  <?php if ( trim(get_option('ga_google_token')) == '' ) { ?>
321
- <p style="margin-top: 7px;"><a href="https://www.google.com/accounts/AuthSubRequest?next=<?php echo urlencode(admin_url('/options-general.php?page=google-analyticator.php')); ?>&amp;scope=https://www.google.com/analytics/feeds/&amp;secure=0&amp;session=1"><?php _e('Click here to login to Google, thus authenticating Google Analyticator with your Analytics account.', 'google-analyticator'); ?></a></p>
 
 
 
 
 
 
 
 
322
  <?php } else { ?>
323
- <p style="margin-top: 7px;"><?php _e('Currently authenticated with Google.', 'google-analyticator'); ?> <a href="https://www.google.com/accounts/AuthSubRequest?next=<?php echo urlencode(admin_url('/options-general.php?page=google-analyticator.php')); ?>&amp;scope=https://www.google.com/analytics/feeds/&amp;secure=0&amp;session=1"><?php _e('Click here to authenticate again.', 'google-analyticator'); ?></a></p>
324
  <?php } ?>
325
  <p style="margin: 5px 10px;" class="setting-description"><?php _e('Clicking the above link will authenticate Google Analyticator with Google. Authentication with Google is needed for use with the stats widget. In addition, authenticating will enable you to select your Analytics account through a drop-down instead of searching for your UID. If you are not going to use the stat widget, <strong>authenticating with Google is optional</strong>.', 'google-analyticator'); ?></p>
326
  </td>
@@ -551,7 +588,7 @@ function ga_options_page() {
551
  <?php
552
  echo "<input type='text' size='50' ";
553
  echo "name='".key_ga_downloads_prefix."' ";
554
- echo "id='".key_ga_download_sprefix."' ";
555
  echo "value='".stripslashes(get_option(key_ga_downloads_prefix))."' />\n";
556
  ?>
557
  <p style="margin: 5px 10px;" class="setting-description"><?php _e('Enter a name for the section tracked download links will appear under. This option has no effect if event tracking is enabled.', 'google-analyticator'); ?></em></p>
@@ -654,6 +691,34 @@ function ga_options_page() {
654
  <p style="margin: 5px 10px;" class="setting-description"><?php _e('Disabling this option will completely remove the Dashboard Summary widget and the theme Stats widget. Use this option if you would prefer to not see the widgets.', 'google-analyticator'); ?></p>
655
  </td>
656
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
657
  <?php } ?>
658
  </table>
659
  <p class="submit">
@@ -698,6 +763,30 @@ function ga_get_analytics_accounts()
698
  return false;
699
  }
700
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
701
  // Add the script
702
  $ga_in_footer = false;
703
  if (get_option(key_ga_footer) == ga_enabled) {
1
  <?php
2
  /*
3
  * Plugin Name: Google Analyticator
4
+ * Version: 5.2
5
  * Plugin URI: http://plugins.spiralwebconsulting.com/analyticator.html
6
  * Description: Adds the necessary JavaScript code to enable <a href="http://www.google.com/analytics/">Google's Analytics</a>. After enabling this plugin visit <a href="options-general.php?page=google-analyticator.php">the settings page</a> and enter your Google Analytics' UID and enable logging.
7
  * Author: Spiral Web Consulting
9
  * Text Domain: google-analyticator
10
  */
11
 
12
+ define('GOOGLE_ANALYTICATOR_VERSION', '5.2');
13
 
14
  // Constants for enabled/disabled state
15
  define("ga_enabled", "enabled", true);
68
  add_option(key_ga_specify_http, ga_specify_http_default, 'Automatically detect the http/https settings');
69
  add_option(key_ga_widgets, ga_widgets_default, 'If the widgets are enabled or disabled');
70
  add_option('ga_google_token', '', 'The token used to authenticate with Google');
71
+ add_option('ga_compatibility', 'off', 'Transport compatibility options');
72
 
73
  # Check if we have a version of WordPress greater than 2.8
74
  if ( function_exists('register_widget') ) {
75
 
76
+ # Get the current memory limit
77
+ $current_mem_limit = substr(ini_get('memory_limit'), 0, -1);
78
+
79
+ # Check if this limit is less than 96M, if so, increase it
80
+ if ( $current_mem_limit < 96 || $current_mem_limit == '' ) {
81
+ if ( function_exists('memory_get_usage') )
82
+ @ini_set('memory_limit', '96M');
83
+ }
84
+
85
  # Check if widgets are enabled
86
  if ( get_option(key_ga_widgets) == 'enabled' ) {
87
+
88
+ # Get the current memory limit, after the update
89
+ $current_mem_limit = substr(ini_get('memory_limit'), 0, -1);
90
+
91
+ # Check again if the memory limit is fine
92
+ # If the memory limit did not increase, disable the widgets
93
+ if ( $current_mem_limit < 96 && $current_mem_limit != '' ) {
94
+ update_option(key_ga_widgets, 'disabled');
95
+ } else {
96
+
97
+ # Include Google Analytics Stats widget
98
+ require_once('google-analytics-stats-widget.php');
99
 
100
+ # Include the Google Analytics Summary widget
101
+ require_once('google-analytics-summary-widget.php');
102
+ $google_analytics_summary = new GoogleAnalyticsSummary();
103
+
104
+ }
 
105
 
106
  }
107
 
263
  if (($ga_widgets != ga_enabled) && ($ga_widgets != ga_disabled))
264
  $ga_widgets = ga_widgets_default;
265
  update_option(key_ga_widgets, $ga_widgets);
266
+
267
+ // Update the compatibility options
268
+ $ga_compatibility = $_POST['ga_compatibility'];
269
+ if ( $ga_compatibility == '' )
270
+ $ga_compatibility = 'off';
271
+ update_option('ga_compatibility', $ga_compatibility);
272
 
273
  // Give an updated message
274
  echo "<div class='updated fade'><p><strong>" . __('Google Analyticator settings saved.', 'google-analyticator') . "</strong></p></div>";
332
  </td>
333
  </tr>
334
  <?php
335
+ # Get the current memory limit, after the update
336
+ $current_mem_limit = substr(ini_get('memory_limit'), 0, -1);
337
+ # Check if we have a version of WordPress greater than 2.8, and check if we have the memory to use the api
338
+ if ( function_exists('register_widget') && ( $current_mem_limit >= 96 || $current_mem_limit == '' ) ) {
339
  ?>
340
  <?php
341
  # Get the list of accounts if available
347
  </th>
348
  <td>
349
  <?php if ( trim(get_option('ga_google_token')) == '' ) { ?>
350
+ <p style="margin-top: 7px;"><a href="https://www.google.com/accounts/AuthSubRequest?<?php echo http_build_query(array( 'next' => admin_url('/options-general.php?page=google-analyticator.php'),
351
+ 'scope' => 'https://www.google.com/analytics/feeds/',
352
+ 'secure' => 0,
353
+ 'session' => 1,
354
+ 'hd' => 'default'
355
+ )); ?>"><?php _e('Click here to login to Google, thus authenticating Google Analyticator with your Analytics account.', 'google-analyticator'); ?></a></p>
356
+ <?php if ( isset($_GET['token']) && $_GET['token'] != 'deauth' && $ga_accounts == false ) { ?>
357
+ <p style="color: red;"><?php _e('Failed to authenticate with Google. Try using the compatibility options at the bottom of this page. If you are still unable to authenticate, contact your host, informing them you are experiencing errors with outbound SSL connections.', 'google-analyticator'); ?></p>
358
+ <?php } ?>
359
  <?php } else { ?>
360
+ <p style="margin-top: 7px;"><?php _e('Currently authenticated with Google.', 'google-analyticator'); ?> <a href="<?php echo admin_url('/options-general.php?page=google-analyticator.php&token=deauth'); ?>"><?php _e('Deauthorize Google Analyticator.', 'google-analyticator'); ?></a></p>
361
  <?php } ?>
362
  <p style="margin: 5px 10px;" class="setting-description"><?php _e('Clicking the above link will authenticate Google Analyticator with Google. Authentication with Google is needed for use with the stats widget. In addition, authenticating will enable you to select your Analytics account through a drop-down instead of searching for your UID. If you are not going to use the stat widget, <strong>authenticating with Google is optional</strong>.', 'google-analyticator'); ?></p>
363
  </td>
588
  <?php
589
  echo "<input type='text' size='50' ";
590
  echo "name='".key_ga_downloads_prefix."' ";
591
+ echo "id='".key_ga_downloads_prefix."' ";
592
  echo "value='".stripslashes(get_option(key_ga_downloads_prefix))."' />\n";
593
  ?>
594
  <p style="margin: 5px 10px;" class="setting-description"><?php _e('Enter a name for the section tracked download links will appear under. This option has no effect if event tracking is enabled.', 'google-analyticator'); ?></em></p>
691
  <p style="margin: 5px 10px;" class="setting-description"><?php _e('Disabling this option will completely remove the Dashboard Summary widget and the theme Stats widget. Use this option if you would prefer to not see the widgets.', 'google-analyticator'); ?></p>
692
  </td>
693
  </tr>
694
+ <tr>
695
+ <th width="30%" valign="top" style="padding-top: 10px;">
696
+ <label for="ga_compatibility"><?php _e('Authentication compatibility', 'google-analyticator'); ?>:</label>
697
+ </th>
698
+ <td>
699
+ <?php
700
+ echo "<select name='ga_compatibility' id='ga_compatibility'>\n";
701
+
702
+ echo "<option value='off'";
703
+ if(get_option('ga_compatibility') == 'off')
704
+ echo " selected='selected'";
705
+ echo ">" . __('Off', 'google-analyticator') . "</option>\n";
706
+
707
+ echo "<option value='level1'";
708
+ if(get_option('ga_compatibility') == 'level1')
709
+ echo " selected='selected'";
710
+ echo ">" . __('Disable cURL', 'google-analyticator') . "</option>\n";
711
+
712
+ echo "<option value='level2'";
713
+ if(get_option('ga_compatibility') == 'level2')
714
+ echo " selected='selected'";
715
+ echo ">" . __('Disable cURL and PHP Streams', 'google-analyticator') . "</option>\n";
716
+
717
+ echo "</select>\n";
718
+ ?>
719
+ <p style="margin: 5px 10px;" class="setting-description"><?php _e('If you\'re having trouble authenticating with Google for use with the stats widgets, try setting these compatibility modes. Try disabling cURL first and re-authenticate. If that fails, try disabling cURL and PHP Streams.', 'google-analyticator'); ?></p>
720
+ </td>
721
+ </tr>
722
  <?php } ?>
723
  </table>
724
  <p class="submit">
763
  return false;
764
  }
765
 
766
+ /**
767
+ * Add http_build_query if it doesn't exist already
768
+ **/
769
+ if ( !function_exists('http_build_query') ) {
770
+ function http_build_query($params, $key = null)
771
+ {
772
+ $ret = array();
773
+
774
+ foreach( (array) $params as $name => $val ) {
775
+ $name = urlencode($name);
776
+
777
+ if ( $key !== null )
778
+ $name = $key . "[" . $name . "]";
779
+
780
+ if ( is_array($val) || is_object($val) )
781
+ $ret[] = http_build_query($val, $name);
782
+ elseif ($val !== null)
783
+ $ret[] = $name . "=" . urlencode($val);
784
+ }
785
+
786
+ return implode("&", $ret);
787
+ }
788
+ }
789
+
790
  // Add the script
791
  $ga_in_footer = false;
792
  if (get_option(key_ga_footer) == ga_enabled) {
google-analytics-summary-widget.php CHANGED
@@ -29,7 +29,7 @@ class GoogleAnalyticsSummary
29
  $this->id = $this->getAnalyticsAccount();
30
  $this->api->setAccount($this->id);
31
 
32
- wp_add_dashboard_widget('google-analytics-summary', 'Google Analytics Summary', array($this, 'widget'));
33
  }
34
 
35
  /**
@@ -147,6 +147,10 @@ class GoogleAnalyticsSummary
147
  # Get a list of accounts
148
  $accounts = $this->api->getAnalyticsAccounts();
149
 
 
 
 
 
150
  # Check if we have a list of accounts
151
  if ( count($accounts) <= 0 )
152
  return false;
@@ -200,17 +204,27 @@ class GoogleAnalyticsSummary
200
  # Create a list of the data points for graphing
201
  $data = '';
202
  $max = 0;
203
- foreach ( $stats AS $stat ) {
204
- $data .= $stat['ga:visits'] . ',';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
 
206
- # Update the max value if greater
207
- if ( $max < $stat['ga:visits'] )
208
- $max = $stat['ga:visits'];
209
  }
210
 
211
- # Shorten the string to remove the last comma
212
- $data = substr($data, 0, -1);
213
-
214
  # Output the graph
215
  echo '<script type="text/javascript">var ga_visits = [' . $data . '];</script>';
216
  echo '<span class="ga_visits" title="' . sprintf(__('The most visits on a single day was %d. Yesterday there were %d visits.', 'google-analyticator'), $max, $stat['ga:visits']) . '"></span>';
@@ -326,8 +340,8 @@ class GoogleAnalyticsSummary
326
  }
327
 
328
  # Check the size of the stats array
329
- if ( count($stats) <= 0 ) {
330
- echo '<p>' . __('There is no data for view.') . '</p>';
331
  } else {
332
  # Build the top pages list
333
  echo '<ol>';
@@ -377,8 +391,8 @@ class GoogleAnalyticsSummary
377
  }
378
 
379
  # Check the size of the stats array
380
- if ( count($stats) <= 0 ) {
381
- echo '<p>' . __('There is no data for view.') . '</p>';
382
  } else {
383
  # Build the top pages list
384
  echo '<ol>';
@@ -428,8 +442,8 @@ class GoogleAnalyticsSummary
428
  }
429
 
430
  # Check the size of the stats array
431
- if ( count($stats) <= 0 ) {
432
- echo '<p>' . __('There is no data for view.') . '</p>';
433
  } else {
434
  # Build the top pages list
435
  echo '<ol>';
29
  $this->id = $this->getAnalyticsAccount();
30
  $this->api->setAccount($this->id);
31
 
32
+ wp_add_dashboard_widget('google-analytics-summary', __('Google Analytics Summary', 'google-analyticator'), array($this, 'widget'));
33
  }
34
 
35
  /**
147
  # Get a list of accounts
148
  $accounts = $this->api->getAnalyticsAccounts();
149
 
150
+ # Check if we actually have accounts
151
+ if ( !is_array($accounts) )
152
+ return false;
153
+
154
  # Check if we have a list of accounts
155
  if ( count($accounts) <= 0 )
156
  return false;
204
  # Create a list of the data points for graphing
205
  $data = '';
206
  $max = 0;
207
+
208
+ # Check the size of the stats array
209
+ if ( count($stats) <= 0 || !is_array($stats) ) {
210
+ $data = '0,0';
211
+ } else {
212
+ foreach ( $stats AS $stat ) {
213
+ # Verify the number is numeric
214
+ if ( is_numeric($stat['ga:visits']) )
215
+ $data .= $stat['ga:visits'] . ',';
216
+ else
217
+ $data .= '0,';
218
+
219
+ # Update the max value if greater
220
+ if ( $max < $stat['ga:visits'] )
221
+ $max = $stat['ga:visits'];
222
+ }
223
 
224
+ # Shorten the string to remove the last comma
225
+ $data = substr($data, 0, -1);
 
226
  }
227
 
 
 
 
228
  # Output the graph
229
  echo '<script type="text/javascript">var ga_visits = [' . $data . '];</script>';
230
  echo '<span class="ga_visits" title="' . sprintf(__('The most visits on a single day was %d. Yesterday there were %d visits.', 'google-analyticator'), $max, $stat['ga:visits']) . '"></span>';
340
  }
341
 
342
  # Check the size of the stats array
343
+ if ( count($stats) <= 0 || !is_array($stats) ) {
344
+ echo '<p>' . __('There is no data for view.', 'google-analyticator') . '</p>';
345
  } else {
346
  # Build the top pages list
347
  echo '<ol>';
391
  }
392
 
393
  # Check the size of the stats array
394
+ if ( count($stats) <= 0 || !is_array($stats) ) {
395
+ echo '<p>' . __('There is no data for view.', 'google-analyticator') . '</p>';
396
  } else {
397
  # Build the top pages list
398
  echo '<ol>';
442
  }
443
 
444
  # Check the size of the stats array
445
+ if ( count($stats) <= 0 || !is_array($stats) ) {
446
+ echo '<p>' . __('There is no data for view.', 'google-analyticator') . '</p>';
447
  } else {
448
  # Build the top pages list
449
  echo '<ol>';
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: cavemonkey50, jesse_altman, spiralwebconsulting
3
  Donate link: http://plugins.spiralwebconsulting.com/analyticator.html#donate
4
  Tags: stats, statistics, google, analytics, google analytics, tracking, widget
5
  Requires at least: 2.7
6
- Tested up to: 2.8.1
7
- Stable tag: 5.1
8
 
9
  Adds the necessary JavaScript code to enable Google Analytics. Includes widgets for Analytics data display.
10
 
@@ -52,6 +52,16 @@ Please visit [Spiral Web Consulting's forum](http://plugins.spiralwebconsulting.
52
 
53
  == Changelog ==
54
 
 
 
 
 
 
 
 
 
 
 
55
  = 5.1 =
56
  * Fixes the broken/frozen error on the Dashboard introduced in Google Analyticator 5.0.
57
  * Fixes an Internal Server Error received on the settings page under IIS servers.
3
  Donate link: http://plugins.spiralwebconsulting.com/analyticator.html#donate
4
  Tags: stats, statistics, google, analytics, google analytics, tracking, widget
5
  Requires at least: 2.7
6
+ Tested up to: 2.8.2
7
+ Stable tag: 5.2
8
 
9
  Adds the necessary JavaScript code to enable Google Analytics. Includes widgets for Analytics data display.
10
 
52
 
53
  == Changelog ==
54
 
55
+ = 5.2 =
56
+ * Adds support for deauthorizing with Google Analytics.
57
+ * Increases checks on the memory limit and now prevents the memory intensive functionality from running if there is insufficient memory.
58
+ * Adds authentication compatibility modes for users having issues with cURL and PHP Streams.
59
+ * Improves detection of Google Accounts that are not linked to Analytics accounts.
60
+ * Improves detection of accounts without stats.
61
+ * Cleans up the authentication URL, preventing the malformed URL error that Google would sometimes display.
62
+ * Removes hosted Google accounts from Google's authentication page.
63
+ * Adds an error message to the settings page if Google authentication fails.
64
+
65
  = 5.1 =
66
  * Fixes the broken/frozen error on the Dashboard introduced in Google Analyticator 5.0.
67
  * Fixes an Internal Server Error received on the settings page under IIS servers.