Slimstat Analytics - Version 4.7.8.2

Version Description

  • [New] The IP to hostname conversion feature now stores in the database the information it calculates, to avoid querying the DNS server over and over again.
  • [Update] The opt-out banner is now loaded dynamically, to address HTML caching issues. Thank you, fuchsws.
Download this release

Release Info

Developer coolmann
Plugin Icon 128x128 Slimstat Analytics
Version 4.7.8.2
Comparing to
See all releases

Code changes from version 4.7.8.1 to 4.7.8.2

admin/config/index.php CHANGED
@@ -108,7 +108,7 @@ $settings = array(
108
  'title' => __( 'Tracker', 'wp-slimstat' ),
109
  'rows' => array(
110
  'privacy_header' => array( 'description' => __( 'Privacy and Data Protection', 'wp-slimstat' ), 'type' => 'section_header' ),
111
- 'anonymize_ip' => array( 'description' => __( 'Enable Privacy Mode', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "Mask your visitors' IP addresses to comply with European Privacy Laws.", 'wp-slimstat' ) ),
112
  'honor_dnt_header' => array( 'description' => __( 'DNT Header', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "The <a href='https://en.wikipedia.org/wiki/Do_Not_Track' target='_blank'>Do Not Track (DNT)</a> header is the proposed HTTP header field DNT that requests that a web application disable either its tracking or cross-site user tracking (the ambiguity remains unresolved) of an individual user. You can decide to ignore this header and track any pageview regardless of the headers sent by the browser.", 'wp-slimstat' ) ),
113
  'set_tracker_cookie' => array( 'description' => __( 'Set Cookie', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Disable this option if, for legal or security reasons, you do not want Slimstat to assign a <a href="https://en.wikipedia.org/wiki/HTTP_cookie" target="_blank">cookie</a> to your visitors. Please note that, by deactivating this feature, Slimstat will not keep track of returning visitors and sessions.', 'wp-slimstat' ) ),
114
  'display_opt_out' => array( 'description' => __( 'Allow Opt-out', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "The European <a href='https://en.wikipedia.org/wiki/General_Data_Protection_Regulation' target='_blank'>General Data Protection Regulation (GDPR)</a> requires website owners to provide a way for their visitors to opt-out of tracking. If enabled, the message here below will be displayed to all users who don't have the corresponding cookie set. A notice will be recorded under Settings > Maintenance every time a pageview is ignored because the corresponding visitor has opted out of tracking.", 'wp-slimstat' ) ),
108
  'title' => __( 'Tracker', 'wp-slimstat' ),
109
  'rows' => array(
110
  'privacy_header' => array( 'description' => __( 'Privacy and Data Protection', 'wp-slimstat' ), 'type' => 'section_header' ),
111
+ 'anonymize_ip' => array( 'description' => __( 'Enable Privacy Mode', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "Mask your visitors' IP addresses to comply with European Privacy Laws. This feature will turn the final part of each IP address into a ZERO. Based on our understanding of the various privacy guidelines, this is enough to comply with the existing regulations.", 'wp-slimstat' ) ),
112
  'honor_dnt_header' => array( 'description' => __( 'DNT Header', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "The <a href='https://en.wikipedia.org/wiki/Do_Not_Track' target='_blank'>Do Not Track (DNT)</a> header is the proposed HTTP header field DNT that requests that a web application disable either its tracking or cross-site user tracking (the ambiguity remains unresolved) of an individual user. You can decide to ignore this header and track any pageview regardless of the headers sent by the browser.", 'wp-slimstat' ) ),
113
  'set_tracker_cookie' => array( 'description' => __( 'Set Cookie', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Disable this option if, for legal or security reasons, you do not want Slimstat to assign a <a href="https://en.wikipedia.org/wiki/HTTP_cookie" target="_blank">cookie</a> to your visitors. Please note that, by deactivating this feature, Slimstat will not keep track of returning visitors and sessions.', 'wp-slimstat' ) ),
114
  'display_opt_out' => array( 'description' => __( 'Allow Opt-out', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "The European <a href='https://en.wikipedia.org/wiki/General_Data_Protection_Regulation' target='_blank'>General Data Protection Regulation (GDPR)</a> requires website owners to provide a way for their visitors to opt-out of tracking. If enabled, the message here below will be displayed to all users who don't have the corresponding cookie set. A notice will be recorded under Settings > Maintenance every time a pageview is ignored because the corresponding visitor has opted out of tracking.", 'wp-slimstat' ) ),
admin/css/slimstat.frontend.css CHANGED
@@ -1,21 +1,24 @@
1
- [id*=slim_p].postbox {
2
- box-sizing: border-box;
3
- margin-bottom: 2em;
4
- width: 100%;
5
- }
6
- [id*=slim_p].postbox h3 {
7
- display: none;
8
- }
9
- [id*=slim_p].postbox .inside {
10
- height: 20em;
11
- overflow: auto;
12
- }
13
- [id*=slim_p].postbox p {
14
- border-bottom: 1px solid #ccc;
15
- padding: 5px 10px;
16
- margin: 0;
17
- }
18
- [id*=slim_p].postbox p span {
19
- float: right;
20
- margin-left: 0.5em;
 
 
 
21
  }
1
+ [id*=slim_p].postbox {
2
+ box-sizing: border-box;
3
+ margin-bottom: 2em;
4
+ width: 100%;
5
+ }
6
+ [id*=slim_p].postbox h3 {
7
+ display: none;
8
+ }
9
+ [id*=slim_p].postbox .inside {
10
+ height: 20em;
11
+ overflow: auto;
12
+ }
13
+ [id*=slim_p].postbox p {
14
+ border-bottom: 1px solid #ccc;
15
+ padding: 5px 10px;
16
+ margin: 0;
17
+ }
18
+ [id*=slim_p].postbox p span {
19
+ float: right;
20
+ margin-left: 0.5em;
21
+ }
22
+ [id*=slim_p].postbox p .slimstat-tooltip-content {
23
+ display: none;
24
  }
admin/view/right-now.php CHANGED
@@ -11,11 +11,11 @@ if ( wp_slimstat::$settings[ 'async_load' ] == 'on' && ( !defined( 'DOING_AJAX'
11
  $is_dashboard = empty( $_REQUEST[ 'page' ] ) || $_REQUEST[ 'page' ] != 'slimview1';
12
 
13
  // Available icons
14
- $supported_browser_icons = array('Android','Anonymouse','Baiduspider','BlackBerry','BingBot','CFNetwork','Chrome','Chromium','Default Browser','Edge','Exabot/BiggerBetter','FacebookExternalHit','FeedBurner','Feedfetcher-Google','Firefox','Internet Archive','Googlebot','Google Bot','Google Feedfetcher','Google Web Preview','IE','IEMobile','iPad','iPhone','iPod Touch','Maxthon','Mediapartners-Google','Microsoft-WebDAV','msnbot','Mozilla','NewsGatorOnline','Netscape','Nokia','Opera','Opera Mini','Opera Mobi','Pingdom','Python','PycURL','Safari','W3C_Validator','WordPress','Yahoo! Slurp','YandexBot');
15
- $supported_os_icons = array('android','blackberry os','cellos','chromeos','ios','iphone osx','java','linux','macosx','rim os','symbianos','win7','win8','win8.1','win10','winphone7','winphone7.5','winphone8','winphone8.1','winvista','winxp','unknown');
16
- $supported_browser_types = array(__('Human','wp-slimstat'),__('Bot/Crawler','wp-slimstat'),__('Mobile Device','wp-slimstat'),__('Syndication Reader','wp-slimstat'));
17
 
18
- $plugin_url = plugins_url('', dirname(__FILE__));
19
 
20
  // Get the data
21
  wp_slimstat_db::$debug_message = '';
@@ -35,12 +35,31 @@ echo wp_slimstat_db::$debug_message;
35
  // Return the results if we are not echoing them (export, email, etc)
36
  if ( isset( $_args[ 'echo' ] ) && $_args[ 'echo' ] === false ) {
37
 
38
- // Massage the data before returning it
39
  if ( wp_slimstat::$settings[ 'convert_ip_addresses' ] == 'on' ) {
40
- for ( $i = 0; $i < $count_page_results; $i++ ) {
41
- $gethostbyaddr = gethostbyaddr( $results[ $i ][ 'ip' ] );
42
- if ( $gethostbyaddr != $host_by_ip && !empty( $gethostbyaddr ) ) {
43
- $results[ $i ][ 'ip' ] .= ', ' . $gethostbyaddr;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  }
45
  }
46
  }
@@ -48,8 +67,8 @@ if ( isset( $_args[ 'echo' ] ) && $_args[ 'echo' ] === false ) {
48
  return $results;
49
  }
50
 
51
- if ($count_page_results == 0){
52
- echo '<p class="nodata">'.__('No data to display','wp-slimstat').'</p>';
53
  return 0;
54
  }
55
 
@@ -63,10 +82,30 @@ $delete_row = '';
63
  // Loop through the results
64
  for ( $i=0; $i < $count_page_results; $i++ ) {
65
  $host_by_ip = $results[ $i ][ 'ip' ];
 
66
  if ( wp_slimstat::$settings[ 'convert_ip_addresses' ] == 'on' ) {
67
- $gethostbyaddr = gethostbyaddr( $results[ $i ][ 'ip' ] );
68
- if ( $gethostbyaddr != $host_by_ip && !empty( $gethostbyaddr ) ) {
69
- $host_by_ip .= ', ' . $gethostbyaddr;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  }
71
  }
72
 
11
  $is_dashboard = empty( $_REQUEST[ 'page' ] ) || $_REQUEST[ 'page' ] != 'slimview1';
12
 
13
  // Available icons
14
+ $supported_browser_icons = array( 'Android', 'Anonymouse', 'Baiduspider', 'BlackBerry', 'BingBot', 'CFNetwork', 'Chrome', 'Chromium', 'Default Browser', 'Edge', 'Exabot/BiggerBetter', 'FacebookExternalHit', 'FeedBurner', 'Feedfetcher-Google', 'Firefox', 'Internet Archive', 'Googlebot', 'Google Bot', 'Google Feedfetcher', 'Google Web Preview', 'IE', 'IEMobile', 'iPad', 'iPhone', 'iPod Touch', 'Maxthon', 'Mediapartners-Google', 'Microsoft-WebDAV', 'msnbot', 'Mozilla', 'NewsGatorOnline', 'Netscape', 'Nokia', 'Opera', 'Opera Mini', 'Opera Mobi', 'Pingdom', 'Python', 'PycURL', 'Safari', 'W3C_Validator', 'WordPress', 'Yahoo! Slurp', 'YandexBot' );
15
+ $supported_os_icons = array( 'android',' blackberry os', 'cellos', 'chromeos', 'ios', 'iphone osx', 'java', 'linux', 'macosx', 'rim os', 'symbianos', 'win7', 'win8', 'win8.1', 'win10', 'winphone7', 'winphone7.5', 'winphone8', 'winphone8.1', 'winvista', 'winxp', 'unknown' );
16
+ $supported_browser_types = array( __( 'Human', 'wp-slimstat' ), __( 'Bot/Crawler', 'wp-slimstat' ), __( 'Mobile Device', 'wp-slimstat' ), __( 'Syndication Reader', 'wp-slimstat' ) );
17
 
18
+ $plugin_url = plugins_url( '', dirname( __FILE__ ) );
19
 
20
  // Get the data
21
  wp_slimstat_db::$debug_message = '';
35
  // Return the results if we are not echoing them (export, email, etc)
36
  if ( isset( $_args[ 'echo' ] ) && $_args[ 'echo' ] === false ) {
37
 
38
+ // Process the data before returning it
39
  if ( wp_slimstat::$settings[ 'convert_ip_addresses' ] == 'on' ) {
40
+ for ( $i=0; $i < $count_page_results; $i++ ) {
41
+ // When the IP conversion feature is enabled, data is stored in the "notes" field, so that it doesn't need to be calculated over and over again
42
+ $gethostbyaddr = '';
43
+ if ( strpos( $results[ $i ][ 'notes' ], 'hostbyaddr:' ) === false ) {
44
+ $gethostbyaddr = gethostbyaddr( $results[ $i ][ 'ip' ] );
45
+ if ( $gethostbyaddr != $results[ $i ][ 'ip' ] && !empty( $gethostbyaddr ) ) {
46
+ wp_slimstat::$wpdb->query( wp_slimstat::$wpdb->prepare( "
47
+ UPDATE {$GLOBALS['wpdb']->prefix}slim_stats
48
+ SET notes = %s
49
+ WHERE id = %s", ( empty( $results[ $i ][ 'notes' ] ) ? '' : $results[ $i ][ 'notes' ] . ';' ) . "hostbyaddr:$gethostbyaddr", $results[ $i ][ 'id' ]
50
+ ) );
51
+
52
+ $results[ $i ][ 'ip' ] .= ', ' . $gethostbyaddr;
53
+ }
54
+ }
55
+ else {
56
+ $gethostbyaddr = substr( $results[ $i ][ 'notes' ], strpos( $results[ $i ][ 'notes' ], 'hostbyaddr:' ) + 11 );
57
+
58
+ $length = strpos( $gethostbyaddr, ';' );
59
+ if ( $length == 0 ) {
60
+ $length = strlen( $gethostbyaddr );
61
+ }
62
+ $results[ $i ][ 'ip' ] .= ', ' . substr( $gethostbyaddr, 0, $length );
63
  }
64
  }
65
  }
67
  return $results;
68
  }
69
 
70
+ if ( $count_page_results == 0 ) {
71
+ echo '<p class="nodata">' . __( 'No data to display', 'wp-slimstat' ) . '</p>';
72
  return 0;
73
  }
74
 
82
  // Loop through the results
83
  for ( $i=0; $i < $count_page_results; $i++ ) {
84
  $host_by_ip = $results[ $i ][ 'ip' ];
85
+
86
  if ( wp_slimstat::$settings[ 'convert_ip_addresses' ] == 'on' ) {
87
+ // When the IP conversion feature is enabled, data is stored in the "notes" field, so that it doesn't need to be calculated over and over again
88
+ $gethostbyaddr = '';
89
+ if ( strpos( $results[ $i ][ 'notes' ], 'hostbyaddr:' ) === false ) {
90
+ $gethostbyaddr = gethostbyaddr( $results[ $i ][ 'ip' ] );
91
+ if ( $gethostbyaddr != $results[ $i ][ 'ip' ] && !empty( $gethostbyaddr ) ) {
92
+ wp_slimstat::$wpdb->query( wp_slimstat::$wpdb->prepare( "
93
+ UPDATE {$GLOBALS['wpdb']->prefix}slim_stats
94
+ SET notes = %s
95
+ WHERE id = %s", ( empty( $results[ $i ][ 'notes' ] ) ? '' : $results[ $i ][ 'notes' ] . ';' ) . "hostbyaddr:$gethostbyaddr", $results[ $i ][ 'id' ]
96
+ ) );
97
+
98
+ $host_by_ip .= ', ' . $gethostbyaddr;
99
+ }
100
+ }
101
+ else {
102
+ $gethostbyaddr = substr( $results[ $i ][ 'notes' ], strpos( $results[ $i ][ 'notes' ], 'hostbyaddr:' ) + 11 );
103
+
104
+ $length = strpos( $gethostbyaddr, ';' );
105
+ if ( $length == 0 ) {
106
+ $length = strlen( $gethostbyaddr );
107
+ }
108
+ $host_by_ip .= ', ' . substr( $gethostbyaddr, 0, $length );
109
  }
110
  }
111
 
admin/wp-slimstat-admin.php CHANGED
@@ -407,6 +407,12 @@ class wp_slimstat_admin {
407
  }
408
  // --- END: Updates for version 4.7.8 ---
409
 
 
 
 
 
 
 
410
  // Now we can update the version stored in the database
411
  wp_slimstat::$settings[ 'version' ] = wp_slimstat::$version;
412
 
407
  }
408
  // --- END: Updates for version 4.7.8 ---
409
 
410
+ // --- Updates for version 4.7.8.2 ---
411
+ if ( version_compare( wp_slimstat::$settings[ 'version' ], '4.7.8.2', '<' ) ) {
412
+ wp_slimstat::$settings[ 'opt_out_message' ] = '<p style="display:block;position:fixed;left:0;bottom:0;margin:0;padding:1em 2em;background-color:#eee;width:100%;z-index:99999;">This website stores cookies on your computer. These cookies are used to provide a more personalized experience and to track your whereabouts around our website in compliance with the European General Data Protection Regulation. If you decide to to opt-out of any future tracking, a cookie will be setup in your browser to remember this choice for one year.<br><br><a href="#" onclick="javascript:SlimStat.optout(event, false);">Accept</a> or <a href="#" onclick="javascript:SlimStat.optout(event, true);">Deny</a></p>';
413
+ }
414
+ // --- END: Updates for version 4.7.8.2 ---
415
+
416
  // Now we can update the version stored in the database
417
  wp_slimstat::$settings[ 'version' ] = wp_slimstat::$version;
418
 
readme.txt CHANGED
@@ -6,7 +6,7 @@ Text Domain: wp-slimstat
6
  Requires at least: 3.8
7
  Requires PHP: 5.2
8
  Tested up to: 4.9
9
- Stable tag: 4.7.8.1
10
 
11
  == Description ==
12
  The leading web analytics plugin for WordPress. Track returning customers and registered users, monitor Javascript events, detect intrusions, analyze email campaigns. Thousands of WordPress sites are already using it.
@@ -78,6 +78,10 @@ Our knowledge base is available on our [support center](http://docs.wp-slimstat.
78
  5. **Responsive layout** - Keep an eye on your reports on the go
79
 
80
  == Changelog ==
 
 
 
 
81
  = 4.7.8.1 =
82
  * [New] The Customizer now has its own access control settings. This allows admins to control in a more granular way who can do what.
83
  * [Update] If you have an existing opt-in mechanism, asking your users if they want to be tracked, you can now configure Slimstat to use that cookie to determine if a given pageview should be recorded or not.
6
  Requires at least: 3.8
7
  Requires PHP: 5.2
8
  Tested up to: 4.9
9
+ Stable tag: 4.7.8.2
10
 
11
  == Description ==
12
  The leading web analytics plugin for WordPress. Track returning customers and registered users, monitor Javascript events, detect intrusions, analyze email campaigns. Thousands of WordPress sites are already using it.
78
  5. **Responsive layout** - Keep an eye on your reports on the go
79
 
80
  == Changelog ==
81
+ = 4.7.8.2 =
82
+ * [New] The IP to hostname conversion feature now stores in the database the information it calculates, to avoid querying the DNS server over and over again.
83
+ * [Update] The opt-out banner is now loaded dynamically, to address HTML caching issues. Thank you, [fuchsws](https://wordpress.org/support/topic/opt-out-message-vs-html-cache).
84
+
85
  = 4.7.8.1 =
86
  * [New] The Customizer now has its own access control settings. This allows admins to control in a more granular way who can do what.
87
  * [Update] If you have an existing opt-in mechanism, asking your users if they want to be tracked, you can now configure Slimstat to use that cookie to determine if a given pageview should be recorded or not.
wp-slimstat.js CHANGED
@@ -160,6 +160,48 @@ var SlimStat = {
160
  return slim_performance.timing.responseEnd - slim_performance.timing.connectEnd;
161
  },
162
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  add_event : function( obj, type, fn ) {
164
  if ( obj && obj.addEventListener ) {
165
  obj.addEventListener( type, fn, false );
@@ -192,6 +234,15 @@ var SlimStat = {
192
  return false;
193
  },
194
 
 
 
 
 
 
 
 
 
 
195
  send_to_server : function( data, use_beacon ) {
196
  if ( "undefined" == typeof SlimStatParams.ajaxurl || "undefined" == typeof data ) {
197
  return false;
@@ -445,7 +496,8 @@ SlimStat.add_event( window, "load", function() {
445
  // Attach an event tracker to all the links on the page that satisfy the criteria set by the admin
446
  SlimStat.attach_tracker();
447
 
448
- //
 
449
  } );
450
 
451
  var slimstat_data = "";
160
  return slim_performance.timing.responseEnd - slim_performance.timing.connectEnd;
161
  },
162
 
163
+ optout: function( event, cookie_value ) {
164
+ event.preventDefault();
165
+
166
+ expiration = new Date();
167
+ expiration.setTime( expiration.getTime() + 31536000000 );
168
+ document.cookie = "slimstat_optout_tracking=" + cookie_value + ";expires=" + expiration.toGMTString();
169
+
170
+ event.target.parentNode.parentNode.removeChild( event.target.parentNode );
171
+ },
172
+
173
+ show_optout_message : function() {
174
+ var opt_out_cookies = ( "undefined" != typeof SlimStatParams.opt_out_cookies && SlimStatParams.opt_out_cookies ) ? SlimStatParams.opt_out_cookies.split( ',' ) : [];
175
+
176
+ var show_optout = true;
177
+ for ( var i = 0; i < opt_out_cookies.length; i++ ) {
178
+ if ( SlimStat.get_cookie( opt_out_cookies[ i ] ) != "" ) {
179
+ show_optout = false;
180
+ }
181
+ }
182
+
183
+ if ( show_optout ) {
184
+ // Retrieve the message from the server
185
+ xhr = new XMLHttpRequest();
186
+
187
+ if ( xhr ) {
188
+ xhr.open( "POST", SlimStatParams.ajaxurl, true );
189
+ xhr.setRequestHeader( "Content-type", "application/x-www-form-urlencoded" );
190
+ xhr.setRequestHeader( "X-Requested-With", "XMLHttpRequest" );
191
+ xhr.withCredentials = true;
192
+ xhr.send( "action=slimstat_optout_html" );
193
+
194
+ xhr.onreadystatechange = function() {
195
+ if ( 4 == xhr.readyState ) {
196
+ document.body.insertAdjacentHTML( 'beforeend', xhr.responseText );
197
+ }
198
+ }
199
+
200
+ return true;
201
+ }
202
+ }
203
+ },
204
+
205
  add_event : function( obj, type, fn ) {
206
  if ( obj && obj.addEventListener ) {
207
  obj.addEventListener( type, fn, false );
234
  return false;
235
  },
236
 
237
+ get_cookie : function( name ) {
238
+ var value = "; " + document.cookie;
239
+ var parts = value.split( "; " + name + "=" );
240
+ if ( parts.length == 2 ) {
241
+ return parts.pop().split( ";" ).shift();
242
+ }
243
+ return "";
244
+ },
245
+
246
  send_to_server : function( data, use_beacon ) {
247
  if ( "undefined" == typeof SlimStatParams.ajaxurl || "undefined" == typeof data ) {
248
  return false;
496
  // Attach an event tracker to all the links on the page that satisfy the criteria set by the admin
497
  SlimStat.attach_tracker();
498
 
499
+ // GDPR: display the Opt-Out box, if needed
500
+ SlimStat.show_optout_message();
501
  } );
502
 
503
  var slimstat_data = "";
wp-slimstat.min.js CHANGED
@@ -1 +1 @@
1
- var SlimStat={_id:void 0!==SlimStatParams.id?SlimStatParams.id:"-1.0",_base64_key_str:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",_plugins:{acrobat:{substrings:["Adobe","Acrobat"],active_x_strings:["AcroPDF.PDF","PDF.PDFCtrl.5"]},pdfviewer:{substrings:["PDF"],active_x_strings:["AcroPDF.PDF"]},flash:{substrings:["Shockwave","Flash"],active_x_strings:["ShockwaveFlash.ShockwaveFlash"]},mediaplayer:{substrings:["Windows Media"],active_x_strings:["WMPlayer.OCX"]},quicktime:{substrings:["QuickTime"],active_x_strings:["QuickTime.QuickTime"]},silverlight:{substrings:["Silverlight"],active_x_strings:["AgControl.AgControl"]}},_utf8_encode:function(e){var t,n,i="";for(e=e.replace(/\r\n/g,"\n"),t=0;t<e.length;t++)(n=e.charCodeAt(t))<128?i+=String.fromCharCode(n):n>127&&n<2048?(i+=String.fromCharCode(n>>6|192),i+=String.fromCharCode(63&n|128)):(i+=String.fromCharCode(n>>12|224),i+=String.fromCharCode(n>>6&63|128),i+=String.fromCharCode(63&n|128));return i},_base64_encode:function(e){var t,n,i,r,a,o,s,l="",d=0;for(e=SlimStat._utf8_encode(e);d<e.length;)r=(t=e.charCodeAt(d++))>>2,a=(3&t)<<4|(n=e.charCodeAt(d++))>>4,o=(15&n)<<2|(i=e.charCodeAt(d++))>>6,s=63&i,isNaN(n)?o=s=64:isNaN(i)&&(s=64),l=l+SlimStat._base64_key_str.charAt(r)+SlimStat._base64_key_str.charAt(a)+SlimStat._base64_key_str.charAt(o)+SlimStat._base64_key_str.charAt(s);return l},_detect_single_plugin_not_ie:function(e){var t,n,i,r;for(i in navigator.plugins){for(r in t=""+navigator.plugins[i].name+navigator.plugins[i].description,n=0,SlimStat._plugins[e].substrings)-1!=t.indexOf(SlimStat._plugins[e].substrings[r])&&n++;if(n==SlimStat._plugins[e].substrings.length)return!0}return!1},_detect_single_plugin_ie:function(e){var t="",n=!1;for(t in SlimStat._plugins[e].active_x_strings)try{new ActiveXObject(SlimStat._plugins[e].active_x_strings[t]),n=!0}catch(e){}return n},_detect_single_plugin:function(e){return navigator.plugins.length?this.detect=SlimStat._detect_single_plugin_not_ie:this.detect=SlimStat._detect_single_plugin_ie,this.detect(e)},detect_plugins:function(){var e,t=[];for(e in SlimStat._plugins)SlimStat._detect_single_plugin(e)&&t.push(e);return"function"==typeof navigator.javaEnabled&&navigator.javaEnabled()&&t.push("java"),t.join(",")},get_page_performance:function(){return slim_performance=window.performance||window.mozPerformance||window.msPerformance||window.webkitPerformance||{},void 0===slim_performance.timing?0:slim_performance.timing.loadEventEnd-slim_performance.timing.responseEnd},get_server_latency:function(){return slim_performance=window.performance||window.mozPerformance||window.msPerformance||window.webkitPerformance||{},void 0===slim_performance.timing?0:slim_performance.timing.responseEnd-slim_performance.timing.connectEnd},add_event:function(e,t,n){e&&e.addEventListener?e.addEventListener(t,n,!1):e&&e.attachEvent?(e["e"+t+n]=n,e[t+n]=function(){e["e"+t+n](window.event)},e.attachEvent("on"+t,e[t+n])):e["on"+t]=e["e"+t+n]},in_array:function(e,t){for(var n=0;n<t.length;n++)if(t[n].trim()==e)return!0;return!1},in_array_substring:function(e,t){for(var n=0;n<t.length;n++)if(-1!=e.indexOf(t[n].trim()))return!0;return!1},send_to_server:function(e,t){if(void 0===SlimStatParams.ajaxurl||void 0===e)return!1;if(void 0===t&&(t=!0),slimstat_data_with_client_info=e+"&sw="+screen.width+"&sh="+screen.height+"&bw="+window.innerWidth+"&bh="+window.innerHeight+"&sl="+SlimStat.get_server_latency()+"&pp="+SlimStat.get_page_performance()+"&pl="+SlimStat.detect_plugins(),t&&navigator.sendBeacon)navigator.sendBeacon(SlimStatParams.ajaxurl,slimstat_data_with_client_info);else{try{window.XMLHttpRequest?request=new XMLHttpRequest:window.ActiveXObject&&(request=new ActiveXObject("Microsoft.XMLHTTP"))}catch(e){return!1}if(request)return request.open("POST",SlimStatParams.ajaxurl,!0),request.setRequestHeader("Content-type","application/x-www-form-urlencoded"),request.setRequestHeader("X-Requested-With","XMLHttpRequest"),request.withCredentials=!0,request.send(slimstat_data_with_client_info),request.onreadystatechange=function(){4==request.readyState&&(parsed_id=parseInt(request.responseText),!isNaN(parsed_id)&&parsed_id>0&&(SlimStat._id=request.responseText))},!0}return!1},ss_track:function(e,t,n,i){if(e=e||window.event,t=void 0===t?0:parseInt(t),note_array=[],void 0===i&&(i=!0),parsed_id=parseInt(SlimStat._id),isNaN(parsed_id)||parsed_id<=0)return!1;if(node=void 0!==e.target?e.target:void 0!==e.srcElement&&e.srcElement,!node)return!1;switch(3==node.nodeType&&(node=node.parentNode),parent_node=node.parentNode,resource_url="",node.nodeName){case"FORM":void 0!==node.action&&node.action&&(resource_url=node.action);break;case"INPUT":for(;"undefined"!=typeof parent_node&&"FORM"!=parent_node.nodeName&&"BODY"!=parent_node.nodeName;)parent_node=parent_node.parentNode;if(void 0!==parent_node.action&&parent_node.action){resource_url=parent_node.action;break}default:if("A"!=node.nodeName)for(;void 0!==node.parentNode&&null!=node.parentNode&&"A"!=node.nodeName&&"BODY"!=node.nodeName;)node=node.parentNode;void 0!==node.hash&&node.hash&&node.hostname==location.hostname?resource_url=node.hash:void 0!==node.href&&-1==node.href.indexOf("javascript:")&&(resource_url=node.href),"function"==typeof node.getAttribute&&(void 0!==node.getAttribute("title")&&node.getAttribute("title")&&note_array.push("Title:"+node.getAttribute("title")),void 0!==node.getAttribute("id")&&node.getAttribute("id")&&note_array.push("ID:"+node.getAttribute("id")))}return pos_x=-1,pos_y=-1,position="",void 0!==e.pageX&&void 0!==e.pageY?(pos_x=e.pageX,pos_y=e.pageY):void 0!==e.clientX&&void 0!==e.clientY&&void 0!==document.body.scrollLeft&&void 0!==document.documentElement.scrollLeft&&void 0!==document.body.scrollTop&&void 0!==document.documentElement.scrollTop&&(pos_x=e.clientX+document.body.scrollLeft+document.documentElement.scrollLeft,pos_y=e.clientY+document.body.scrollTop+document.documentElement.scrollTop),pos_x>0&&pos_y>0&&(position=pos_x+","+pos_y),void 0!==e.type&&(event_description=e.type,"keypress"==e.type?event_description+="; keypress:"+String.fromCharCode(parseInt(e.which)):"click"==e.type&&(event_description+="; which:"+e.which)),void 0!==n&&n&&note_array.push(n),note_string=SlimStat._base64_encode(note_array.join(", ")),requested_op="add",1==t?resource_url=resource_url.substring(resource_url.indexOf(location.hostname)+location.hostname.length):requested_op=0==t||2==t?"update":"event",SlimStat.send_to_server("action=slimtrack&op="+requested_op+"&id="+SlimStat._id+"&ty="+t+"&ref="+SlimStat._base64_encode(document.referrer)+"&res="+SlimStat._base64_encode(resource_url)+"&pos="+position+"&des="+SlimStat._base64_encode(event_description)+"&no="+note_string,i),!0},attach_tracker:function(){all_links=document.getElementsByTagName("a");for(var e=void 0!==SlimStatParams.extensions_to_track&&SlimStatParams.extensions_to_track?SlimStatParams.extensions_to_track.split(","):[],t=void 0!==SlimStatParams.outbound_classes_rel_href_to_not_track&&SlimStatParams.outbound_classes_rel_href_to_not_track?SlimStatParams.outbound_classes_rel_href_to_not_track.split(","):[],n=0;n<all_links.length;n++){if(linktype=all_links[n].href&&(all_links[n].hostname==location.hostname||-1==all_links[n].href.indexOf("://"))||-1==all_links[n].href.indexOf("javascript:")?2:0,tracking=1,t.length>0){if(1==tracking){classes_current_link=void 0!==all_links[n].className&&all_links[n].className?all_links[n].className.split(" "):[];for(var i=0;i<classes_current_link.length;i++)if(SlimStat.in_array_substring(classes_current_link[i],t)){tracking=0;break}}1==tracking&&void 0!==all_links[n].attributes.rel&&all_links[n].attributes.rel.value&&SlimStat.in_array_substring(all_links[n].attributes.rel.value,t)&&(tracking=0),1==tracking&&void 0!==all_links[n].href&&all_links[n].href&&SlimStat.in_array_substring(all_links[n].href,t)&&(tracking=0)}extension_current_link=all_links[n].pathname.split(/[?#]/)[0].split(".").pop().replace(/[\/\-]/g,""),2==linktype&&e.length>0&&SlimStat.in_array(extension_current_link,e)&&(tracking=1,linktype=1),all_links[n].setAttribute("data-slimstat",(linktype<<1)+tracking),SlimStat.add_event(all_links[n],"click",function(e){link_info=parseInt(this.getAttribute("data-slimstat")),isNaN(link_info)&&(link_info=0),!0&link_info&&SlimStat.ss_track(e,link_info>>1,"")})}}};"function"!=typeof String.prototype.trim&&(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),SlimStat.add_event(window,"load",function(){SlimStat.attach_tracker()});var slimstat_data="",use_beacon=!0;void 0!==SlimStatParams.id&&parseInt(SlimStatParams.id)>0?slimstat_data="action=slimtrack&op=update&id="+SlimStatParams.id:void 0!==SlimStatParams.ci&&(slimstat_data="action=slimtrack&op=add&id="+SlimStatParams.ci+"&ref="+SlimStat._base64_encode(document.referrer)+"&res="+SlimStat._base64_encode(window.location.href),use_beacon=!1),slimstat_data.length>0&&SlimStat.add_event(window,"load",function(){setTimeout(function(){SlimStat.send_to_server(slimstat_data,"")},0)});
1
+ var SlimStat={_id:void 0!==SlimStatParams.id?SlimStatParams.id:"-1.0",_base64_key_str:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",_plugins:{acrobat:{substrings:["Adobe","Acrobat"],active_x_strings:["AcroPDF.PDF","PDF.PDFCtrl.5"]},pdfviewer:{substrings:["PDF"],active_x_strings:["AcroPDF.PDF"]},flash:{substrings:["Shockwave","Flash"],active_x_strings:["ShockwaveFlash.ShockwaveFlash"]},mediaplayer:{substrings:["Windows Media"],active_x_strings:["WMPlayer.OCX"]},quicktime:{substrings:["QuickTime"],active_x_strings:["QuickTime.QuickTime"]},silverlight:{substrings:["Silverlight"],active_x_strings:["AgControl.AgControl"]}},_utf8_encode:function(t){var e,n,i="";for(t=t.replace(/\r\n/g,"\n"),e=0;e<t.length;e++)(n=t.charCodeAt(e))<128?i+=String.fromCharCode(n):n>127&&n<2048?(i+=String.fromCharCode(n>>6|192),i+=String.fromCharCode(63&n|128)):(i+=String.fromCharCode(n>>12|224),i+=String.fromCharCode(n>>6&63|128),i+=String.fromCharCode(63&n|128));return i},_base64_encode:function(t){var e,n,i,r,a,o,s,l="",d=0;for(t=SlimStat._utf8_encode(t);d<t.length;)r=(e=t.charCodeAt(d++))>>2,a=(3&e)<<4|(n=t.charCodeAt(d++))>>4,o=(15&n)<<2|(i=t.charCodeAt(d++))>>6,s=63&i,isNaN(n)?o=s=64:isNaN(i)&&(s=64),l=l+SlimStat._base64_key_str.charAt(r)+SlimStat._base64_key_str.charAt(a)+SlimStat._base64_key_str.charAt(o)+SlimStat._base64_key_str.charAt(s);return l},_detect_single_plugin_not_ie:function(t){var e,n,i,r;for(i in navigator.plugins){for(r in e=""+navigator.plugins[i].name+navigator.plugins[i].description,n=0,SlimStat._plugins[t].substrings)-1!=e.indexOf(SlimStat._plugins[t].substrings[r])&&n++;if(n==SlimStat._plugins[t].substrings.length)return!0}return!1},_detect_single_plugin_ie:function(t){var e="",n=!1;for(e in SlimStat._plugins[t].active_x_strings)try{new ActiveXObject(SlimStat._plugins[t].active_x_strings[e]),n=!0}catch(t){}return n},_detect_single_plugin:function(t){return navigator.plugins.length?this.detect=SlimStat._detect_single_plugin_not_ie:this.detect=SlimStat._detect_single_plugin_ie,this.detect(t)},detect_plugins:function(){var t,e=[];for(t in SlimStat._plugins)SlimStat._detect_single_plugin(t)&&e.push(t);return"function"==typeof navigator.javaEnabled&&navigator.javaEnabled()&&e.push("java"),e.join(",")},get_page_performance:function(){return slim_performance=window.performance||window.mozPerformance||window.msPerformance||window.webkitPerformance||{},void 0===slim_performance.timing?0:slim_performance.timing.loadEventEnd-slim_performance.timing.responseEnd},get_server_latency:function(){return slim_performance=window.performance||window.mozPerformance||window.msPerformance||window.webkitPerformance||{},void 0===slim_performance.timing?0:slim_performance.timing.responseEnd-slim_performance.timing.connectEnd},optout:function(t,e){t.preventDefault(),expiration=new Date,expiration.setTime(expiration.getTime()+31536e6),document.cookie="slimstat_optout_tracking="+e+";expires="+expiration.toGMTString(),t.target.parentNode.parentNode.removeChild(t.target.parentNode)},show_optout_message:function(){for(var t=void 0!==SlimStatParams.opt_out_cookies&&SlimStatParams.opt_out_cookies?SlimStatParams.opt_out_cookies.split(","):[],e=!0,n=0;n<t.length;n++)""!=SlimStat.get_cookie(t[n])&&(e=!1);if(e&&(xhr=new XMLHttpRequest,xhr))return xhr.open("POST",SlimStatParams.ajaxurl,!0),xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xhr.setRequestHeader("X-Requested-With","XMLHttpRequest"),xhr.withCredentials=!0,xhr.send("action=slimstat_optout_html"),xhr.onreadystatechange=function(){4==xhr.readyState&&document.body.insertAdjacentHTML("beforeend",xhr.responseText)},!0},add_event:function(t,e,n){t&&t.addEventListener?t.addEventListener(e,n,!1):t&&t.attachEvent?(t["e"+e+n]=n,t[e+n]=function(){t["e"+e+n](window.event)},t.attachEvent("on"+e,t[e+n])):t["on"+e]=t["e"+e+n]},in_array:function(t,e){for(var n=0;n<e.length;n++)if(e[n].trim()==t)return!0;return!1},in_array_substring:function(t,e){for(var n=0;n<e.length;n++)if(-1!=t.indexOf(e[n].trim()))return!0;return!1},get_cookie:function(t){var e=("; "+document.cookie).split("; "+t+"=");return 2==e.length?e.pop().split(";").shift():""},send_to_server:function(t,e){if(void 0===SlimStatParams.ajaxurl||void 0===t)return!1;if(void 0===e&&(e=!0),slimstat_data_with_client_info=t+"&sw="+screen.width+"&sh="+screen.height+"&bw="+window.innerWidth+"&bh="+window.innerHeight+"&sl="+SlimStat.get_server_latency()+"&pp="+SlimStat.get_page_performance()+"&pl="+SlimStat.detect_plugins(),e&&navigator.sendBeacon)navigator.sendBeacon(SlimStatParams.ajaxurl,slimstat_data_with_client_info);else{try{window.XMLHttpRequest?request=new XMLHttpRequest:window.ActiveXObject&&(request=new ActiveXObject("Microsoft.XMLHTTP"))}catch(t){return!1}if(request)return request.open("POST",SlimStatParams.ajaxurl,!0),request.setRequestHeader("Content-type","application/x-www-form-urlencoded"),request.setRequestHeader("X-Requested-With","XMLHttpRequest"),request.withCredentials=!0,request.send(slimstat_data_with_client_info),request.onreadystatechange=function(){4==request.readyState&&(parsed_id=parseInt(request.responseText),!isNaN(parsed_id)&&parsed_id>0&&(SlimStat._id=request.responseText))},!0}return!1},ss_track:function(t,e,n,i){if(t=t||window.event,e=void 0===e?0:parseInt(e),note_array=[],void 0===i&&(i=!0),parsed_id=parseInt(SlimStat._id),isNaN(parsed_id)||parsed_id<=0)return!1;if(node=void 0!==t.target?t.target:void 0!==t.srcElement&&t.srcElement,!node)return!1;switch(3==node.nodeType&&(node=node.parentNode),parent_node=node.parentNode,resource_url="",node.nodeName){case"FORM":void 0!==node.action&&node.action&&(resource_url=node.action);break;case"INPUT":for(;"undefined"!=typeof parent_node&&"FORM"!=parent_node.nodeName&&"BODY"!=parent_node.nodeName;)parent_node=parent_node.parentNode;if(void 0!==parent_node.action&&parent_node.action){resource_url=parent_node.action;break}default:if("A"!=node.nodeName)for(;void 0!==node.parentNode&&null!=node.parentNode&&"A"!=node.nodeName&&"BODY"!=node.nodeName;)node=node.parentNode;void 0!==node.hash&&node.hash&&node.hostname==location.hostname?resource_url=node.hash:void 0!==node.href&&-1==node.href.indexOf("javascript:")&&(resource_url=node.href),"function"==typeof node.getAttribute&&(void 0!==node.getAttribute("title")&&node.getAttribute("title")&&note_array.push("Title:"+node.getAttribute("title")),void 0!==node.getAttribute("id")&&node.getAttribute("id")&&note_array.push("ID:"+node.getAttribute("id")))}return pos_x=-1,pos_y=-1,position="",void 0!==t.pageX&&void 0!==t.pageY?(pos_x=t.pageX,pos_y=t.pageY):void 0!==t.clientX&&void 0!==t.clientY&&void 0!==document.body.scrollLeft&&void 0!==document.documentElement.scrollLeft&&void 0!==document.body.scrollTop&&void 0!==document.documentElement.scrollTop&&(pos_x=t.clientX+document.body.scrollLeft+document.documentElement.scrollLeft,pos_y=t.clientY+document.body.scrollTop+document.documentElement.scrollTop),pos_x>0&&pos_y>0&&(position=pos_x+","+pos_y),void 0!==t.type&&(event_description=t.type,"keypress"==t.type?event_description+="; keypress:"+String.fromCharCode(parseInt(t.which)):"click"==t.type&&(event_description+="; which:"+t.which)),void 0!==n&&n&&note_array.push(n),note_string=SlimStat._base64_encode(note_array.join(", ")),requested_op="add",1==e?resource_url=resource_url.substring(resource_url.indexOf(location.hostname)+location.hostname.length):requested_op=0==e||2==e?"update":"event",SlimStat.send_to_server("action=slimtrack&op="+requested_op+"&id="+SlimStat._id+"&ty="+e+"&ref="+SlimStat._base64_encode(document.referrer)+"&res="+SlimStat._base64_encode(resource_url)+"&pos="+position+"&des="+SlimStat._base64_encode(event_description)+"&no="+note_string,i),!0},attach_tracker:function(){all_links=document.getElementsByTagName("a");for(var t=void 0!==SlimStatParams.extensions_to_track&&SlimStatParams.extensions_to_track?SlimStatParams.extensions_to_track.split(","):[],e=void 0!==SlimStatParams.outbound_classes_rel_href_to_not_track&&SlimStatParams.outbound_classes_rel_href_to_not_track?SlimStatParams.outbound_classes_rel_href_to_not_track.split(","):[],n=0;n<all_links.length;n++){if(linktype=all_links[n].href&&(all_links[n].hostname==location.hostname||-1==all_links[n].href.indexOf("://"))||-1==all_links[n].href.indexOf("javascript:")?2:0,tracking=1,e.length>0){if(1==tracking){classes_current_link=void 0!==all_links[n].className&&all_links[n].className?all_links[n].className.split(" "):[];for(var i=0;i<classes_current_link.length;i++)if(SlimStat.in_array_substring(classes_current_link[i],e)){tracking=0;break}}1==tracking&&void 0!==all_links[n].attributes.rel&&all_links[n].attributes.rel.value&&SlimStat.in_array_substring(all_links[n].attributes.rel.value,e)&&(tracking=0),1==tracking&&void 0!==all_links[n].href&&all_links[n].href&&SlimStat.in_array_substring(all_links[n].href,e)&&(tracking=0)}extension_current_link=all_links[n].pathname.split(/[?#]/)[0].split(".").pop().replace(/[\/\-]/g,""),2==linktype&&t.length>0&&SlimStat.in_array(extension_current_link,t)&&(tracking=1,linktype=1),all_links[n].setAttribute("data-slimstat",(linktype<<1)+tracking),SlimStat.add_event(all_links[n],"click",function(t){link_info=parseInt(this.getAttribute("data-slimstat")),isNaN(link_info)&&(link_info=0),!0&link_info&&SlimStat.ss_track(t,link_info>>1,"")})}}};"function"!=typeof String.prototype.trim&&(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),SlimStat.add_event(window,"load",function(){SlimStat.attach_tracker(),SlimStat.show_optout_message()});var slimstat_data="",use_beacon=!0;void 0!==SlimStatParams.id&&parseInt(SlimStatParams.id)>0?slimstat_data="action=slimtrack&op=update&id="+SlimStatParams.id:void 0!==SlimStatParams.ci&&(slimstat_data="action=slimtrack&op=add&id="+SlimStatParams.ci+"&ref="+SlimStat._base64_encode(document.referrer)+"&res="+SlimStat._base64_encode(window.location.href),use_beacon=!1),slimstat_data.length>0&&SlimStat.add_event(window,"load",function(){setTimeout(function(){SlimStat.send_to_server(slimstat_data,"")},0)});
wp-slimstat.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Slimstat Analytics
4
  Plugin URI: http://wordpress.org/plugins/wp-slimstat/
5
  Description: The leading web analytics plugin for WordPress
6
- Version: 4.7.8.1
7
  Author: Jason Crouse
8
  Author URI: http://www.wp-slimstat.com/
9
  Text Domain: wp-slimstat
@@ -15,7 +15,7 @@ if ( !empty( wp_slimstat::$settings ) ) {
15
  }
16
 
17
  class wp_slimstat {
18
- public static $version = '4.7.8.1';
19
  public static $settings = array();
20
 
21
  public static $wpdb = '';
@@ -57,13 +57,18 @@ class wp_slimstat {
57
  self::$wpdb = apply_filters( 'slimstat_custom_wpdb', $GLOBALS[ 'wpdb' ] );
58
 
59
  // Define the folder where to store the geolocation database (shared among sites in a network, by default)
60
- self::$upload_dir = wp_upload_dir();
61
- self::$upload_dir = self::$upload_dir[ 'basedir' ];
62
- if ( is_multisite() && ! ( is_main_network() && is_main_site() && defined( 'MULTISITE' ) ) ) {
63
- self::$upload_dir = str_replace( '/sites/' . get_current_blog_id(), '', self::$upload_dir );
 
 
 
 
 
 
 
64
  }
65
- self::$upload_dir .= '/wp-slimstat';
66
- self::$upload_dir = apply_filters( 'slimstat_maxmind_path', self::$upload_dir );
67
 
68
  self::$maxmind_path = self::$upload_dir . '/maxmind.mmdb';
69
 
@@ -88,31 +93,6 @@ class wp_slimstat {
88
  if ( self::$settings[ 'track_users' ] == 'on' ) {
89
  add_action( 'login_enqueue_scripts', array( __CLASS__, 'wp_slimstat_enqueue_tracking_script' ), 10 );
90
  }
91
-
92
- // GDPR Compliance: opt-out text box and handling
93
- $is_cookie_empty = !isset( $_COOKIE[ 'slimstat_optout_' . COOKIEHASH ] );
94
- if ( $is_cookie_empty && !empty( self::$settings[ 'opt_out_cookie_names' ] ) ) {
95
- foreach ( self::string_to_array( self::$settings[ 'opt_out_cookie_names' ] ) as $a_cookie_pair ) {
96
- list( $name, $value ) = explode( '=', $a_cookie_pair );
97
-
98
- if ( !empty( $name ) && isset( $_COOKIE[ $name ] ) ) {
99
- $is_cookie_empty = false;
100
- break;
101
- }
102
- }
103
- }
104
- if ( $is_cookie_empty && self::$settings[ 'display_opt_out' ] == 'on' && !isset( $_GET[ 'slimstat-opt-out' ] ) ) {
105
- add_action( 'wp_footer', array( __CLASS__, 'opt_out_box' ) );
106
- }
107
-
108
- if ( isset( $_GET[ 'slimstat-opt-out' ] ) ) {
109
- @setcookie(
110
- 'slimstat_optout_' . COOKIEHASH,
111
- $_GET[ 'slimstat-opt-out' ],
112
- time() + 31557600, // 365 days
113
- COOKIEPATH
114
- );
115
- }
116
  }
117
 
118
  // Hook a DB clean-up routine to the daily cronjob
@@ -121,8 +101,12 @@ class wp_slimstat {
121
  // Allow external domains on CORS requests
122
  add_filter( 'allowed_http_origins', array(__CLASS__, 'open_cors_admin_ajax' ) );
123
 
 
 
 
 
124
  // Shortcodes
125
- add_shortcode('slimstat', array(__CLASS__, 'slimstat_shortcode'), 15);
126
 
127
  // Include our browser detector library
128
  include_once( plugin_dir_path( __FILE__ ) . 'browscap/browser.php' );
@@ -295,7 +279,7 @@ class wp_slimstat {
295
  }
296
 
297
  // Opt-out of tracking via cookie
298
- $cookie_names = array( 'slimstat_optout_' . COOKIEHASH => 'true' );
299
 
300
  if ( !empty( self::$settings[ 'opt_out_cookie_names' ] ) ) {
301
  $cookie_names = array();
@@ -695,7 +679,7 @@ class wp_slimstat {
695
 
696
  self::$stat = self::$stat + self::$browser;
697
 
698
- // This function can be called in "simulate" mode: no data will be actually saved in the database
699
  if ( is_array( $_argument ) && isset( $_argument[ 'slimtrack_simulate' ] ) ) {
700
  $_argument[ 'slimtrack_would_track' ] = true;
701
  return ( $_argument );
@@ -772,15 +756,15 @@ class wp_slimstat {
772
  /**
773
  * Decodes the permalink
774
  */
775
- public static function get_request_uri(){
776
- if (isset($_SERVER['REQUEST_URI'])){
777
- return urldecode($_SERVER['REQUEST_URI']);
778
  }
779
- elseif (isset($_SERVER['SCRIPT_NAME'])){
780
- return isset($_SERVER['QUERY_STRING'])?$_SERVER['SCRIPT_NAME']."?".$_SERVER['QUERY_STRING']:$_SERVER['SCRIPT_NAME'];
781
  }
782
  else{
783
- return isset($_SERVER['QUERY_STRING'])?$_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING']:$_SERVER['PHP_SELF'];
784
  }
785
  }
786
  // end get_request_uri
@@ -788,22 +772,22 @@ class wp_slimstat {
788
  /**
789
  * Stores the information (array) in the appropriate table and returns the corresponding ID
790
  */
791
- public static function insert_row($_data = array(), $_table = ''){
792
  if ( empty( $_data ) || empty( $_table ) ) {
793
  return -1;
794
  }
795
 
796
  // Remove unwanted characters (SQL injections, anyone?)
797
  $data_keys = array();
798
- foreach (array_keys($_data) as $a_key){
799
- $data_keys[] = sanitize_key($a_key);
800
  }
801
 
802
- self::$wpdb->query(self::$wpdb->prepare("
803
- INSERT IGNORE INTO $_table (".implode(", ", $data_keys).')
804
- VALUES ('.substr(str_repeat('%s,', count($_data)), 0, -1).")", $_data));
805
 
806
- return intval(self::$wpdb->insert_id);
807
  }
808
  // end insert_row
809
 
@@ -1662,25 +1646,36 @@ class wp_slimstat {
1662
  'javascript_mode' => 'on',
1663
  'enable_javascript' => 'on',
1664
  'track_admin_pages' => 'no',
 
 
1665
  'use_separate_menu' => 'on',
1666
- 'add_posts_column' => 'no',
1667
  'posts_column_day_interval' => 30,
 
1668
  'posts_column_pageviews' => 'on',
1669
- 'add_dashboard_widgets' => 'on',
1670
  'hide_addons' => 'no',
 
1671
  'auto_purge' => 0,
1672
  'auto_purge_delete' => 'on',
1673
 
1674
  // Tracker
 
 
 
 
 
 
 
 
1675
  'do_not_track_outbound_classes_rel_href' => 'noslimstat,ab-item',
1676
  'extensions_to_track' => 'pdf,doc,xls,zip',
1677
  'track_same_domain_referers' => 'on',
 
1678
  'geolocation_country' => 'on',
1679
  'session_duration' => 1800,
1680
  'extend_session' => 'no',
1681
- 'set_tracker_cookie' => 'on',
1682
  'enable_cdn' => 'on',
1683
  'ajax_relative_path' => 'no',
 
1684
  'external_domains' => '',
1685
 
1686
  // Filters
@@ -1688,11 +1683,6 @@ class wp_slimstat {
1688
  'ignore_spammers' => 'on',
1689
  'ignore_bots' => 'no',
1690
  'ignore_prefetch' => 'on',
1691
- 'anonymize_ip' => 'no',
1692
- 'honor_dnt_header' => 'yes',
1693
- 'display_opt_out' => 'no',
1694
- 'opt_out_cookie_names' => '',
1695
- 'opt_out_message' => '<p style="display:block;position:fixed;left:0;bottom:0;margin:0;padding:1em 2em;background-color:#eee;width:100%;z-index:99999;">This website stores cookies on your computer. These cookies are used to provide a more personalized experience and to track your whereabouts around our website in compliance with the European General Data Protection Regulation. If you decide to to opt-out of any future tracking, a cookie will be setup in your browser to remember this choice for one year.<br><br><a href="{{accept_url}}">Accept</a> or <a href="{{deny_url}}">Deny</a></p>',
1696
 
1697
  'ignore_users' => '',
1698
  'ignore_ip' => '',
@@ -1712,6 +1702,7 @@ class wp_slimstat {
1712
  'show_display_name' => 'no',
1713
  'convert_resource_urls_to_titles' => 'on',
1714
  'convert_ip_addresses' => 'no',
 
1715
  'async_load' => 'no',
1716
  'use_current_month_timespan' => 'no',
1717
  'expand_details' => 'no',
@@ -1720,9 +1711,11 @@ class wp_slimstat {
1720
  'ip_lookup_service' => 'http://www.infosniper.net/?ip_address=',
1721
  'mozcom_access_id' => '',
1722
  'mozcom_secret_key' => '',
 
1723
  'refresh_interval' => '60',
1724
  'number_results_raw_data' => '50',
1725
  'max_dots_on_map' => '50',
 
1726
  'custom_css' => '',
1727
  'chart_colors' => '',
1728
  'comparison_chart' => 'on',
@@ -1733,10 +1726,13 @@ class wp_slimstat {
1733
  'restrict_authors_view' => 'on',
1734
  'capability_can_view' => 'activate_plugins',
1735
  'can_view' => '',
 
1736
  'capability_can_customize' => 'activate_plugins',
1737
  'can_customize' => '',
 
1738
  'capability_can_admin' => 'activate_plugins',
1739
  'can_admin' => '',
 
1740
  'rest_api_tokens' => wp_hash( uniqid( time() - 3600, true ) ),
1741
 
1742
  // Maintenance
@@ -1799,6 +1795,23 @@ class wp_slimstat {
1799
  $params[ 'outbound_classes_rel_href_to_not_track' ] = str_replace( ' ', '', self::$settings[ 'do_not_track_outbound_classes_rel_href' ] );
1800
  }
1801
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1802
  if ( self::$settings[ 'javascript_mode' ] != 'on' ) {
1803
  // Do not enqueue the tracker if this page view was not tracked for some reason
1804
  if ( !isset( self::$stat[ 'id' ] ) || intval( self::$stat[ 'id' ] ) < 0 ) {
@@ -1888,20 +1901,10 @@ class wp_slimstat {
1888
  }
1889
 
1890
  /**
1891
- * Allow users to opt-out of tracking
1892
  */
1893
- public static function opt_out_box() {
1894
- if ( strpos( $_SERVER[ 'REQUEST_URI' ], '?' ) !== false ) {
1895
- $concat_char = '&';
1896
- }
1897
- else {
1898
- $concat_char = '?';
1899
- }
1900
-
1901
- $opt_out_url = '//' . $_SERVER[ 'HTTP_HOST' ] . $_SERVER[ 'REQUEST_URI' ] . $concat_char . 'slimstat-opt-out=';
1902
-
1903
- $message = str_replace( '{{accept_url}}', $opt_out_url . 'false', stripslashes( self::$settings[ 'opt_out_message' ] ) );
1904
- echo str_replace( '{{deny_url}}', $opt_out_url . 'true', $message );
1905
  }
1906
 
1907
  /**
3
  Plugin Name: Slimstat Analytics
4
  Plugin URI: http://wordpress.org/plugins/wp-slimstat/
5
  Description: The leading web analytics plugin for WordPress
6
+ Version: 4.7.8.2
7
  Author: Jason Crouse
8
  Author URI: http://www.wp-slimstat.com/
9
  Text Domain: wp-slimstat
15
  }
16
 
17
  class wp_slimstat {
18
+ public static $version = '4.7.8.2';
19
  public static $settings = array();
20
 
21
  public static $wpdb = '';
57
  self::$wpdb = apply_filters( 'slimstat_custom_wpdb', $GLOBALS[ 'wpdb' ] );
58
 
59
  // Define the folder where to store the geolocation database (shared among sites in a network, by default)
60
+ if ( defined( 'UPLOADS' ) ) {
61
+ self::$upload_dir = ABSPATH . UPLOADS;
62
+ }
63
+ else {
64
+ self::$upload_dir = wp_upload_dir();
65
+ self::$upload_dir = self::$upload_dir[ 'basedir' ];
66
+ if ( is_multisite() && ! ( is_main_network() && is_main_site() && defined( 'MULTISITE' ) ) ) {
67
+ self::$upload_dir = str_replace( '/sites/' . get_current_blog_id(), '', self::$upload_dir );
68
+ }
69
+ self::$upload_dir .= '/wp-slimstat';
70
+ self::$upload_dir = apply_filters( 'slimstat_maxmind_path', self::$upload_dir );
71
  }
 
 
72
 
73
  self::$maxmind_path = self::$upload_dir . '/maxmind.mmdb';
74
 
93
  if ( self::$settings[ 'track_users' ] == 'on' ) {
94
  add_action( 'login_enqueue_scripts', array( __CLASS__, 'wp_slimstat_enqueue_tracking_script' ), 10 );
95
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  }
97
 
98
  // Hook a DB clean-up routine to the daily cronjob
101
  // Allow external domains on CORS requests
102
  add_filter( 'allowed_http_origins', array(__CLASS__, 'open_cors_admin_ajax' ) );
103
 
104
+ // GDPR: Opt-out Ajax Handler
105
+ add_action( 'wp_ajax_slimstat_optout_html', array( __CLASS__, 'get_optout_html' ) );
106
+ add_action( 'wp_ajax_nopriv_slimstat_optout_html', array( __CLASS__, 'get_optout_html' ) );
107
+
108
  // Shortcodes
109
+ add_shortcode( 'slimstat', array( __CLASS__, 'slimstat_shortcode' ), 15 );
110
 
111
  // Include our browser detector library
112
  include_once( plugin_dir_path( __FILE__ ) . 'browscap/browser.php' );
279
  }
280
 
281
  // Opt-out of tracking via cookie
282
+ $cookie_names = array( 'slimstat_optout_tracking' => 'true' );
283
 
284
  if ( !empty( self::$settings[ 'opt_out_cookie_names' ] ) ) {
285
  $cookie_names = array();
679
 
680
  self::$stat = self::$stat + self::$browser;
681
 
682
+ // This function can be called in "simulation" mode: no data will be actually saved in the database
683
  if ( is_array( $_argument ) && isset( $_argument[ 'slimtrack_simulate' ] ) ) {
684
  $_argument[ 'slimtrack_would_track' ] = true;
685
  return ( $_argument );
756
  /**
757
  * Decodes the permalink
758
  */
759
+ public static function get_request_uri() {
760
+ if ( isset( $_SERVER[ 'REQUEST_URI' ] ) ) {
761
+ return urldecode( $_SERVER[ 'REQUEST_URI' ] );
762
  }
763
+ elseif ( isset( $_SERVER[ 'SCRIPT_NAME' ] ) ) {
764
+ return isset( $_SERVER[ 'QUERY_STRING' ] ) ? $_SERVER[ 'SCRIPT_NAME' ] . '?' . $_SERVER[ 'QUERY_STRING' ] : $_SERVER[ 'SCRIPT_NAME' ];
765
  }
766
  else{
767
+ return isset( $_SERVER[ 'QUERY_STRING' ] ) ? $_SERVER[ 'PHP_SELF' ] . '?' . $_SERVER[ 'QUERY_STRING' ] : $_SERVER[ 'PHP_SELF' ];
768
  }
769
  }
770
  // end get_request_uri
772
  /**
773
  * Stores the information (array) in the appropriate table and returns the corresponding ID
774
  */
775
+ public static function insert_row( $_data = array(), $_table = '' ) {
776
  if ( empty( $_data ) || empty( $_table ) ) {
777
  return -1;
778
  }
779
 
780
  // Remove unwanted characters (SQL injections, anyone?)
781
  $data_keys = array();
782
+ foreach ( array_keys( $_data ) as $a_key ) {
783
+ $data_keys[] = sanitize_key( $a_key );
784
  }
785
 
786
+ self::$wpdb->query( self::$wpdb->prepare( "
787
+ INSERT IGNORE INTO $_table (" . implode (", ", $data_keys) . ')
788
+ VALUES (' . substr( str_repeat( '%s,', count( $_data ) ), 0, -1 ) . ")", $_data ) );
789
 
790
+ return intval( self::$wpdb->insert_id );
791
  }
792
  // end insert_row
793
 
1646
  'javascript_mode' => 'on',
1647
  'enable_javascript' => 'on',
1648
  'track_admin_pages' => 'no',
1649
+
1650
+ 'add_dashboard_widgets' => 'on',
1651
  'use_separate_menu' => 'on',
 
1652
  'posts_column_day_interval' => 30,
1653
+ 'add_posts_column' => 'no',
1654
  'posts_column_pageviews' => 'on',
 
1655
  'hide_addons' => 'no',
1656
+
1657
  'auto_purge' => 0,
1658
  'auto_purge_delete' => 'on',
1659
 
1660
  // Tracker
1661
+ 'anonymize_ip' => 'no',
1662
+ 'honor_dnt_header' => 'yes',
1663
+ 'set_tracker_cookie' => 'on',
1664
+ 'display_opt_out' => 'no',
1665
+ 'opt_out_message' => '<p style="display:block;position:fixed;left:0;bottom:0;margin:0;padding:1em 2em;background-color:#eee;width:100%;z-index:99999;">This website stores cookies on your computer. These cookies are used to provide a more personalized experience and to track your whereabouts around our website in compliance with the European General Data Protection Regulation. If you decide to to opt-out of any future tracking, a cookie will be setup in your browser to remember this choice for one year.<br><br><a href="#" onclick="javascript:SlimStat.optout(event, false);">Accept</a> or <a href="#" onclick="javascript:SlimStat.optout(event, true);">Deny</a></p>',
1666
+ 'opt_out_cookie_names' => '',
1667
+ 'opt_in_cookie_names' => '',
1668
+
1669
  'do_not_track_outbound_classes_rel_href' => 'noslimstat,ab-item',
1670
  'extensions_to_track' => 'pdf,doc,xls,zip',
1671
  'track_same_domain_referers' => 'on',
1672
+
1673
  'geolocation_country' => 'on',
1674
  'session_duration' => 1800,
1675
  'extend_session' => 'no',
 
1676
  'enable_cdn' => 'on',
1677
  'ajax_relative_path' => 'no',
1678
+
1679
  'external_domains' => '',
1680
 
1681
  // Filters
1683
  'ignore_spammers' => 'on',
1684
  'ignore_bots' => 'no',
1685
  'ignore_prefetch' => 'on',
 
 
 
 
 
1686
 
1687
  'ignore_users' => '',
1688
  'ignore_ip' => '',
1702
  'show_display_name' => 'no',
1703
  'convert_resource_urls_to_titles' => 'on',
1704
  'convert_ip_addresses' => 'no',
1705
+
1706
  'async_load' => 'no',
1707
  'use_current_month_timespan' => 'no',
1708
  'expand_details' => 'no',
1711
  'ip_lookup_service' => 'http://www.infosniper.net/?ip_address=',
1712
  'mozcom_access_id' => '',
1713
  'mozcom_secret_key' => '',
1714
+
1715
  'refresh_interval' => '60',
1716
  'number_results_raw_data' => '50',
1717
  'max_dots_on_map' => '50',
1718
+
1719
  'custom_css' => '',
1720
  'chart_colors' => '',
1721
  'comparison_chart' => 'on',
1726
  'restrict_authors_view' => 'on',
1727
  'capability_can_view' => 'activate_plugins',
1728
  'can_view' => '',
1729
+
1730
  'capability_can_customize' => 'activate_plugins',
1731
  'can_customize' => '',
1732
+
1733
  'capability_can_admin' => 'activate_plugins',
1734
  'can_admin' => '',
1735
+
1736
  'rest_api_tokens' => wp_hash( uniqid( time() - 3600, true ) ),
1737
 
1738
  // Maintenance
1795
  $params[ 'outbound_classes_rel_href_to_not_track' ] = str_replace( ' ', '', self::$settings[ 'do_not_track_outbound_classes_rel_href' ] );
1796
  }
1797
 
1798
+ // GDPR Compliance: test for third-party cookies to see if we need to display the opt-out message
1799
+ $params[ 'opt_out_cookies' ] = array( 'slimstat_optout_tracking' );
1800
+ if ( !empty( self::$settings[ 'opt_out_cookie_names' ] ) ) {
1801
+ foreach( self::string_to_array( self::$settings[ 'opt_out_cookie_names' ] ) as $a_cookie_pair ) {
1802
+ $params[ 'opt_out_cookies' ][] = substr( $a_cookie_pair, 0, strpos( $a_cookie_pair, '=' ) );
1803
+ }
1804
+ }
1805
+ $params[ 'opt_out_cookies' ] = implode( ',', $params[ 'opt_out_cookies' ] );
1806
+
1807
+ if ( !empty( self::$settings[ 'opt_in_cookie_names' ] ) ) {
1808
+ $params[ 'opt_in_cookies' ] = array();
1809
+ foreach( self::string_to_array( self::$settings[ 'opt_in_cookie_names' ] ) as $a_cookie_pair ) {
1810
+ $params[ 'opt_in_cookies' ][] = substr( $a_cookie_pair, 0, strpos( $a_cookie_pair, '=' ) );
1811
+ }
1812
+ $params[ 'opt_in_cookies' ] = implode( ',', $params[ 'opt_in_cookies' ] );
1813
+ }
1814
+
1815
  if ( self::$settings[ 'javascript_mode' ] != 'on' ) {
1816
  // Do not enqueue the tracker if this page view was not tracked for some reason
1817
  if ( !isset( self::$stat[ 'id' ] ) || intval( self::$stat[ 'id' ] ) < 0 ) {
1901
  }
1902
 
1903
  /**
1904
+ * Displays the opt-out box via Ajax request
1905
  */
1906
+ public static function get_optout_html() {
1907
+ die( stripslashes( self::$settings[ 'opt_out_message' ] ) );
 
 
 
 
 
 
 
 
 
 
1908
  }
1909
 
1910
  /**