Google Analyticator - Version 6.0

Version Description

  • Switches current tracking script (ga.js) to the new awesome async tracking script. In laymen's terms: updates to the latest tracking code, the tracking script will load faster, and tracking will be more reliable. If you use custom tracking code, be sure to migrate that code to the new async tracking methods.
  • Removes settings made obsolete due to the new async tracking (footer tracking and http/https).
  • Fixes the (not set) pages in the Top Pages section of the dashboard widget. Pages containing the title (not set) will be combined with the correct page and corresponding title. Note that I am still trying to get this bug fixed in the Google Analytics API; this is just a hold over until the bug is fixed.
  • Adds a link to Google Analytics on the dashboard widget for quick access to view full stat reports.
  • Fixes a Javascript error that prevented the dashboard widget from collapsing.
  • Corrects a uid undefined error message that appeared if error reporting was set too high.
  • Updates the included jQuery sparklines plugin to the latest version, 1.4.3.
  • Adds an experimental function to retrieve page visitors stats for theme developers. This function is not final and only provided for advanced users who know what they're doing. Future versions will improve on the code already in place. Find the get_analytics_visits_by_page in google-analyticator.php to learn how to use. Use at your own risk.
  • Fixes several security flaws identified during a recent security audit of Google Analyticator.
  • Removes references to Spiral Web Consulting. Google Analyticator is now being developed exclusively by Ronald Heft.
Download this release

Release Info

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

Code changes from version 5.3.2 to 6.0

external-tracking.js CHANGED
@@ -23,9 +23,9 @@ jQuery(document).ready(function() {
23
  // Add the tracking code
24
  a.click(function() {
25
  if ( analyticsEventTracking == 'enabled' ) {
26
- pageTracker._trackEvent("Downloads", extension.toUpperCase(), href);
27
  } else
28
- pageTracker._trackPageview(analyticsDownloadsPrefix + url);
29
  });
30
  }
31
 
@@ -34,9 +34,9 @@ jQuery(document).ready(function() {
34
  // Add the tracking code
35
  a.click(function() {
36
  if ( analyticsEventTracking == 'enabled' ) {
37
- pageTracker._trackEvent("Outbound Traffic", href.match(/:\/\/(.[^/]+)/)[1], href);
38
  } else
39
- pageTracker._trackPageview(analyticsOutboundPrefix + url);
40
  });
41
  }
42
  });
23
  // Add the tracking code
24
  a.click(function() {
25
  if ( analyticsEventTracking == 'enabled' ) {
26
+ _gaq.push(['_trackEvent', 'Downloads', extension.toUpperCase(), href]);
27
  } else
28
+ _gaq.push(['_trackPageview', analyticsDownloadsPrefix + url]);
29
  });
30
  }
31
 
34
  // Add the tracking code
35
  a.click(function() {
36
  if ( analyticsEventTracking == 'enabled' ) {
37
+ _gaq.push(['_trackEvent', 'Outbound Traffic', href.match(/:\/\/(.[^/]+)/)[1], href]);
38
  } else
39
+ _gaq.push(['_trackPageview', analyticsOutboundPrefix + url]);
40
  });
41
  }
42
  });
external-tracking.min.js CHANGED
@@ -1,5 +1,5 @@
1
  jQuery(document).ready(function(){jQuery('a').each(function(){var a=jQuery(this);var href=a.attr('href');if(href==undefined)
2
- return;var url=href.replace('http://','').replace('https://','');var hrefArray=href.split('.').reverse();var extension=hrefArray[0].toLowerCase();var hrefArray=href.split('/').reverse();var domain=hrefArray[2];var downloadTracked=false;if(jQuery.inArray(extension,analyticsFileTypes)!=-1){downloadTracked=true;a.click(function(){if(analyticsEventTracking=='enabled'){pageTracker._trackEvent("Downloads",extension.toUpperCase(),href);}else
3
- pageTracker._trackPageview(analyticsDownloadsPrefix+url);});}
4
- if((href.match(/^http/))&&(!href.match(document.domain))&&(downloadTracked==false)){a.click(function(){if(analyticsEventTracking=='enabled'){pageTracker._trackEvent("Outbound Traffic",href.match(/:\/\/(.[^/]+)/)[1],href);}else
5
- pageTracker._trackPageview(analyticsOutboundPrefix+url);});}});});
1
  jQuery(document).ready(function(){jQuery('a').each(function(){var a=jQuery(this);var href=a.attr('href');if(href==undefined)
2
+ return;var url=href.replace('http://','').replace('https://','');var hrefArray=href.split('.').reverse();var extension=hrefArray[0].toLowerCase();var hrefArray=href.split('/').reverse();var domain=hrefArray[2];var downloadTracked=false;if(jQuery.inArray(extension,analyticsFileTypes)!=-1){downloadTracked=true;a.click(function(){if(analyticsEventTracking=='enabled'){_gaq.push(['_trackEvent','Downloads',extension.toUpperCase(),href]);}else
3
+ _gaq.push(['_trackPageview',analyticsDownloadsPrefix+url]);});}
4
+ if((href.match(/^http/))&&(!href.match(document.domain))&&(downloadTracked==false)){a.click(function(){if(analyticsEventTracking=='enabled'){_gaq.push(['_trackEvent','Outbound Traffic',href.match(/:\/\/(.[^/]+)/)[1],href]);}else
5
+ _gaq.push(['_trackPageview',analyticsOutboundPrefix+url]);});}});});
google-analyticator.php CHANGED
@@ -1,15 +1,15 @@
1
  <?php
2
  /*
3
  * Plugin Name: Google Analyticator
4
- * Version: 5.3.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
8
- * Author URI: http://spiralwebconsulting.com/
9
  * Text Domain: google-analyticator
10
  */
11
 
12
- define('GOOGLE_ANALYTICATOR_VERSION', '5.3.2');
13
 
14
  // Constants for enabled/disabled state
15
  define("ga_enabled", "enabled", true);
@@ -29,8 +29,6 @@ define("key_ga_outbound", "ga_outbound", true);
29
  define("key_ga_outbound_prefix", "ga_outbound_prefix", true);
30
  define("key_ga_downloads", "ga_downloads", true);
31
  define("key_ga_downloads_prefix", "ga_downloads_prefix", true);
32
- define("key_ga_footer", "ga_footer", true);
33
- define("key_ga_specify_http", "ga_specify_http", true);
34
  define("key_ga_widgets", "ga_widgets", true);
35
 
36
  define("ga_uid_default", "XX-XXXXX-X", true);
@@ -46,8 +44,6 @@ define("ga_outbound_default", ga_enabled, true);
46
  define("ga_outbound_prefix_default", 'outgoing', true);
47
  define("ga_downloads_default", "", true);
48
  define("ga_downloads_prefix_default", "download", true);
49
- define("ga_footer_default", ga_disabled, true);
50
- define("ga_specify_http_default", "auto", true);
51
  define("ga_widgets_default", ga_enabled, true);
52
 
53
  // Create the default key and status
@@ -64,8 +60,6 @@ add_option(key_ga_outbound, ga_outbound_default, 'Add tracking of outbound links
64
  add_option(key_ga_outbound_prefix, ga_outbound_prefix_default, 'Add tracking of outbound links');
65
  add_option(key_ga_downloads, ga_downloads_default, 'Download extensions to track with Google Analyticator');
66
  add_option(key_ga_downloads_prefix, ga_downloads_prefix_default, 'Download extensions to track with Google Analyticator');
67
- add_option(key_ga_footer, ga_footer_default, 'If Google Analyticator is outputting in the footer');
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');
@@ -96,28 +90,12 @@ function ga_admin_init() {
96
  # Load the localization information
97
  $plugin_dir = basename(dirname(__FILE__));
98
  load_plugin_textdomain('google-analyticator', 'wp-content/plugins/' . $plugin_dir . '/localizations', $plugin_dir . '/localizations');
99
-
100
- // Register out options so WordPress knows about them
101
- if ( function_exists('register_setting') ) {
102
- register_setting('google-analyticator', key_ga_status, '');
103
- register_setting('google-analyticator', key_ga_uid, '');
104
- register_setting('google-analyticator', key_ga_admin, '');
105
- register_setting('google-analyticator', key_ga_admin_disable, '');
106
- register_setting('google-analyticator', key_ga_admin_level, '');
107
- register_setting('google-analyticator', key_ga_adsense, '');
108
- register_setting('google-analyticator', key_ga_extra, '');
109
- register_setting('google-analyticator', key_ga_extra_after, '');
110
- register_setting('google-analyticator', key_ga_event, '');
111
- register_setting('google-analyticator', key_ga_outbound, '');
112
- register_setting('google-analyticator', key_ga_outbound_prefix, '');
113
- register_setting('google-analyticator', key_ga_downloads, '');
114
- register_setting('google-analyticator', key_ga_downloads_prefix, '');
115
- register_setting('google-analyticator', key_ga_footer, '');
116
- register_setting('google-analyticator', key_ga_specify_http, '');
117
- }
118
  }
119
 
120
- // Initialize outbound link tracking
 
 
 
121
  add_action('init', 'ga_outgoing_links');
122
 
123
  // Hook in the options page function
@@ -146,9 +124,9 @@ function ga_filter_plugin_links($links, $file)
146
  {
147
  if ( $file == plugin_basename(__FILE__) )
148
  {
149
- $links[] = '<a href="http://plugins.spiralwebconsulting.com/forums/viewforum.php?f=5">' . __('FAQ', 'google-analyticator') . '</a>';
150
- $links[] = '<a href="http://plugins.spiralwebconsulting.com/forums/viewforum.php?f=6">' . __('Support', 'google-analyticator') . '</a>';
151
- $links[] = '<a href="http://plugins.spiralwebconsulting.com/analyticator.html#donate">' . __('Donate', 'google-analyticator') . '</a>';
152
  }
153
 
154
  return $links;
@@ -157,105 +135,93 @@ function ga_filter_plugin_links($links, $file)
157
  function ga_options_page() {
158
  // If we are a postback, store the options
159
  if (isset($_POST['info_update'])) {
160
- // if ( wp_verify_nonce($_POST['ga-nonce-key'], 'google-analyticator') ) {
161
-
162
- // Update the status
163
- $ga_status = $_POST[key_ga_status];
164
- if (($ga_status != ga_enabled) && ($ga_status != ga_disabled))
165
- $ga_status = ga_status_default;
166
- update_option(key_ga_status, $ga_status);
167
-
168
- // Update the UID
169
- $ga_uid = $_POST[key_ga_uid];
170
- if ($ga_uid == '')
171
- $ga_uid = ga_uid_default;
172
- update_option(key_ga_uid, $ga_uid);
173
-
174
- // Update the admin logging
175
- $ga_admin = $_POST[key_ga_admin];
176
- if (($ga_admin != ga_enabled) && ($ga_admin != ga_disabled))
177
- $ga_admin = ga_admin_default;
178
- update_option(key_ga_admin, $ga_admin);
179
-
180
- // Update the admin disable setting
181
- $ga_admin_disable = $_POST[key_ga_admin_disable];
182
- if ( $ga_admin_disable == '' )
183
- $ga_admin_disable = ga_admin_disable_default;
184
- update_option(key_ga_admin_disable, $ga_admin_disable);
185
-
186
- // Update the admin level
187
- $ga_admin_level = $_POST[key_ga_admin_level];
188
- if ( $ga_admin_level == '' )
189
- $ga_admin_level = ga_admin_level_default;
190
- update_option(key_ga_admin_level, $ga_admin_level);
191
-
192
- // Update the extra tracking code
193
- $ga_extra = $_POST[key_ga_extra];
194
- update_option(key_ga_extra, $ga_extra);
195
-
196
- // Update the extra after tracking code
197
- $ga_extra_after = $_POST[key_ga_extra_after];
198
- update_option(key_ga_extra_after, $ga_extra_after);
199
-
200
- // Update the adsense key
201
- $ga_adsense = $_POST[key_ga_adsense];
202
- update_option(key_ga_adsense, $ga_adsense);
203
-
204
- // Update the event tracking
205
- $ga_event = $_POST[key_ga_event];
206
- if (($ga_event != ga_enabled) && ($ga_event != ga_disabled))
207
- $ga_event = ga_event_default;
208
- update_option(key_ga_event, $ga_event);
209
-
210
- // Update the outbound tracking
211
- $ga_outbound = $_POST[key_ga_outbound];
212
- if (($ga_outbound != ga_enabled) && ($ga_outbound != ga_disabled))
213
- $ga_outbound = ga_outbound_default;
214
- update_option(key_ga_outbound, $ga_outbound);
215
-
216
- // Update the outbound prefix
217
- $ga_outbound_prefix = $_POST[key_ga_outbound_prefix];
218
- if ($ga_outbound_prefix == '')
219
- $ga_outbound_prefix = ga_outbound_prefix_default;
220
- update_option(key_ga_outbound_prefix, $ga_outbound_prefix);
221
-
222
- // Update the download tracking code
223
- $ga_downloads = $_POST[key_ga_downloads];
224
- update_option(key_ga_downloads, $ga_downloads);
225
-
226
- // Update the download prefix
227
- $ga_downloads_prefix = $_POST[key_ga_downloads_prefix];
228
- if ($ga_downloads_prefix == '')
229
- $ga_downloads_prefix = ga_downloads_prefix_default;
230
- update_option(key_ga_downloads_prefix, $ga_downloads_prefix);
231
-
232
- // Update the footer
233
- $ga_footer = $_POST[key_ga_footer];
234
- if (($ga_footer != ga_enabled) && ($ga_footer != ga_disabled))
235
- $ga_footer = ga_footer_default;
236
- update_option(key_ga_footer, $ga_footer);
237
-
238
- // Update the HTTP status
239
- $ga_specify_http = $_POST[key_ga_specify_http];
240
- if ( $ga_specify_http == '' )
241
- $ga_specify_http = 'auto';
242
- update_option(key_ga_specify_http, $ga_specify_http);
243
-
244
- // Update the widgets option
245
- $ga_widgets = $_POST[key_ga_widgets];
246
- if (($ga_widgets != ga_enabled) && ($ga_widgets != ga_disabled))
247
- $ga_widgets = ga_widgets_default;
248
- update_option(key_ga_widgets, $ga_widgets);
249
-
250
- // Update the compatibility options
251
- $ga_compatibility = $_POST['ga_compatibility'];
252
- if ( $ga_compatibility == '' )
253
- $ga_compatibility = 'off';
254
- update_option('ga_compatibility', $ga_compatibility);
255
-
256
- // Give an updated message
257
- echo "<div class='updated fade'><p><strong>" . __('Google Analyticator settings saved.', 'google-analyticator') . "</strong></p></div>";
258
- // }
259
  }
260
 
261
  // Output the options page
@@ -265,20 +231,13 @@ function ga_options_page() {
265
 
266
  <h2><?php _e('Google Analyticator Settings', 'google-analyticator'); ?></h2>
267
 
268
- <div style="float: right;">
269
- <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
270
- <input type="hidden" name="cmd" value="_s-xclick">
271
- <input type="hidden" name="hosted_button_id" value="6309412">
272
- <input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
273
- <img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1">
274
- </form>
275
- </div>
276
 
277
  <form method="post" action="options-general.php?page=google-analyticator.php">
278
-
279
- <p><em>
280
- <?php _e('Google Analyticator is brought to you for free by <a href="http://spiralwebconsulting.com/">Spiral Web Consulting</a>. Spiral Web Consulting is a small web development firm specializing in PHP development. Visit our website to learn more, and don\'t hesitate to ask us to develop your next big WordPress plugin idea.', 'google-analyticator'); ?>
281
- </em></p>
282
 
283
  <h3><?php _e('Basic Settings', 'google-analyticator'); ?></h3>
284
  <?php if (get_option(key_ga_status) == ga_disabled) { ?>
@@ -433,29 +392,6 @@ function ga_options_page() {
433
  <p style="margin: 5px 10px;" class="setting-description"><?php _e('Selecting the "Remove" option will physically remove the tracking code from logged in admin users. Selecting the "Use \'admin\' variable" option will assign a variable called \'admin\' to logged in admin users. This option will allow Google Analytics\' site overlay feature to work, but you will have to manually configure Google Analytics to exclude tracking from hits with the \'admin\' variable.', 'google-analyticator'); ?></p>
434
  </td>
435
  </tr>
436
- <tr>
437
- <th width="30%" valign="top" style="padding-top: 10px;">
438
- <label for="<?php echo key_ga_footer ?>"><?php _e('Footer tracking code', 'google-analyticator'); ?>:</label>
439
- </th>
440
- <td>
441
- <?php
442
- echo "<select name='".key_ga_footer."' id='".key_ga_footer."'>\n";
443
-
444
- echo "<option value='".ga_enabled."'";
445
- if(get_option(key_ga_footer) == ga_enabled)
446
- echo " selected='selected'";
447
- echo ">" . __('Enabled', 'google-analyticator') . "</option>\n";
448
-
449
- echo "<option value='".ga_disabled."'";
450
- if(get_option(key_ga_footer) == ga_disabled)
451
- echo" selected='selected'";
452
- echo ">" . __('Disabled', 'google-analyticator') . "</option>\n";
453
-
454
- echo "</select>\n";
455
- ?>
456
- <p style="margin: 5px 10px;" class="setting-description"><?php _e('Enabling this option will insert the Google Analytics tracking code in your site\'s footer instead of your header. This will speed up your page loading if turned on. Not all themes support code in the footer, so if you turn this option on, be sure to check the Analytics code is still displayed on your site.', 'google-analyticator'); ?></p>
457
- </td>
458
- </tr>
459
  <tr>
460
  <th width="30%" valign="top" style="padding-top: 10px;">
461
  <label for="<?php echo key_ga_outbound ?>"><?php _e('Outbound link tracking', 'google-analyticator'); ?>:</label>
@@ -586,34 +522,6 @@ function ga_options_page() {
586
  <p style="margin: 5px 10px;" class="setting-description"><?php _e('Enter any additional lines of tracking code that you would like to include in the Google Analytics tracking script. The code in this section will be displayed <strong>after</strong> the Google Analytics tracker is initialized. Read <a href="http://www.google.com/analytics/InstallingGATrackingCode.pdf">Google Analytics tracker manual</a> to learn what code goes here and how to use it.', 'google-analyticator'); ?></p>
587
  </td>
588
  </tr>
589
- <tr>
590
- <th width="30%" valign="top" style="padding-top: 10px;">
591
- <label for="<?php echo key_ga_specify_http; ?>"><?php _e('Specify HTTP detection', 'google-analyticator'); ?>:</label>
592
- </th>
593
- <td>
594
- <?php
595
- echo "<select name='".key_ga_specify_http."' id='".key_ga_specify_http."'>\n";
596
-
597
- echo "<option value='auto'";
598
- if(get_option(key_ga_specify_http) == 'auto')
599
- echo " selected='selected'";
600
- echo ">" . __('Auto Detect', 'google-analyticator') . "</option>\n";
601
-
602
- echo "<option value='http'";
603
- if(get_option(key_ga_specify_http) == 'http')
604
- echo " selected='selected'";
605
- echo ">" . __('HTTP', 'google-analyticator') . "</option>\n";
606
-
607
- echo "<option value='https'";
608
- if(get_option(key_ga_specify_http) == 'https')
609
- echo " selected='selected'";
610
- echo ">" . __('HTTPS', 'google-analyticator') . "</option>\n";
611
-
612
- echo "</select>\n";
613
- ?>
614
- <p style="margin: 5px 10px;" class="setting-description"><?php _e('Explicitly set the type of HTTP connection your website uses. Setting this option instead of relying on the auto detect may resolve the _gat is undefined error message.', 'google-analyticator'); ?></p>
615
- </td>
616
- </tr>
617
  <?php
618
  # Check if we have a version of WordPress greater than 2.8
619
  if ( function_exists('register_widget') ) {
@@ -672,7 +580,6 @@ function ga_options_page() {
672
  <?php } ?>
673
  </table>
674
  <p class="submit">
675
- <?php if ( function_exists('settings_fields') ) settings_fields('google-analyticator'); ?>
676
  <input type="submit" name="info_update" value="<?php _e('Save Changes', 'google-analyticator'); ?>" />
677
  </p>
678
  </div>
@@ -698,7 +605,7 @@ function ga_admin_ajax()
698
  url: 'admin-ajax.php',
699
  data: {
700
  action: 'ga_ajax_accounts',
701
- _ajax_nonce: '<?php echo wp_create_nonce("ga_ajax_accounts"); ?>'<?php if ( isset($_GET['token']) ) { ?>,
702
  token: '<?php echo $_GET["token"]; ?>'
703
  <?php } ?>
704
  },
@@ -726,7 +633,7 @@ add_action('wp_ajax_ga_ajax_accounts', 'ga_ajax_accounts');
726
  function ga_ajax_accounts()
727
  {
728
  # Check the ajax widget
729
- check_ajax_referer('ga_ajax_accounts');
730
 
731
  # Get the list of accounts if available
732
  $ga_accounts = ga_get_analytics_accounts();
@@ -818,110 +725,85 @@ if ( !function_exists('http_build_query') ) {
818
  }
819
  }
820
 
821
- // Add the script
822
- $ga_in_footer = false;
823
- if (get_option(key_ga_footer) == ga_enabled) {
824
- $ga_in_footer = true;
825
- add_action('wp_head', 'add_ga_adsense');
826
- add_action('wp_footer', 'add_google_analytics');
827
- } else {
828
- add_action('wp_head', 'add_google_analytics');
829
- }
830
-
831
  /**
832
- * Adds the Analytics Adsense tracking code to the header if the main Analytics tracking code is in the footer.
833
- * Idea and code for Adsense tracking with main code in footer props William Charles Nickerson on May 16, 2009.
834
  **/
835
- function add_ga_adsense() {
836
- $uid = stripslashes(get_option(key_ga_uid));
837
- // If GA is enabled and has a valid key
838
- if ( (get_option(key_ga_status) != ga_disabled ) && ( $uid != "XX-XXXXX-X" )) {
839
- // Display page tracking if user is not an admin
840
- if ( ( get_option(key_ga_admin) == ga_enabled || !current_user_can('level_' . get_option(key_ga_admin_level)) ) && get_option(key_ga_admin_disable) == 'remove' || get_option(key_ga_admin_disable) != 'remove' ) {
841
- if ( get_option(key_ga_adsense) != '' ) {
842
- echo "<!-- Google Analytics Tracking by Google Analyticator " . GOOGLE_ANALYTICATOR_VERSION . ": http://plugins.spiralwebconsulting.com/analyticator.html -->\n";
843
- echo ' <script type="text/javascript">window.google_analytics_uacct = "' . get_option(key_ga_adsense) . "\";</script>\n\n";
844
- }
845
- }
846
- }
847
- }
848
-
849
- // The guts of the Google Analytics script
850
- function add_google_analytics() {
851
- global $ga_in_footer;
852
-
853
  $uid = stripslashes(get_option(key_ga_uid));
854
  $extra = stripslashes(get_option(key_ga_extra));
855
  $extra_after = stripslashes(get_option(key_ga_extra_after));
856
  $extensions = str_replace (",", "|", get_option(key_ga_downloads));
857
 
858
- // If GA is enabled and has a valid key
859
- if ( (get_option(key_ga_status) != ga_disabled ) && ( $uid != "XX-XXXXX-X" )) {
860
-
861
- // Display page tracking if user is not an admin
862
- if ( ( get_option(key_ga_admin) == ga_enabled || !current_user_can('level_' . get_option(key_ga_admin_level)) ) && get_option(key_ga_admin_disable) == 'remove' || get_option(key_ga_admin_disable) != 'remove' ) {
863
-
864
- echo "<!-- Google Analytics Tracking by Google Analyticator " . GOOGLE_ANALYTICATOR_VERSION . ": http://plugins.spiralwebconsulting.com/analyticator.html -->\n";
865
- # Google Adsense data if enabled
866
- if ( get_option(key_ga_adsense) != '' && !$ga_in_footer )
867
- echo ' <script type="text/javascript">window.google_analytics_uacct = "' . get_option(key_ga_adsense) . "\";</script>\n\n";
868
 
869
- // Pick the HTTP connection
870
- if ( get_option(key_ga_specify_http) == 'http' ) {
871
- echo " <script type=\"text/javascript\" src=\"http://www.google-analytics.com/ga.js\"></script>\n\n";
872
- } elseif ( get_option(key_ga_specify_http) == 'https' ) {
873
- echo " <script type=\"text/javascript\" src=\"https://ssl.google-analytics.com/ga.js\"></script>\n\n";
874
- } else {
875
- echo " <script type=\"text/javascript\">\n";
876
- echo " var gaJsHost = ((\"https:\" == document.location.protocol) ? \"https://ssl.\" : \"http://www.\");\n";
877
- echo " document.write(unescape(\"%3Cscript src='\" + gaJsHost + \"google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E\"));\n";
878
- echo " </script>\n\n";
879
- }
880
-
881
- echo " <script type=\"text/javascript\">\n";
882
- echo " try {\n";
883
- echo " var pageTracker = _gat._getTracker(\"$uid\");\n";
884
-
885
- // Insert extra before tracker code
886
- if ( '' != $extra )
887
- echo " " . $extra . "\n";
888
-
889
- // Initialize the tracker
890
- echo " pageTracker._initData();\n";
891
- echo " pageTracker._trackPageview();\n";
892
-
893
- // Disable page tracking if admin is logged in
894
- if ( ( get_option(key_ga_admin) == ga_disabled ) && ( current_user_can('level_' . get_option(key_ga_admin_level)) ) )
895
- echo " pageTracker._setVar('admin');\n";
896
-
897
- // Insert extra after tracker code
898
- if ( '' != $extra_after )
899
- echo " " . $extra_after . "\n";
900
-
901
- echo " } catch(err) {}</script>\n";
902
-
903
- // Include the file types to track
904
  $extensions = explode(',', stripslashes(get_option(key_ga_downloads)));
905
  $ext = "";
906
  foreach ( $extensions AS $extension )
907
  $ext .= "'$extension',";
908
  $ext = substr($ext, 0, -1);
909
-
910
- // Include the link tracking prefixes
911
  $outbound_prefix = stripslashes(get_option(key_ga_outbound_prefix));
912
  $downloads_prefix = stripslashes(get_option(key_ga_downloads_prefix));
913
  $event_tracking = get_option(key_ga_event);
914
-
915
  ?>
916
- <script type="text/javascript">
917
- var analyticsFileTypes = [<?php echo strtolower($ext); ?>];
918
  <?php if ( $event_tracking != 'enabled' ) { ?>
919
- var analyticsOutboundPrefix = '/<?php echo $outbound_prefix; ?>/';
920
- var analyticsDownloadsPrefix = '/<?php echo $downloads_prefix; ?>/';
921
  <?php } ?>
922
- var analyticsEventTracking = '<?php echo $event_tracking; ?>';
923
- </script>
924
- <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
925
  }
926
  }
927
  }
@@ -931,14 +813,21 @@ function add_google_analytics() {
931
  **/
932
  function ga_outgoing_links()
933
  {
934
- // If GA is enabled and has a valid key
935
- if ( (get_option(key_ga_status) != ga_disabled ) && ( $uid != "XX-XXXXX-X" )) {
936
- // If outbound tracking is enabled
937
- if ( get_option(key_ga_outbound) == ga_enabled ) {
938
- // If this is not an admin page
939
- if ( !is_admin() ) {
940
- // Display page tracking if user is not an admin
941
- if ( ( get_option(key_ga_admin) == ga_enabled || !current_user_can('level_' . get_option(key_ga_admin_level)) ) && get_option(key_ga_admin_disable) == 'remove' || get_option(key_ga_admin_disable) != 'remove' ) {
 
 
 
 
 
 
 
942
  add_action('wp_print_scripts', 'ga_external_tracking_js');
943
  }
944
  }
@@ -951,8 +840,61 @@ function ga_outgoing_links()
951
  **/
952
  function ga_external_tracking_js()
953
  {
954
- // wp_enqueue_script('jquery');
955
  wp_enqueue_script('ga-external-tracking', plugins_url('/google-analyticator/external-tracking.min.js'), array('jquery'), GOOGLE_ANALYTICATOR_VERSION);
956
  }
957
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
958
  ?>
1
  <?php
2
  /*
3
  * Plugin Name: Google Analyticator
4
+ * Version: 6.0
5
+ * Plugin URI: http://ronaldheft.com/code/analyticator/
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: Ronald Heft
8
+ * Author URI: http://ronaldheft.com/
9
  * Text Domain: google-analyticator
10
  */
11
 
12
+ define('GOOGLE_ANALYTICATOR_VERSION', '6.0');
13
 
14
  // Constants for enabled/disabled state
15
  define("ga_enabled", "enabled", true);
29
  define("key_ga_outbound_prefix", "ga_outbound_prefix", true);
30
  define("key_ga_downloads", "ga_downloads", true);
31
  define("key_ga_downloads_prefix", "ga_downloads_prefix", true);
 
 
32
  define("key_ga_widgets", "ga_widgets", true);
33
 
34
  define("ga_uid_default", "XX-XXXXX-X", true);
44
  define("ga_outbound_prefix_default", 'outgoing', true);
45
  define("ga_downloads_default", "", true);
46
  define("ga_downloads_prefix_default", "download", true);
 
 
47
  define("ga_widgets_default", ga_enabled, true);
48
 
49
  // Create the default key and status
60
  add_option(key_ga_outbound_prefix, ga_outbound_prefix_default, 'Add tracking of outbound links');
61
  add_option(key_ga_downloads, ga_downloads_default, 'Download extensions to track with Google Analyticator');
62
  add_option(key_ga_downloads_prefix, ga_downloads_prefix_default, 'Download extensions to track with Google Analyticator');
 
 
63
  add_option(key_ga_widgets, ga_widgets_default, 'If the widgets are enabled or disabled');
64
  add_option('ga_google_token', '', 'The token used to authenticate with Google');
65
  add_option('ga_compatibility', 'off', 'Transport compatibility options');
90
  # Load the localization information
91
  $plugin_dir = basename(dirname(__FILE__));
92
  load_plugin_textdomain('google-analyticator', 'wp-content/plugins/' . $plugin_dir . '/localizations', $plugin_dir . '/localizations');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  }
94
 
95
+ # Add the core Google Analytics script, with a high priority to ensure last script for async tracking
96
+ add_action('wp_head', 'add_google_analytics', 999999);
97
+
98
+ # Initialize outbound link tracking
99
  add_action('init', 'ga_outgoing_links');
100
 
101
  // Hook in the options page function
124
  {
125
  if ( $file == plugin_basename(__FILE__) )
126
  {
127
+ $links[] = '<a href="http://forums.ronaldheft.com/viewforum.php?f=5">' . __('FAQ', 'google-analyticator') . '</a>';
128
+ $links[] = '<a href="http://forums.ronaldheft.com/viewforum.php?f=6">' . __('Support', 'google-analyticator') . '</a>';
129
+ $links[] = '<a href="http://ronaldheft.com/code/donate/">' . __('Donate', 'google-analyticator') . '</a>';
130
  }
131
 
132
  return $links;
135
  function ga_options_page() {
136
  // If we are a postback, store the options
137
  if (isset($_POST['info_update'])) {
138
+ # Verify nonce
139
+ check_admin_referer('google-analyticator-update_settings');
140
+
141
+ // Update the status
142
+ $ga_status = $_POST[key_ga_status];
143
+ if (($ga_status != ga_enabled) && ($ga_status != ga_disabled))
144
+ $ga_status = ga_status_default;
145
+ update_option(key_ga_status, $ga_status);
146
+
147
+ // Update the UID
148
+ $ga_uid = $_POST[key_ga_uid];
149
+ if ($ga_uid == '')
150
+ $ga_uid = ga_uid_default;
151
+ update_option(key_ga_uid, $ga_uid);
152
+
153
+ // Update the admin logging
154
+ $ga_admin = $_POST[key_ga_admin];
155
+ if (($ga_admin != ga_enabled) && ($ga_admin != ga_disabled))
156
+ $ga_admin = ga_admin_default;
157
+ update_option(key_ga_admin, $ga_admin);
158
+
159
+ // Update the admin disable setting
160
+ $ga_admin_disable = $_POST[key_ga_admin_disable];
161
+ if ( $ga_admin_disable == '' )
162
+ $ga_admin_disable = ga_admin_disable_default;
163
+ update_option(key_ga_admin_disable, $ga_admin_disable);
164
+
165
+ // Update the admin level
166
+ $ga_admin_level = $_POST[key_ga_admin_level];
167
+ if ( $ga_admin_level == '' )
168
+ $ga_admin_level = ga_admin_level_default;
169
+ update_option(key_ga_admin_level, $ga_admin_level);
170
+
171
+ // Update the extra tracking code
172
+ $ga_extra = $_POST[key_ga_extra];
173
+ update_option(key_ga_extra, $ga_extra);
174
+
175
+ // Update the extra after tracking code
176
+ $ga_extra_after = $_POST[key_ga_extra_after];
177
+ update_option(key_ga_extra_after, $ga_extra_after);
178
+
179
+ // Update the adsense key
180
+ $ga_adsense = $_POST[key_ga_adsense];
181
+ update_option(key_ga_adsense, $ga_adsense);
182
+
183
+ // Update the event tracking
184
+ $ga_event = $_POST[key_ga_event];
185
+ if (($ga_event != ga_enabled) && ($ga_event != ga_disabled))
186
+ $ga_event = ga_event_default;
187
+ update_option(key_ga_event, $ga_event);
188
+
189
+ // Update the outbound tracking
190
+ $ga_outbound = $_POST[key_ga_outbound];
191
+ if (($ga_outbound != ga_enabled) && ($ga_outbound != ga_disabled))
192
+ $ga_outbound = ga_outbound_default;
193
+ update_option(key_ga_outbound, $ga_outbound);
194
+
195
+ // Update the outbound prefix
196
+ $ga_outbound_prefix = $_POST[key_ga_outbound_prefix];
197
+ if ($ga_outbound_prefix == '')
198
+ $ga_outbound_prefix = ga_outbound_prefix_default;
199
+ update_option(key_ga_outbound_prefix, $ga_outbound_prefix);
200
+
201
+ // Update the download tracking code
202
+ $ga_downloads = $_POST[key_ga_downloads];
203
+ update_option(key_ga_downloads, $ga_downloads);
204
+
205
+ // Update the download prefix
206
+ $ga_downloads_prefix = $_POST[key_ga_downloads_prefix];
207
+ if ($ga_downloads_prefix == '')
208
+ $ga_downloads_prefix = ga_downloads_prefix_default;
209
+ update_option(key_ga_downloads_prefix, $ga_downloads_prefix);
210
+
211
+ // Update the widgets option
212
+ $ga_widgets = $_POST[key_ga_widgets];
213
+ if (($ga_widgets != ga_enabled) && ($ga_widgets != ga_disabled))
214
+ $ga_widgets = ga_widgets_default;
215
+ update_option(key_ga_widgets, $ga_widgets);
216
+
217
+ // Update the compatibility options
218
+ $ga_compatibility = $_POST['ga_compatibility'];
219
+ if ( $ga_compatibility == '' )
220
+ $ga_compatibility = 'off';
221
+ update_option('ga_compatibility', $ga_compatibility);
222
+
223
+ // Give an updated message
224
+ echo "<div class='updated fade'><p><strong>" . __('Google Analyticator settings saved.', 'google-analyticator') . "</strong></p></div>";
 
 
 
 
 
 
 
 
 
 
 
 
225
  }
226
 
227
  // Output the options page
231
 
232
  <h2><?php _e('Google Analyticator Settings', 'google-analyticator'); ?></h2>
233
 
234
+ <p><em>Like Google Analyticator? Help support it <a href="http://ronaldheft.com/code/donate/">by donating to the developer</a>. This helps cover the cost of maintaining the plugin and development time toward new features. Every donation, no matter how small, is appreciated.</em></p>
 
 
 
 
 
 
 
235
 
236
  <form method="post" action="options-general.php?page=google-analyticator.php">
237
+ <?php
238
+ # Add a nonce
239
+ wp_nonce_field('google-analyticator-update_settings');
240
+ ?>
241
 
242
  <h3><?php _e('Basic Settings', 'google-analyticator'); ?></h3>
243
  <?php if (get_option(key_ga_status) == ga_disabled) { ?>
392
  <p style="margin: 5px 10px;" class="setting-description"><?php _e('Selecting the "Remove" option will physically remove the tracking code from logged in admin users. Selecting the "Use \'admin\' variable" option will assign a variable called \'admin\' to logged in admin users. This option will allow Google Analytics\' site overlay feature to work, but you will have to manually configure Google Analytics to exclude tracking from hits with the \'admin\' variable.', 'google-analyticator'); ?></p>
393
  </td>
394
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
395
  <tr>
396
  <th width="30%" valign="top" style="padding-top: 10px;">
397
  <label for="<?php echo key_ga_outbound ?>"><?php _e('Outbound link tracking', 'google-analyticator'); ?>:</label>
522
  <p style="margin: 5px 10px;" class="setting-description"><?php _e('Enter any additional lines of tracking code that you would like to include in the Google Analytics tracking script. The code in this section will be displayed <strong>after</strong> the Google Analytics tracker is initialized. Read <a href="http://www.google.com/analytics/InstallingGATrackingCode.pdf">Google Analytics tracker manual</a> to learn what code goes here and how to use it.', 'google-analyticator'); ?></p>
523
  </td>
524
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
525
  <?php
526
  # Check if we have a version of WordPress greater than 2.8
527
  if ( function_exists('register_widget') ) {
580
  <?php } ?>
581
  </table>
582
  <p class="submit">
 
583
  <input type="submit" name="info_update" value="<?php _e('Save Changes', 'google-analyticator'); ?>" />
584
  </p>
585
  </div>
605
  url: 'admin-ajax.php',
606
  data: {
607
  action: 'ga_ajax_accounts',
608
+ _ajax_nonce: '<?php echo wp_create_nonce("google-analyticator-accounts_get"); ?>'<?php if ( isset($_GET['token']) ) { ?>,
609
  token: '<?php echo $_GET["token"]; ?>'
610
  <?php } ?>
611
  },
633
  function ga_ajax_accounts()
634
  {
635
  # Check the ajax widget
636
+ check_ajax_referer('google-analyticator-accounts_get');
637
 
638
  # Get the list of accounts if available
639
  $ga_accounts = ga_get_analytics_accounts();
725
  }
726
  }
727
 
 
 
 
 
 
 
 
 
 
 
728
  /**
729
+ * Echos out the core Analytics tracking code
 
730
  **/
731
+ function add_google_analytics()
732
+ {
733
+ # Fetch variables used in the tracking code
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
734
  $uid = stripslashes(get_option(key_ga_uid));
735
  $extra = stripslashes(get_option(key_ga_extra));
736
  $extra_after = stripslashes(get_option(key_ga_extra_after));
737
  $extensions = str_replace (",", "|", get_option(key_ga_downloads));
738
 
739
+ # Determine if the GA is enabled and contains a valid UID
740
+ if ( ( get_option(key_ga_status) != ga_disabled ) && ( $uid != "XX-XXXXX-X" ) )
741
+ {
742
+ # Determine if the user is an admin, and should see the tracking code
743
+ if ( ( get_option(key_ga_admin) == ga_enabled || !current_user_can('level_' . get_option(key_ga_admin_level)) ) && get_option(key_ga_admin_disable) == 'remove' || get_option(key_ga_admin_disable) != 'remove' )
744
+ {
745
+ # Add the notice that Google Analyticator tracking is enabled
746
+ echo "<!-- Google Analytics Tracking by Google Analyticator " . GOOGLE_ANALYTICATOR_VERSION . ": http://ronaldheft.com/code/analyticator/ -->\n";
 
 
747
 
748
+ # Add the Adsense data if specified
749
+ if ( get_option(key_ga_adsense) != '' )
750
+ echo '<script type="text/javascript">window.google_analytics_uacct = "' . get_option(key_ga_adsense) . "\";</script>\n";
751
+
752
+ # Include the file types to track
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
753
  $extensions = explode(',', stripslashes(get_option(key_ga_downloads)));
754
  $ext = "";
755
  foreach ( $extensions AS $extension )
756
  $ext .= "'$extension',";
757
  $ext = substr($ext, 0, -1);
758
+
759
+ # Include the link tracking prefixes
760
  $outbound_prefix = stripslashes(get_option(key_ga_outbound_prefix));
761
  $downloads_prefix = stripslashes(get_option(key_ga_downloads_prefix));
762
  $event_tracking = get_option(key_ga_event);
763
+
764
  ?>
765
+ <script type="text/javascript">
766
+ var analyticsFileTypes = [<?php echo strtolower($ext); ?>];
767
  <?php if ( $event_tracking != 'enabled' ) { ?>
768
+ var analyticsOutboundPrefix = '/<?php echo $outbound_prefix; ?>/';
769
+ var analyticsDownloadsPrefix = '/<?php echo $downloads_prefix; ?>/';
770
  <?php } ?>
771
+ var analyticsEventTracking = '<?php echo $event_tracking; ?>';
772
+ </script>
773
+ <?php
774
+ # Add the first part of the core tracking code
775
+ ?>
776
+ <script type="text/javascript">
777
+ var _gaq = _gaq || [];
778
+ _gaq.push(['_setAccount', '<?php echo $uid; ?>']);
779
+ <?php
780
+
781
+ # Add any tracking code before the trackPageview
782
+ if ( '' != $extra )
783
+ echo " $extra\n";
784
+
785
+ # Add the track pageview function
786
+ echo " _gaq.push(['_trackPageview']);\n";
787
+
788
+ # Disable page tracking if admin is logged in
789
+ if ( ( get_option(key_ga_admin) == ga_disabled ) && ( current_user_can('level_' . get_option(key_ga_admin_level)) ) )
790
+ echo " _gaq.push(['_setVar', 'admin]);\n";
791
+
792
+ # Add any tracking code after the trackPageview
793
+ if ( '' != $extra_after )
794
+ echo " $extra_after\n";
795
+
796
+ # Add the final section of the tracking code
797
+ ?>
798
+
799
+ (function() {
800
+ var ga = document.createElement('script');
801
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
802
+ ga.setAttribute('async', 'true');
803
+ document.documentElement.firstChild.appendChild(ga);
804
+ })();
805
+ </script>
806
+ <?php
807
  }
808
  }
809
  }
813
  **/
814
  function ga_outgoing_links()
815
  {
816
+ # Fetch the UID
817
+ $uid = stripslashes(get_option(key_ga_uid));
818
+
819
+ # If GA is enabled and has a valid key
820
+ if ( (get_option(key_ga_status) != ga_disabled ) && ( $uid != "XX-XXXXX-X" ) )
821
+ {
822
+ # If outbound tracking is enabled
823
+ if ( get_option(key_ga_outbound) == ga_enabled )
824
+ {
825
+ # If this is not an admin page
826
+ if ( !is_admin() )
827
+ {
828
+ # Display page tracking if user is not an admin
829
+ if ( ( get_option(key_ga_admin) == ga_enabled || !current_user_can('level_' . get_option(key_ga_admin_level)) ) && get_option(key_ga_admin_disable) == 'remove' || get_option(key_ga_admin_disable) != 'remove' )
830
+ {
831
  add_action('wp_print_scripts', 'ga_external_tracking_js');
832
  }
833
  }
840
  **/
841
  function ga_external_tracking_js()
842
  {
 
843
  wp_enqueue_script('ga-external-tracking', plugins_url('/google-analyticator/external-tracking.min.js'), array('jquery'), GOOGLE_ANALYTICATOR_VERSION);
844
  }
845
 
846
+ /**
847
+ * EXPERIMENTAL: Retrieve Google's visits for the given page
848
+ * More work needs to be done. Needs caching, needs to be less resource intensive, and
849
+ * needs an automated way to determine the page.
850
+ * Function may/will change in future releases. Only use if you know what you're doing.
851
+ *
852
+ * @param url - the page url, missing the domain information
853
+ * @param days - the number of days to get
854
+ * @return the number of visits
855
+ **/
856
+ function get_analytics_visits_by_page($page, $days = 31)
857
+ {
858
+ require_once('class.analytics.stats.php');
859
+
860
+ # Create a new API object
861
+ $api = new GoogleAnalyticsStats();
862
+
863
+ # Get the current accounts accounts
864
+ $accounts = ga_get_analytics_accounts();
865
+
866
+ # Verify accounts exist
867
+ if ( count($accounts) <= 0 )
868
+ return 0;
869
+
870
+ # Loop throught the account and return the current account
871
+ foreach ( $accounts AS $account )
872
+ {
873
+ # Check if the UID matches the selected UID
874
+ if ( $account['ga:webPropertyId'] == get_option('ga_uid') )
875
+ {
876
+ $api->setAccount($account['id']);
877
+ break;
878
+ }
879
+ }
880
+
881
+ # Encode the page url
882
+ $page = urlencode($page);
883
+
884
+ # Get the metric information from Google
885
+ $before = date('Y-m-d', strtotime('-' . $days . ' days'));
886
+ $yesterday = date('Y-m-d', strtotime('-1 day'));
887
+ $stats = $api->getMetrics('ga:visits', $before, $yesterday, 'ga:pagePath', false, 'ga:pagePath%3D%3D' . $page, 1);
888
+
889
+ # Check the size of the stats array
890
+ if ( count($stats) <= 0 || !is_array($stats) ) {
891
+ return 0;
892
+ } else {
893
+ # Loop through each stat for display
894
+ foreach ( $stats AS $stat ) {
895
+ return $stat['ga:visits'];
896
+ }
897
+ }
898
+ }
899
+
900
  ?>
google-analytics-summary-widget.php CHANGED
@@ -3,7 +3,7 @@
3
  /**
4
  * Creates a summary widget for Google Analytics stats
5
  *
6
- * @author Spiral Web Consulting
7
  **/
8
  class GoogleAnalyticsSummary
9
  {
@@ -38,7 +38,7 @@ class GoogleAnalyticsSummary
38
  function addJavascript()
39
  {
40
  # Include the Sparklines graphing library
41
- wp_enqueue_script('jquery-sparklines', plugins_url('/google-analyticator/jquery.sparkline.min.js'), array('jquery'), '1.4.2');
42
  }
43
 
44
  /**
@@ -51,23 +51,26 @@ class GoogleAnalyticsSummary
51
 
52
  jQuery(document).ready(function(){
53
 
 
 
 
54
  // Grab the widget data
55
  jQuery.ajax({
56
  type: 'post',
57
  url: 'admin-ajax.php',
58
  data: {
59
  action: 'ga_stats_widget',
60
- _ajax_nonce: '<?php echo wp_create_nonce("ga_stats_widget"); ?>'
61
  },
62
  success: function(html) {
63
  // Hide the loading message
64
- jQuery('#google-analytics-summary .inside').hide();
65
 
66
  // Place the widget data in the area
67
- jQuery('#google-analytics-summary .inside').html(html);
68
 
69
  // Display the widget data
70
- jQuery('#google-analytics-summary .inside').slideDown();
71
 
72
  // Handle displaying the graph
73
  if ( navigator.appName != 'Microsoft Internet Explorer' ) {
@@ -92,6 +95,7 @@ class GoogleAnalyticsSummary
92
  function widget()
93
  {
94
  echo '<small>' . __('Loading') . '...</small>';
 
95
  }
96
 
97
  /**
@@ -100,7 +104,7 @@ class GoogleAnalyticsSummary
100
  function ajaxWidget()
101
  {
102
  # Check the ajax widget
103
- check_ajax_referer('ga_stats_widget');
104
 
105
  # Attempt to login and get the current account
106
  $this->id = $this->getAnalyticsAccount();
@@ -369,7 +373,7 @@ class GoogleAnalyticsSummary
369
  # Get the metrics needed to build the top pages
370
  $before = date('Y-m-d', strtotime('-31 days'));
371
  $yesterday = date('Y-m-d', strtotime('-1 day'));
372
- $stats = $this->api->getMetrics('ga:pageviews', $before, $yesterday, 'ga:pageTitle,ga:pagePath', '-ga:pageviews', 'ga:pagePath!%3D%2F', '5');
373
 
374
  # Store the serialized stats in the database
375
  $newStats = serialize(array('stats'=>$stats, 'lastcalled'=>time()));
@@ -384,9 +388,52 @@ class GoogleAnalyticsSummary
384
  # Build the top pages list
385
  echo '<ol>';
386
 
387
- # Loop through each stat
 
 
 
 
388
  foreach ( $stats AS $stat ) {
389
- echo '<li><a href="' . esc_html($stat['ga:pagePath']) . '">' . $stat['ga:pageTitle'] . '</a> - ' . number_format($stat['ga:pageviews']) . ' ' . __('Views', 'google-analyticator') . '</li>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
390
  }
391
 
392
  # Finish the list
@@ -496,6 +543,21 @@ class GoogleAnalyticsSummary
496
  }
497
  }
498
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
499
  /**
500
  * Convert second to a time format
501
  **/
3
  /**
4
  * Creates a summary widget for Google Analytics stats
5
  *
6
+ * @author Ronald Heft
7
  **/
8
  class GoogleAnalyticsSummary
9
  {
38
  function addJavascript()
39
  {
40
  # Include the Sparklines graphing library
41
+ wp_enqueue_script('jquery-sparklines', plugins_url('/google-analyticator/jquery.sparkline.min.js'), array('jquery'), '1.4.3');
42
  }
43
 
44
  /**
51
 
52
  jQuery(document).ready(function(){
53
 
54
+ // Add a link to see full stats on the Analytics website
55
+ jQuery('#google-analytics-summary h3.hndle span').append('<span class="postbox-title-action"><a href="http://google.com/analytics/" class="edit-box open-box"><?php _e('View Full Stat Report', 'google-analyticator'); ?></a></span>');
56
+
57
  // Grab the widget data
58
  jQuery.ajax({
59
  type: 'post',
60
  url: 'admin-ajax.php',
61
  data: {
62
  action: 'ga_stats_widget',
63
+ _ajax_nonce: '<?php echo wp_create_nonce("google-analyticator-statsWidget_get"); ?>'
64
  },
65
  success: function(html) {
66
  // Hide the loading message
67
+ jQuery('#google-analytics-summary .inside small').remove();
68
 
69
  // Place the widget data in the area
70
+ jQuery('#google-analytics-summary .inside .target').html(html);
71
 
72
  // Display the widget data
73
+ jQuery('#google-analytics-summary .inside .target').slideDown();
74
 
75
  // Handle displaying the graph
76
  if ( navigator.appName != 'Microsoft Internet Explorer' ) {
95
  function widget()
96
  {
97
  echo '<small>' . __('Loading') . '...</small>';
98
+ echo '<div class="target" style="display: none;"></div>';
99
  }
100
 
101
  /**
104
  function ajaxWidget()
105
  {
106
  # Check the ajax widget
107
+ check_ajax_referer('google-analyticator-statsWidget_get');
108
 
109
  # Attempt to login and get the current account
110
  $this->id = $this->getAnalyticsAccount();
373
  # Get the metrics needed to build the top pages
374
  $before = date('Y-m-d', strtotime('-31 days'));
375
  $yesterday = date('Y-m-d', strtotime('-1 day'));
376
+ $stats = $this->api->getMetrics('ga:pageviews', $before, $yesterday, 'ga:pageTitle,ga:pagePath', '-ga:pageviews', 'ga:pagePath!%3D%2F', '10');
377
 
378
  # Store the serialized stats in the database
379
  $newStats = serialize(array('stats'=>$stats, 'lastcalled'=>time()));
388
  # Build the top pages list
389
  echo '<ol>';
390
 
391
+ # Set variables needed to correct (not set) bug
392
+ $new_stats = array();
393
+ $notset_stats = array();
394
+
395
+ # Loop through each stat and create a new array
396
  foreach ( $stats AS $stat ) {
397
+ # If the stat is not set
398
+ if ( $stat['ga:pageTitle'] == '(not set)' ) {
399
+ # Add it to separate array
400
+ $notset_stats[] = $stat;
401
+ } else {
402
+ # Add it to new array with index set
403
+ $new_stats[$stat['ga:pagePath']] = $stat;
404
+ }
405
+ }
406
+
407
+ # Loop through all the (not set) stats and attempt to add them to their correct stat
408
+ foreach ( $notset_stats AS $stat ) {
409
+ # If the stat has a "partner"
410
+ if ( $new_stats[$stat['ga:pagePath']] != NULL ) {
411
+ # Add the pageviews to the stat
412
+ $new_stats[$stat['ga:pagePath']]['ga:pageviews'] = $new_stats[$stat['ga:pagePath']]['ga:pageviews'] + $stat['ga:pageviews'];
413
+ } else {
414
+ # Stat goes to the ether since we couldn't find a partner (if anyone reads this and has a suggestion to improve, let me know)
415
+ }
416
+ }
417
+
418
+ # Renew new_stats back to stats
419
+ $stats = $new_stats;
420
+
421
+ # Sort the stats array, since adding the (not set) items may have changed the order
422
+ usort($stats, array($this, 'statSort'));
423
+
424
+ # Since we can no longer rely on the API as a limiter, we need to keep track of this ourselves
425
+ $stat_count = 0;
426
+
427
+ # Loop through each stat for display
428
+ foreach ( $stats AS $stat ) {
429
+ echo '<li><a href="' . esc_url($stat['ga:pagePath']) . '">' . esc_html($stat['ga:pageTitle']) . '</a> - ' . number_format($stat['ga:pageviews']) . ' ' . __('Views', 'google-analyticator') . '</li>';
430
+
431
+ # Increase the stat counter
432
+ $stat_count++;
433
+
434
+ # Stop at 5
435
+ if ( $stat_count >= 5 )
436
+ break;
437
  }
438
 
439
  # Finish the list
543
  }
544
  }
545
 
546
+ /**
547
+ * Sort a set of stats in descending order
548
+ *
549
+ * @return how the stat should be sorted
550
+ **/
551
+ function statSort($x, $y)
552
+ {
553
+ if ( $x['ga:pageviews'] == $y['ga:pageviews'] )
554
+ return 0;
555
+ elseif ( $x['ga:pageviews'] < $y['ga:pageviews'] )
556
+ return 1;
557
+ else
558
+ return -1;
559
+ }
560
+
561
  /**
562
  * Convert second to a time format
563
  **/
jquery.sparkline.min.js CHANGED
@@ -1,10 +1,10 @@
1
- /* jquery.sparkline 1.4.2 - http://omnipotent.net/jquery.sparkline/ */
2
 
3
  (function($){$.fn.simpledraw=function(width,height,use_existing){if(use_existing&&this[0].vcanvas)return this[0].vcanvas;if(width==undefined)width=$(this).innerWidth();if(height==undefined)height=$(this).innerHeight();if($.browser.hasCanvas){return new vcanvas_canvas(width,height,this);}else if($.browser.msie){return new vcanvas_vml(width,height,this);}else{return false;}};var pending=[];$.fn.sparkline=function(uservalues,options){var options=$.extend({type:'line',lineColor:'#00f',fillColor:'#cdf',defaultPixelsPerValue:3,width:'auto',height:'auto',composite:false},options?options:{});return this.each(function(){var render=function(){var values=(uservalues=='html'||uservalues==undefined)?$(this).text().split(','):uservalues;var width=options.width=='auto'?values.length*options.defaultPixelsPerValue:options.width;if(options.height=='auto'){if(!options.composite||!this.vcanvas){var tmp=document.createElement('span');tmp.innerHTML='a';$(this).html(tmp);height=$(tmp).innerHeight();$(tmp).remove();}}else{height=options.height;}
4
  $.fn.sparkline[options.type].call(this,values,options,width,height);}
5
- if(($(this).html()&&$(this).is(':hidden'))||($.fn.jquery<"1.3.0"&&$(this).parents().is(':hidden'))){pending.push([this,render]);}else{render.call(this);}});};$.sparkline_display_visible=function(){for(var i=pending.length-1;i>=0;i--){var el=pending[i][0];if($(el).is(':visible')&&!$(el).parents().is(':hidden')){pending[i][1].call(el);pending.splice(i,1);}}};$.fn.sparkline.line=function(values,options,width,height){var options=$.extend({spotColor:'#f80',spotRadius:1.5,minSpotColor:'#f80',maxSpotColor:'#f80',normalRangeMin:undefined,normalRangeMax:undefined,normalRangeColor:'#ccc',chartRangeMin:undefined,chartRangeMax:undefined},options?options:{});var xvalues=[],yvalues=[];for(i=0;i<values.length;i++){var isstr=typeof(values[i])=='string';var isarray=typeof(values[i])=='object'&&values[i]instanceof Array;var sp=isstr&&values[i].split(':');if(isstr&&sp.length==2){xvalues.push(Number(sp[0]));yvalues.push(Number(sp[1]));}else if(isarray){xvalues.push(values[i][0]);yvalues.push(values[i][1]);}else{xvalues.push(i);yvalues.push(Number(values[i]));}}
6
  if(options.xvalues){xvalues=options.xvalues;}
7
- var maxy=Math.max.apply(Math,yvalues);var maxyval=maxy;var miny=Math.min.apply(Math,yvalues);var minyval=miny;var maxx=Math.max.apply(Math,xvalues);var maxxval=maxx;var minx=Math.min.apply(Math,xvalues);var minxval=minx;if(options.normalRangeMin!=undefined){if(options.normalRangeMin<miny)
8
  miny=options.normalRangeMin;if(options.normalRangeMax>maxy)
9
  maxy=options.normalRangeMax;}
10
  if(options.chartRangeMin!=undefined&&options.chartRangeMin<miny){miny=options.chartRangeMin;}
@@ -17,14 +17,21 @@ if(options.minSpotColor||options.maxSpotColor&&(yvalues[0]==miny||yvalues[0]==ma
17
  if(options.spotColor||(options.minSpotColor||options.maxSpotColor&&(yvalues[vl]==miny||yvalues[vl]==maxy)))
18
  canvas_width-=Math.ceil(options.spotRadius);}
19
  canvas_height--;if(options.normalRangeMin!=undefined){var ytop=canvas_top+Math.round(canvas_height-(canvas_height*((options.normalRangeMax-miny)/rangey)));var height=Math.round((canvas_height*(options.normalRangeMax-options.normalRangeMin))/rangey);target.drawRect(canvas_left,ytop,canvas_width,height,undefined,options.normalRangeColor);}
20
- var path=[[canvas_left,canvas_top+canvas_height]];for(var i=0;i<yvalues.length;i++){var x=xvalues[i],y=yvalues[i];path.push([canvas_left+Math.round((x-minx)*(canvas_width/rangex)),canvas_top+Math.round(canvas_height-(canvas_height*((y-miny)/rangey)))]);}
21
- if(options.fillColor){path.push([canvas_left+canvas_width,canvas_top+canvas_height-1]);target.drawShape(path,undefined,options.fillColor);path.pop();}
22
- path[0]=[canvas_left,canvas_top+Math.round(canvas_height-(canvas_height*((yvalues[0]-miny)/rangey)))];target.drawShape(path,options.lineColor);if(options.spotRadius&&options.spotColor){target.drawCircle(canvas_left+canvas_width,canvas_top+Math.round(canvas_height-(canvas_height*((yvalues[vl]-miny)/rangey))),options.spotRadius,undefined,options.spotColor);}
 
 
 
 
23
  if(maxy!=minyval){if(options.spotRadius&&options.minSpotColor){var x=xvalues[yvalues.indexOf(minyval)];target.drawCircle(canvas_left+Math.round((x-minx)*(canvas_width/rangex)),canvas_top+Math.round(canvas_height-(canvas_height*((minyval-miny)/rangey))),options.spotRadius,undefined,options.minSpotColor);}
24
- if(options.spotRadius&&options.maxSpotColor){var x=xvalues[yvalues.indexOf(maxyval)];target.drawCircle(canvas_left+Math.round((x-minx)*(canvas_width/rangex)),canvas_top+Math.round(canvas_height-(canvas_height*((maxyval-miny)/rangey))),options.spotRadius,undefined,options.maxSpotColor);}}}else{this.innerHTML='';}};$.fn.sparkline.bar=function(values,options,width,height){values=$.map(values,Number);var options=$.extend({type:'bar',barColor:'#00f',negBarColor:'#f44',zeroColor:undefined,zeroAxis:undefined,barWidth:4,barSpacing:1,chartRangeMax:undefined,chartRangeMin:undefined},options?options:{});var width=(values.length*options.barWidth)+((values.length-1)*options.barSpacing);var max=Math.max.apply(Math,values);var min=Math.min.apply(Math,values);if(options.chartRangeMin!=undefined&&options.chartRangeMin<min){min=options.chartRangeMin;}
 
25
  if(options.chartRangeMax!=undefined&&options.chartRangeMax>max){max=options.chartRangeMax;}
26
- if(options.zeroAxis==undefined)options.zeroAxis=min<0;var range=max-min==0?1:max-min;var target=$(this).simpledraw(width,height);if(target){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;var yzero=min<0&&options.zeroAxis?canvas_height-Math.round(canvas_height*(Math.abs(min)/range))-1:canvas_height-1;for(var i=0;i<values.length;i++){var x=i*(options.barWidth+options.barSpacing);var val=values[i];var color=(val<0)?options.negBarColor:options.barColor;if(options.zeroAxis&&min<0){var height=Math.round(canvas_height*((Math.abs(val)/range)))+1;var y=(val<0)?yzero:yzero-height;}else{var height=Math.round(canvas_height*((val-min)/range))+1;var y=canvas_height-height;}
 
27
  if(val==0&&options.zeroColor!=undefined){color=options.zeroColor;}
 
28
  target.drawRect(x,y,options.barWidth-1,height-1,color,color);}}else{this.innerHTML='';}};$.fn.sparkline.tristate=function(values,options,width,height){values=$.map(values,Number);var options=$.extend({barWidth:4,barSpacing:1,posBarColor:'#6f6',negBarColor:'#f44',zeroBarColor:'#999',colorMap:{}},options);var width=(values.length*options.barWidth)+((values.length-1)*options.barSpacing);var target=$(this).simpledraw(width,height);if(target){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;var half_height=Math.round(canvas_height/2);for(var i=0;i<values.length;i++){var x=i*(options.barWidth+options.barSpacing);if(values[i]<0){var y=half_height;var height=half_height-1;var color=options.negBarColor;}else if(values[i]>0){var y=0;var height=half_height-1;var color=options.posBarColor;}else{var y=half_height-1;var height=2;var color=options.zeroBarColor;}
29
  if(options.colorMap[values[i]]){color=options.colorMap[values[i]];}
30
  target.drawRect(x,y,options.barWidth-1,height-1,color,color);}}else{this.innerHTML='';}};$.fn.sparkline.discrete=function(values,options,width,height){values=$.map(values,Number);var options=$.extend({lineHeight:'auto',thresholdColor:undefined,thresholdValue:0,chartRangeMax:undefined,chartRangeMin:undefined},options);width=options.width=='auto'?values.length*2:width;var interval=Math.floor(width/values.length);var target=$(this).simpledraw(width,height);if(target){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;var line_height=options.lineHeight=='auto'?Math.round(canvas_height*0.3):options.lineHeight;var pheight=canvas_height-line_height;var min=Math.min.apply(Math,values);var max=Math.max.apply(Math,values);if(options.chartRangeMin!=undefined&&options.chartRangeMin<min){min=options.chartRangeMin;}
@@ -46,15 +53,15 @@ return i;}
46
  return-1;}}
47
  if($.browser.msie&&!document.namespaces['v']){document.namespaces.add('v','urn:schemas-microsoft-com:vml','#default#VML');}
48
  if($.browser.hasCanvas==undefined){var t=document.createElement('canvas');$.browser.hasCanvas=t.getContext!=undefined;}
49
- var vcanvas_base=function(width,height,target){};vcanvas_base.prototype={init:function(width,height,target){this.width=width;this.height=height;this.target=target;if(target[0])target=target[0];target.vcanvas=this;},drawShape:function(path,lineColor,fillColor){alert('drawShape not implemented');},drawLine:function(x1,y1,x2,y2,lineColor){return this.drawShape([[x1,y1],[x2,y2]],lineColor);},drawCircle:function(x,y,radius,lineColor,fillColor){alert('drawCircle not implemented');},drawPieSlice:function(x,y,radius,startAngle,endAngle,lineColor,fillColor){alert('drawPieSlice not implemented');},drawRect:function(x,y,width,height,lineColor,fillColor){alert('drawRect not implemented');},getElement:function(){return this.canvas;},_insert:function(el,target){$(target).html(el);}};var vcanvas_canvas=function(width,height,target){return this.init(width,height,target);};vcanvas_canvas.prototype=$.extend(new vcanvas_base,{_super:vcanvas_base.prototype,init:function(width,height,target){this._super.init(width,height,target);this.canvas=document.createElement('canvas');if(target[0])target=target[0];target.vcanvas=this;$(this.canvas).css({display:'inline-block',width:width,height:height,verticalAlign:'top'});this._insert(this.canvas,target);this.pixel_height=$(this.canvas).height();this.pixel_width=$(this.canvas).width();this.canvas.width=this.pixel_width;this.canvas.height=this.pixel_height;$(this.canvas).css({width:this.pixel_width,height:this.pixel_height});},_getContext:function(lineColor,fillColor){var context=this.canvas.getContext('2d');if(lineColor!=undefined)
50
- context.strokeStyle=lineColor;context.lineWidth=1;if(fillColor!=undefined)
51
- context.fillStyle=fillColor;return context;},drawShape:function(path,lineColor,fillColor){var context=this._getContext(lineColor,fillColor);context.beginPath();context.moveTo(path[0][0]+0.5,path[0][1]+0.5);for(var i=1;i<path.length;i++){context.lineTo(path[i][0]+0.5,path[i][1]+0.5);}
52
  if(lineColor!=undefined){context.stroke();}
53
  if(fillColor!=undefined){context.fill();}},drawCircle:function(x,y,radius,lineColor,fillColor){var context=this._getContext(lineColor,fillColor);context.beginPath();context.arc(x,y,radius,0,2*Math.PI,false);if(lineColor!=undefined){context.stroke();}
54
  if(fillColor!=undefined){context.fill();}},drawPieSlice:function(x,y,radius,startAngle,endAngle,lineColor,fillColor){var context=this._getContext(lineColor,fillColor);context.beginPath();context.moveTo(x,y);context.arc(x,y,radius,startAngle,endAngle,false);context.lineTo(x,y);context.closePath();if(lineColor!=undefined){context.stroke();}
55
  if(fillColor){context.fill();}},drawRect:function(x,y,width,height,lineColor,fillColor){return this.drawShape([[x,y],[x+width,y],[x+width,y+height],[x,y+height],[x,y]],lineColor,fillColor);}});var vcanvas_vml=function(width,height,target){return this.init(width,height,target);};vcanvas_vml.prototype=$.extend(new vcanvas_base,{_super:vcanvas_base.prototype,init:function(width,height,target){this._super.init(width,height,target);if(target[0])target=target[0];target.vcanvas=this;this.canvas=document.createElement('span');$(this.canvas).css({display:'inline-block',position:'relative',overflow:'hidden',width:width,height:height,margin:'0px',padding:'0px',verticalAlign:'top'});this._insert(this.canvas,target);this.pixel_height=$(this.canvas).height();this.pixel_width=$(this.canvas).width();this.canvas.width=this.pixel_width;this.canvas.height=this.pixel_height;;var groupel='<v:group coordorigin="0 0" coordsize="'+this.pixel_width+' '+this.pixel_height+'"'
56
- +' style="position:absolute;top:0;left:0;width:'+this.pixel_width+'px;height='+this.pixel_height+'px;"></v:group>';this.canvas.insertAdjacentHTML('beforeEnd',groupel);this.group=$(this.canvas).children()[0];},drawShape:function(path,lineColor,fillColor){var vpath=[];for(var i=0;i<path.length;i++){vpath[i]=''+(path[i][0])+','+(path[i][1]);}
57
- var initial=vpath.splice(0,1);var stroke=lineColor==undefined?' stroked="false" ':' strokeWeight="1" strokeColor="'+lineColor+'" ';var fill=fillColor==undefined?' filled="false"':' fillColor="'+fillColor+'" filled="true" ';var closed=vpath[0]==vpath[vpath.length-1]?'x ':'';var vel='<v:shape coordorigin="0 0" coordsize="'+this.pixel_width+' '+this.pixel_height+'" '
58
  +stroke
59
  +fill
60
  +' style="position:absolute;left:0px;top:0px;height:'+this.pixel_height+'px;width:'+this.pixel_width+'px;padding:0px;margin:0px;" '
1
+ /* jquery.sparkline 1.4.3 - http://omnipotent.net/jquery.sparkline/ */
2
 
3
  (function($){$.fn.simpledraw=function(width,height,use_existing){if(use_existing&&this[0].vcanvas)return this[0].vcanvas;if(width==undefined)width=$(this).innerWidth();if(height==undefined)height=$(this).innerHeight();if($.browser.hasCanvas){return new vcanvas_canvas(width,height,this);}else if($.browser.msie){return new vcanvas_vml(width,height,this);}else{return false;}};var pending=[];$.fn.sparkline=function(uservalues,options){var options=$.extend({type:'line',lineColor:'#00f',fillColor:'#cdf',defaultPixelsPerValue:3,width:'auto',height:'auto',composite:false},options?options:{});return this.each(function(){var render=function(){var values=(uservalues=='html'||uservalues==undefined)?$(this).text().split(','):uservalues;var width=options.width=='auto'?values.length*options.defaultPixelsPerValue:options.width;if(options.height=='auto'){if(!options.composite||!this.vcanvas){var tmp=document.createElement('span');tmp.innerHTML='a';$(this).html(tmp);height=$(tmp).innerHeight();$(tmp).remove();}}else{height=options.height;}
4
  $.fn.sparkline[options.type].call(this,values,options,width,height);}
5
+ if(($(this).html()&&$(this).is(':hidden'))||($.fn.jquery<"1.3.0"&&$(this).parents().is(':hidden'))){pending.push([this,render]);}else{render.call(this);}});};$.sparkline_display_visible=function(){for(var i=pending.length-1;i>=0;i--){var el=pending[i][0];if($(el).is(':visible')&&!$(el).parents().is(':hidden')){pending[i][1].call(el);pending.splice(i,1);}}};$.fn.sparkline.line=function(values,options,width,height){var options=$.extend({spotColor:'#f80',spotRadius:1.5,minSpotColor:'#f80',maxSpotColor:'#f80',lineWidth:1,normalRangeMin:undefined,normalRangeMax:undefined,normalRangeColor:'#ccc',chartRangeMin:undefined,chartRangeMax:undefined},options?options:{});var xvalues=[],yvalues=[],yminmax=[];for(i=0;i<values.length;i++){var v=values[i];var isstr=typeof(values[i])=='string';var isarray=typeof(values[i])=='object'&&values[i]instanceof Array;var sp=isstr&&values[i].split(':');if(isstr&&sp.length==2){xvalues.push(Number(sp[0]));yvalues.push(Number(sp[1]));yminmax.push(Number(sp[1]));}else if(isarray){xvalues.push(values[i][0]);yvalues.push(values[i][1]);yminmax.push(values[i][1]);}else{xvalues.push(i);if(values[i]===null||values[i]=='null'){yvalues.push(null);}else{yvalues.push(Number(values[i]));yminmax.push(Number(values[i]));}}}
6
  if(options.xvalues){xvalues=options.xvalues;}
7
+ var maxy=Math.max.apply(Math,yminmax);var maxyval=maxy;var miny=Math.min.apply(Math,yminmax);var minyval=miny;var maxx=Math.max.apply(Math,xvalues);var maxxval=maxx;var minx=Math.min.apply(Math,xvalues);var minxval=minx;if(options.normalRangeMin!=undefined){if(options.normalRangeMin<miny)
8
  miny=options.normalRangeMin;if(options.normalRangeMax>maxy)
9
  maxy=options.normalRangeMax;}
10
  if(options.chartRangeMin!=undefined&&options.chartRangeMin<miny){miny=options.chartRangeMin;}
17
  if(options.spotColor||(options.minSpotColor||options.maxSpotColor&&(yvalues[vl]==miny||yvalues[vl]==maxy)))
18
  canvas_width-=Math.ceil(options.spotRadius);}
19
  canvas_height--;if(options.normalRangeMin!=undefined){var ytop=canvas_top+Math.round(canvas_height-(canvas_height*((options.normalRangeMax-miny)/rangey)));var height=Math.round((canvas_height*(options.normalRangeMax-options.normalRangeMin))/rangey);target.drawRect(canvas_left,ytop,canvas_width,height,undefined,options.normalRangeColor);}
20
+ var path=[];var paths=[path];for(var i=0;i<yvalues.length;i++){var x=xvalues[i],y=yvalues[i];if(y===null){if(i){if(yvalues[i-1]!==null){path=[];paths.push(path);}}}else{if(!path.length){path.push([canvas_left+Math.round((x-minx)*(canvas_width/rangex)),canvas_top+canvas_height]);}
21
+ path.push([canvas_left+Math.round((x-minx)*(canvas_width/rangex)),canvas_top+Math.round(canvas_height-(canvas_height*((y-miny)/rangey)))]);}}
22
+ for(var i=0;i<paths.length;i++){path=paths[i];if(!path.length)
23
+ continue;if(options.fillColor){path.push([path[path.length-1][0],canvas_top+canvas_height-1]);target.drawShape(path,undefined,options.fillColor);path.pop();}
24
+ if(path.length>2){path[0]=[path[0][0],path[1][1]];}
25
+ target.drawShape(path,options.lineColor,undefined,options.lineWidth);}
26
+ if(options.spotRadius&&options.spotColor){target.drawCircle(canvas_left+canvas_width,canvas_top+Math.round(canvas_height-(canvas_height*((yvalues[vl]-miny)/rangey))),options.spotRadius,undefined,options.spotColor);}
27
  if(maxy!=minyval){if(options.spotRadius&&options.minSpotColor){var x=xvalues[yvalues.indexOf(minyval)];target.drawCircle(canvas_left+Math.round((x-minx)*(canvas_width/rangex)),canvas_top+Math.round(canvas_height-(canvas_height*((minyval-miny)/rangey))),options.spotRadius,undefined,options.minSpotColor);}
28
+ if(options.spotRadius&&options.maxSpotColor){var x=xvalues[yvalues.indexOf(maxyval)];target.drawCircle(canvas_left+Math.round((x-minx)*(canvas_width/rangex)),canvas_top+Math.round(canvas_height-(canvas_height*((maxyval-miny)/rangey))),options.spotRadius,undefined,options.maxSpotColor);}}}else{this.innerHTML='';}};$.fn.sparkline.bar=function(values,options,width,height){var options=$.extend({type:'bar',barColor:'#00f',negBarColor:'#f44',zeroColor:undefined,zeroAxis:undefined,barWidth:4,barSpacing:1,chartRangeMax:undefined,chartRangeMin:undefined,colorMap:{}},options?options:{});var width=(values.length*options.barWidth)+((values.length-1)*options.barSpacing);var num_values=[];for(var i=0;i<values.length;i++){if(values[i]=='null'||values[i]===null){values[i]=null;}else{values[i]=Number(values[i]);num_values.push(Number(values[i]));}}
29
+ var max=Math.max.apply(Math,num_values);var min=Math.min.apply(Math,num_values);if(options.chartRangeMin!=undefined&&options.chartRangeMin<min){min=options.chartRangeMin;}
30
  if(options.chartRangeMax!=undefined&&options.chartRangeMax>max){max=options.chartRangeMax;}
31
+ if(options.zeroAxis==undefined)options.zeroAxis=min<0;var range=max-min==0?1:max-min;var target=$(this).simpledraw(width,height);if(target){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;var yzero=min<0&&options.zeroAxis?canvas_height-Math.round(canvas_height*(Math.abs(min)/range))-1:canvas_height-1;for(var i=0;i<values.length;i++){var x=i*(options.barWidth+options.barSpacing);var val=values[i];if(val===null){continue;}
32
+ var color=(val<0)?options.negBarColor:options.barColor;if(options.zeroAxis&&min<0){var height=Math.round(canvas_height*((Math.abs(val)/range)))+1;var y=(val<0)?yzero:yzero-height;}else{var height=Math.round(canvas_height*((val-min)/range))+1;var y=canvas_height-height;}
33
  if(val==0&&options.zeroColor!=undefined){color=options.zeroColor;}
34
+ if(options.colorMap[val]){color=options.colorMap[val];}
35
  target.drawRect(x,y,options.barWidth-1,height-1,color,color);}}else{this.innerHTML='';}};$.fn.sparkline.tristate=function(values,options,width,height){values=$.map(values,Number);var options=$.extend({barWidth:4,barSpacing:1,posBarColor:'#6f6',negBarColor:'#f44',zeroBarColor:'#999',colorMap:{}},options);var width=(values.length*options.barWidth)+((values.length-1)*options.barSpacing);var target=$(this).simpledraw(width,height);if(target){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;var half_height=Math.round(canvas_height/2);for(var i=0;i<values.length;i++){var x=i*(options.barWidth+options.barSpacing);if(values[i]<0){var y=half_height;var height=half_height-1;var color=options.negBarColor;}else if(values[i]>0){var y=0;var height=half_height-1;var color=options.posBarColor;}else{var y=half_height-1;var height=2;var color=options.zeroBarColor;}
36
  if(options.colorMap[values[i]]){color=options.colorMap[values[i]];}
37
  target.drawRect(x,y,options.barWidth-1,height-1,color,color);}}else{this.innerHTML='';}};$.fn.sparkline.discrete=function(values,options,width,height){values=$.map(values,Number);var options=$.extend({lineHeight:'auto',thresholdColor:undefined,thresholdValue:0,chartRangeMax:undefined,chartRangeMin:undefined},options);width=options.width=='auto'?values.length*2:width;var interval=Math.floor(width/values.length);var target=$(this).simpledraw(width,height);if(target){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;var line_height=options.lineHeight=='auto'?Math.round(canvas_height*0.3):options.lineHeight;var pheight=canvas_height-line_height;var min=Math.min.apply(Math,values);var max=Math.max.apply(Math,values);if(options.chartRangeMin!=undefined&&options.chartRangeMin<min){min=options.chartRangeMin;}
53
  return-1;}}
54
  if($.browser.msie&&!document.namespaces['v']){document.namespaces.add('v','urn:schemas-microsoft-com:vml','#default#VML');}
55
  if($.browser.hasCanvas==undefined){var t=document.createElement('canvas');$.browser.hasCanvas=t.getContext!=undefined;}
56
+ var vcanvas_base=function(width,height,target){};vcanvas_base.prototype={init:function(width,height,target){this.width=width;this.height=height;this.target=target;if(target[0])target=target[0];target.vcanvas=this;},drawShape:function(path,lineColor,fillColor,lineWidth){alert('drawShape not implemented');},drawLine:function(x1,y1,x2,y2,lineColor,lineWidth){return this.drawShape([[x1,y1],[x2,y2]],lineColor,lineWidth);},drawCircle:function(x,y,radius,lineColor,fillColor){alert('drawCircle not implemented');},drawPieSlice:function(x,y,radius,startAngle,endAngle,lineColor,fillColor){alert('drawPieSlice not implemented');},drawRect:function(x,y,width,height,lineColor,fillColor){alert('drawRect not implemented');},getElement:function(){return this.canvas;},_insert:function(el,target){$(target).html(el);}};var vcanvas_canvas=function(width,height,target){return this.init(width,height,target);};vcanvas_canvas.prototype=$.extend(new vcanvas_base,{_super:vcanvas_base.prototype,init:function(width,height,target){this._super.init(width,height,target);this.canvas=document.createElement('canvas');if(target[0])target=target[0];target.vcanvas=this;$(this.canvas).css({display:'inline-block',width:width,height:height,verticalAlign:'top'});this._insert(this.canvas,target);this.pixel_height=$(this.canvas).height();this.pixel_width=$(this.canvas).width();this.canvas.width=this.pixel_width;this.canvas.height=this.pixel_height;$(this.canvas).css({width:this.pixel_width,height:this.pixel_height});},_getContext:function(lineColor,fillColor,lineWidth){var context=this.canvas.getContext('2d');if(lineColor!=undefined)
57
+ context.strokeStyle=lineColor;context.lineWidth=lineWidth==undefined?1:lineWidth;if(fillColor!=undefined)
58
+ context.fillStyle=fillColor;return context;},drawShape:function(path,lineColor,fillColor,lineWidth){var context=this._getContext(lineColor,fillColor,lineWidth);context.beginPath();context.moveTo(path[0][0]+0.5,path[0][1]+0.5);for(var i=1;i<path.length;i++){context.lineTo(path[i][0]+0.5,path[i][1]+0.5);}
59
  if(lineColor!=undefined){context.stroke();}
60
  if(fillColor!=undefined){context.fill();}},drawCircle:function(x,y,radius,lineColor,fillColor){var context=this._getContext(lineColor,fillColor);context.beginPath();context.arc(x,y,radius,0,2*Math.PI,false);if(lineColor!=undefined){context.stroke();}
61
  if(fillColor!=undefined){context.fill();}},drawPieSlice:function(x,y,radius,startAngle,endAngle,lineColor,fillColor){var context=this._getContext(lineColor,fillColor);context.beginPath();context.moveTo(x,y);context.arc(x,y,radius,startAngle,endAngle,false);context.lineTo(x,y);context.closePath();if(lineColor!=undefined){context.stroke();}
62
  if(fillColor){context.fill();}},drawRect:function(x,y,width,height,lineColor,fillColor){return this.drawShape([[x,y],[x+width,y],[x+width,y+height],[x,y+height],[x,y]],lineColor,fillColor);}});var vcanvas_vml=function(width,height,target){return this.init(width,height,target);};vcanvas_vml.prototype=$.extend(new vcanvas_base,{_super:vcanvas_base.prototype,init:function(width,height,target){this._super.init(width,height,target);if(target[0])target=target[0];target.vcanvas=this;this.canvas=document.createElement('span');$(this.canvas).css({display:'inline-block',position:'relative',overflow:'hidden',width:width,height:height,margin:'0px',padding:'0px',verticalAlign:'top'});this._insert(this.canvas,target);this.pixel_height=$(this.canvas).height();this.pixel_width=$(this.canvas).width();this.canvas.width=this.pixel_width;this.canvas.height=this.pixel_height;;var groupel='<v:group coordorigin="0 0" coordsize="'+this.pixel_width+' '+this.pixel_height+'"'
63
+ +' style="position:absolute;top:0;left:0;width:'+this.pixel_width+'px;height='+this.pixel_height+'px;"></v:group>';this.canvas.insertAdjacentHTML('beforeEnd',groupel);this.group=$(this.canvas).children()[0];},drawShape:function(path,lineColor,fillColor,lineWidth){var vpath=[];for(var i=0;i<path.length;i++){vpath[i]=''+(path[i][0])+','+(path[i][1]);}
64
+ var initial=vpath.splice(0,1);lineWidth=lineWidth==undefined?1:lineWidth;var stroke=lineColor==undefined?' stroked="false" ':' strokeWeight="'+lineWidth+'" strokeColor="'+lineColor+'" ';var fill=fillColor==undefined?' filled="false"':' fillColor="'+fillColor+'" filled="true" ';var closed=vpath[0]==vpath[vpath.length-1]?'x ':'';var vel='<v:shape coordorigin="0 0" coordsize="'+this.pixel_width+' '+this.pixel_height+'" '
65
  +stroke
66
  +fill
67
  +' style="position:absolute;left:0px;top:0px;height:'+this.pixel_height+'px;width:'+this.pixel_width+'px;padding:0px;margin:0px;" '
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: http://ronaldheft.com/code/donate/
4
  Tags: stats, statistics, google, analytics, google analytics, tracking, widget
5
  Requires at least: 2.7
6
  Tested up to: 2.9
7
- Stable tag: 5.3.2
8
 
9
  Adds the necessary JavaScript code to enable Google Analytics. Includes widgets for Analytics data display.
10
 
@@ -12,14 +12,12 @@ Adds the necessary JavaScript code to enable Google Analytics. Includes widgets
12
 
13
  Google Analyticator adds the necessary JavaScript code to enable Google Analytics logging on any WordPress blog. This eliminates the need to edit your template code to begin logging. Google Analyticator also includes several widgets for displaying Analytics data in the admin and on your blog.
14
 
15
- *Google Analyticator is brought to you for free by [Spiral Web Consulting](http://spiralwebconsulting.com/). Spiral Web Consulting is a small web development firm specializing in PHP development. Visit our website to learn more, and don't hesitate to ask us to develop your next big WordPress plugin idea.*
16
-
17
  = Features =
18
 
19
  Google Analyticator Has the Following Features:
20
 
21
- - Supports standard Google Analytics tracking
22
- - **NEW!** Includes an admin dashboard widget that displays a graph of the last 30 days of visitors, a summary of site usage, the top pages, the top referrers, and the top searches
23
  - Includes a widget that can be used to display visitor stat information on the front-end
24
  - Supports outbound link tracking of all links on the page, including links not managed by WordPress
25
  - Supports download link tracking
@@ -27,19 +25,18 @@ Google Analyticator Has the Following Features:
27
  - Allows hiding of Administrator visits without affecting Google Analytics' site overlay feature
28
  - Supports any advanced tracking code Google provides
29
  - Installs easily - unlike other plugins, the user doesn't even have to know their Analytics UID
30
- - Allows tracking code to be placed in the footer to ensure faster load times
31
  - Provides complete control over options; disable any feature if needed
32
- - **NEW!** Supports localization - get the settings page in your language of choice
33
 
34
- For more information, visit the [Google Analyticator plugin page](http://plugins.spiralwebconsulting.com/analyticator.html).
35
 
36
  == Installation ==
37
 
38
- Please visit [Spiral Web Consulting's forum](http://plugins.spiralwebconsulting.com/forums/viewtopic.php?f=5&t=17) for installation information.
39
 
40
  == Frequently Asked Questions ==
41
 
42
- Please visit [Spiral Web Consulting's forum](http://plugins.spiralwebconsulting.com/forums/viewforum.php?f=5) for the latest FAQ information.
43
 
44
  == Screenshots ==
45
 
@@ -52,6 +49,18 @@ Please visit [Spiral Web Consulting's forum](http://plugins.spiralwebconsulting.
52
 
53
  == Changelog ==
54
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  = 5.3.2 =
56
  * Prepares Google Analyticator for WordPress 2.9 compatibility.
57
 
4
  Tags: stats, statistics, google, analytics, google analytics, tracking, widget
5
  Requires at least: 2.7
6
  Tested up to: 2.9
7
+ Stable tag: 6.0
8
 
9
  Adds the necessary JavaScript code to enable Google Analytics. Includes widgets for Analytics data display.
10
 
12
 
13
  Google Analyticator adds the necessary JavaScript code to enable Google Analytics logging on any WordPress blog. This eliminates the need to edit your template code to begin logging. Google Analyticator also includes several widgets for displaying Analytics data in the admin and on your blog.
14
 
 
 
15
  = Features =
16
 
17
  Google Analyticator Has the Following Features:
18
 
19
+ - **NEW!** Supports standard Google Analytics tracking via the latest async tracking methods (faster and more reliable than the older ga.js tracking method)
20
+ - Includes an admin dashboard widget that displays a graph of the last 30 days of visitors, a summary of site usage, the top pages, the top referrers, and the top searches
21
  - Includes a widget that can be used to display visitor stat information on the front-end
22
  - Supports outbound link tracking of all links on the page, including links not managed by WordPress
23
  - Supports download link tracking
25
  - Allows hiding of Administrator visits without affecting Google Analytics' site overlay feature
26
  - Supports any advanced tracking code Google provides
27
  - Installs easily - unlike other plugins, the user doesn't even have to know their Analytics UID
 
28
  - Provides complete control over options; disable any feature if needed
29
+ - Supports localization - get the settings page in your language of choice
30
 
31
+ For more information, visit the [Google Analyticator plugin page](http://ronaldheft.com/code/analyticator/).
32
 
33
  == Installation ==
34
 
35
+ Please visit [Google Analyticator's support forum](http://forums.ronaldheft.com/viewtopic.php?f=5&t=17) for installation information.
36
 
37
  == Frequently Asked Questions ==
38
 
39
+ Please visit [Google Analyticator's support forum](http://forums.ronaldheft.com/viewforum.php?f=5) for the latest FAQ information.
40
 
41
  == Screenshots ==
42
 
49
 
50
  == Changelog ==
51
 
52
+ = 6.0 =
53
+ * Switches current tracking script (ga.js) to the new awesome async tracking script. In laymen's terms: updates to the latest tracking code, the tracking script will load faster, and tracking will be more reliable. If you use custom tracking code, be sure to migrate that code to the new async tracking methods.
54
+ * Removes settings made obsolete due to the new async tracking (footer tracking and http/https).
55
+ * Fixes the (not set) pages in the Top Pages section of the dashboard widget. Pages containing the title (not set) will be combined with the correct page and corresponding title. Note that I am still trying to get this bug fixed in the Google Analytics API; this is just a hold over until the bug is fixed.
56
+ * Adds a link to Google Analytics on the dashboard widget for quick access to view full stat reports.
57
+ * Fixes a Javascript error that prevented the dashboard widget from collapsing.
58
+ * Corrects a uid undefined error message that appeared if error reporting was set too high.
59
+ * Updates the included jQuery sparklines plugin to the latest version, 1.4.3.
60
+ * Adds an experimental function to retrieve page visitors stats for theme developers. This function is not final and only provided for advanced users who know what they're doing. Future versions will improve on the code already in place. Find the get_analytics_visits_by_page in google-analyticator.php to learn how to use. Use at your own risk.
61
+ * Fixes several security flaws identified during a recent security audit of Google Analyticator.
62
+ * Removes references to Spiral Web Consulting. Google Analyticator is now being developed exclusively by Ronald Heft.
63
+
64
  = 5.3.2 =
65
  * Prepares Google Analyticator for WordPress 2.9 compatibility.
66