Slimstat Analytics - Version 4.7.3

Version Description

  • [Fix] A few users pointed out a weird behavior when installing the MaxMind Geolocation data file, where an empty folder would be created instead of the actual file. If you still experience issues related to this problem, please make sure to delete the empty folder "maxmind.mmdb" under wp-content/uploads/wp-slimstat/.
  • [Fix] Apparently Microsoft Security Essentials was not pleased with our code, and was returning a false positive alert that a virus was included with the source code (thank you, Sasa).
  • [Fix] The "content_id" filter could not be used in a shortcode to reference other pages (i.e. [slimstat f='count-all' w='id']content_id equals 2012[/slimstat]). Thank you, Felipe.
  • [Fix] Country flags were not being displayed properly under certain circumstances (thank you, Catmaniax).
  • [Fix] Bug preventing the new Heatmap Add-on from working as expected.
Download this release

Release Info

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

Code changes from version 4.7.2.2 to 4.7.3

admin/config/index.php CHANGED
@@ -114,7 +114,6 @@ $settings = array(
114
 
115
  'advanced_tracker_header' => array( 'description' => __( 'Advanced Options', 'wp-slimstat' ), 'type' => 'section_header' ),
116
  'geolocation_country' => array( 'description' => __( 'Geolocation Precision', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "When Slimstat determines your visitors' Country of origin, it uses a third-party data file <a href='https://dev.maxmind.com/geoip/geoip2/geolite2/' target='_blank'>provided by MaxMind</a>. They offer two precision levels: country and city. By default, Slimstat will install the smaller one (country), and you can decide to use the other one, if you don't mind its 60 Mb average size. After you change this option, please <strong>go to the Maintenance tab</strong> and reload (uninstall/install) the MaxMind GeoLite DB by clicking on the corresponding button.", 'wp-slimstat' ), 'custom_label_on' => __( 'Country', 'wp-slimstat' ), 'custom_label_off' => __( 'City', 'wp-slimstat' ) ),
117
- 'track_users' => array( 'description' => __( 'Track WP Users', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Enable this option to track logged in users.', 'wp-slimstat' ) ),
118
  'session_duration' => array('description' => __( 'Session Duration', 'wp-slimstat' ), 'type' => 'integer', 'long_description' => __( 'How many seconds should a human session last? Google Analytics sets it to 1800 seconds.', 'wp-slimstat' ), 'after_input_field' => __( 'seconds', 'wp-slimstat' ) ),
119
  'extend_session' => array( 'description' => __( 'Extend Session', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Extend the duration of a session each time the user visits a new page.', 'wp-slimstat' ) ),
120
  'enable_cdn' => array( 'description' => __( 'Enable CDN', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "Use <a href='http://www.jsdelivr.com/' target='_blank'>JSDelivr</a>'s CDN, by serving our tracking code from their fast and reliable network (free service).", 'wp-slimstat' ) ),
@@ -139,6 +138,7 @@ $settings = array(
139
  'title' => __( 'Filters', 'wp-slimstat' ),
140
  'rows' => array(
141
  'filters_header' => array('description' => __('Do not track settings','wp-slimstat'), 'type' => 'section_header'),
 
142
  'ignore_users' => array( 'description' => __( 'Blacklist by Username', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "List all the usernames you don't want to track. Please be aware that spaces are <em>not</em> ignored and that usernames are case sensitive. Wildcards: <code>*</code> matches 'any string, including the empty string', <code>!</code> matches 'any character'. For example, <code>user*</code> will match user12 and userfoo, <code>u*100</code> will match user100 and uber100, <code>user!0</code> will match user10 and user90.", 'wp-slimstat' ) ),
143
  'ignore_ip' => array('description' => __('Blacklist by IP Address','wp-slimstat'), 'type' => 'textarea', 'long_description' => __("List all the IP addresses you don't want to track. Each network <strong>must</strong> be defined using the <a href='http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing' target='_blank'>CIDR notation</a> (i.e. <em>192.168.0.0/24</em>). This filter applies both to the public IP and the originating IP, if available.",'wp-slimstat')),
144
  'ignore_capabilities' => array('description' => __('Blacklist by Capability','wp-slimstat'), 'type' => 'textarea', 'long_description' => __("Users having at least one of the <a href='http://codex.wordpress.org/Roles_and_Capabilities' target='_new'>capabilities</a> listed here below will not be tracked. Capabilities are case-insensitive.",'wp-slimstat'), 'skip_update' => true),
@@ -198,11 +198,13 @@ $settings = array(
198
  'restrict_authors_view' => array('description' => __('Restrict Authors','wp-slimstat'), 'type' => 'toggle', 'long_description' => __('Enable this option if you want your authors to only see stats related to their own content.','wp-slimstat')),
199
  'capability_can_view' => array('description' => __('Capability','wp-slimstat'), 'type' => 'text', 'long_description' => __("Specify the minimum <a href='http://codex.wordpress.org/Roles_and_Capabilities' target='_new'>capability</a> needed to access the reports (default: <code>activate_plugins</code>). If this field is empty, <strong>all your users</strong> (including subscribers) will have access to the reports, unless a 'Read access' whitelist has been specified here below. In this case, the list has precedence over the capability.",'wp-slimstat')),
200
  'can_view' => array('description' => __('Whitelist','wp-slimstat'), 'type' => 'textarea', 'long_description' => __("List all the users who should have access to the reports. Administrators are implicitly allowed, so you don't need to list them in here. Usernames are case sensitive.",'wp-slimstat'), 'skip_update' => true),
201
- 'rest_api_tokens' => array( 'description' => __( 'REST API Tokens', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "In order to send requests to <a href='https://slimstat.freshdesk.com/support/solutions/articles/12000033661-slimstat-rest-api' target='_blank'>the Slimstat REST API</a>, you will need to pass a valid token to the endpoint (param ?token=XXX). Using the field here below, you can define as many tokens as you like, to distribute them to your API users. Please note: treat these tokens as passwords, as they will grant read access to your reports to anyone who knows them. Use a service like <a href='https://randomkeygen.com/#ci_key' target='_blank'>RandomKeyGen.com</a> to generate unique secure tokens.", 'wp-slimstat' ) ),
202
 
203
  'permissions_config_header' => array('description' => __('Settings','wp-slimstat'), 'type' => 'section_header'),
204
  'capability_can_admin' => array('description' => __('Capability','wp-slimstat'), 'type' => 'text', 'long_description' => __("Specify the minimum <a href='http://codex.wordpress.org/Roles_and_Capabilities' target='_new'>capability</a> required to configure Slimstat (default: <code>activate_plugins</code>). The whitelist here below can be used to override this option for specific users.",'wp-slimstat')),
205
- 'can_admin' => array('description' => __('Whitelist','wp-slimstat'), 'type' => 'textarea', 'long_description' => __("List all the users who can edit these options. Please be advised that admins <strong>are not</strong> implicitly allowed, so do not forget to include yourself! Usernames are case sensitive.",'wp-slimstat'), 'skip_update' => true)
 
 
 
206
  )
207
  ),
208
 
114
 
115
  'advanced_tracker_header' => array( 'description' => __( 'Advanced Options', 'wp-slimstat' ), 'type' => 'section_header' ),
116
  'geolocation_country' => array( 'description' => __( 'Geolocation Precision', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "When Slimstat determines your visitors' Country of origin, it uses a third-party data file <a href='https://dev.maxmind.com/geoip/geoip2/geolite2/' target='_blank'>provided by MaxMind</a>. They offer two precision levels: country and city. By default, Slimstat will install the smaller one (country), and you can decide to use the other one, if you don't mind its 60 Mb average size. After you change this option, please <strong>go to the Maintenance tab</strong> and reload (uninstall/install) the MaxMind GeoLite DB by clicking on the corresponding button.", 'wp-slimstat' ), 'custom_label_on' => __( 'Country', 'wp-slimstat' ), 'custom_label_off' => __( 'City', 'wp-slimstat' ) ),
 
117
  'session_duration' => array('description' => __( 'Session Duration', 'wp-slimstat' ), 'type' => 'integer', 'long_description' => __( 'How many seconds should a human session last? Google Analytics sets it to 1800 seconds.', 'wp-slimstat' ), 'after_input_field' => __( 'seconds', 'wp-slimstat' ) ),
118
  'extend_session' => array( 'description' => __( 'Extend Session', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Extend the duration of a session each time the user visits a new page.', 'wp-slimstat' ) ),
119
  'enable_cdn' => array( 'description' => __( 'Enable CDN', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "Use <a href='http://www.jsdelivr.com/' target='_blank'>JSDelivr</a>'s CDN, by serving our tracking code from their fast and reliable network (free service).", 'wp-slimstat' ) ),
138
  'title' => __( 'Filters', 'wp-slimstat' ),
139
  'rows' => array(
140
  'filters_header' => array('description' => __('Do not track settings','wp-slimstat'), 'type' => 'section_header'),
141
+ 'track_users' => array( 'description' => __( 'Track WP Users', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Enable this option to track logged in users.', 'wp-slimstat' ) ),
142
  'ignore_users' => array( 'description' => __( 'Blacklist by Username', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "List all the usernames you don't want to track. Please be aware that spaces are <em>not</em> ignored and that usernames are case sensitive. Wildcards: <code>*</code> matches 'any string, including the empty string', <code>!</code> matches 'any character'. For example, <code>user*</code> will match user12 and userfoo, <code>u*100</code> will match user100 and uber100, <code>user!0</code> will match user10 and user90.", 'wp-slimstat' ) ),
143
  'ignore_ip' => array('description' => __('Blacklist by IP Address','wp-slimstat'), 'type' => 'textarea', 'long_description' => __("List all the IP addresses you don't want to track. Each network <strong>must</strong> be defined using the <a href='http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing' target='_blank'>CIDR notation</a> (i.e. <em>192.168.0.0/24</em>). This filter applies both to the public IP and the originating IP, if available.",'wp-slimstat')),
144
  'ignore_capabilities' => array('description' => __('Blacklist by Capability','wp-slimstat'), 'type' => 'textarea', 'long_description' => __("Users having at least one of the <a href='http://codex.wordpress.org/Roles_and_Capabilities' target='_new'>capabilities</a> listed here below will not be tracked. Capabilities are case-insensitive.",'wp-slimstat'), 'skip_update' => true),
198
  'restrict_authors_view' => array('description' => __('Restrict Authors','wp-slimstat'), 'type' => 'toggle', 'long_description' => __('Enable this option if you want your authors to only see stats related to their own content.','wp-slimstat')),
199
  'capability_can_view' => array('description' => __('Capability','wp-slimstat'), 'type' => 'text', 'long_description' => __("Specify the minimum <a href='http://codex.wordpress.org/Roles_and_Capabilities' target='_new'>capability</a> needed to access the reports (default: <code>activate_plugins</code>). If this field is empty, <strong>all your users</strong> (including subscribers) will have access to the reports, unless a 'Read access' whitelist has been specified here below. In this case, the list has precedence over the capability.",'wp-slimstat')),
200
  'can_view' => array('description' => __('Whitelist','wp-slimstat'), 'type' => 'textarea', 'long_description' => __("List all the users who should have access to the reports. Administrators are implicitly allowed, so you don't need to list them in here. Usernames are case sensitive.",'wp-slimstat'), 'skip_update' => true),
 
201
 
202
  'permissions_config_header' => array('description' => __('Settings','wp-slimstat'), 'type' => 'section_header'),
203
  'capability_can_admin' => array('description' => __('Capability','wp-slimstat'), 'type' => 'text', 'long_description' => __("Specify the minimum <a href='http://codex.wordpress.org/Roles_and_Capabilities' target='_new'>capability</a> required to configure Slimstat (default: <code>activate_plugins</code>). The whitelist here below can be used to override this option for specific users.",'wp-slimstat')),
204
+ 'can_admin' => array('description' => __('Whitelist','wp-slimstat'), 'type' => 'textarea', 'long_description' => __("List all the users who can edit these options. Please be advised that admins <strong>are not</strong> implicitly allowed, so do not forget to include yourself! Usernames are case sensitive.",'wp-slimstat'), 'skip_update' => true),
205
+
206
+ 'rest_api_header' => array( 'description' => __( 'Rest API', 'wp-slimstat' ), 'type' => 'section_header' ),
207
+ 'rest_api_tokens' => array( 'description' => __( 'Tokens', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "In order to send requests to <a href='https://slimstat.freshdesk.com/support/solutions/articles/12000033661-slimstat-rest-api' target='_blank'>the Slimstat REST API</a>, you will need to pass a valid token to the endpoint (param ?token=XXX). Using the field here below, you can define as many tokens as you like, to distribute them to your API users. Please note: treat these tokens as passwords, as they will grant read access to your reports to anyone who knows them. Use a service like <a href='https://randomkeygen.com/#ci_key' target='_blank'>RandomKeyGen.com</a> to generate unique secure tokens.", 'wp-slimstat' ) )
208
  )
209
  ),
210
 
admin/config/maintenance.php CHANGED
@@ -44,8 +44,22 @@ if ( !empty( $_REQUEST[ 'action' ] ) ) {
44
  break;
45
 
46
  case 'delete-maxmind':
47
- @unlink( wp_slimstat::$maxmind_path );
48
- wp_slimstat_admin::show_alert_message( __( 'The geolocation database has been uninstalled from your server.', 'wp-slimstat' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  break;
50
 
51
  case 'download-maxmind':
@@ -162,7 +176,7 @@ $slim_browsers_exists =wp_slimstat::$wpdb->get_col( "SHOW TABLES LIKE '{$GLOBALS
162
  <th scope="row"><?php _e( 'Tracker Error', 'wp-slimstat' ) ?></th>
163
  <td>
164
  <?php echo ( !empty( wp_slimstat::$settings[ 'last_tracker_error' ][ 1 ] ) && !empty( wp_slimstat::$settings[ 'last_tracker_error' ][ 2 ] ) ) ? '<strong>[' . date_i18n( wp_slimstat::$settings[ 'date_format' ], wp_slimstat::$settings[ 'last_tracker_error' ][ 2 ], true ) . ' ' . date_i18n( wp_slimstat::$settings[ 'time_format' ], wp_slimstat::$settings[ 'last_tracker_error' ][ 2 ], true ) . '] ' . wp_slimstat::$settings[ 'last_tracker_error' ][ 0 ] . ' ' . wp_slimstat::$settings[ 'last_tracker_error' ][ 1 ] . '</strong><a class="slimstat-font-cancel" title="' . htmlentities( __( 'Reset this error', 'wp-slimstat' ), ENT_QUOTES, 'UTF-8' ) . '" href="' . wp_slimstat_admin::$config_url.$current_tab . '&amp;action=reset-tracker-error-status"></a>' : __( 'So far so good.', 'wp-slimstat' ); ?>
165
- <span class="description"><?php _e( 'The information here above is useful to troubleshoot issues with the tracker. <strong>Errors</strong> are returned when the tracker could not record a page view for some reason, and are indicative of some kind of malfunction. Please include the message here above when sending a support request.', 'wp-slimstat' ) ?></span>
166
  </td>
167
  </tr>
168
  <tr>
44
  break;
45
 
46
  case 'delete-maxmind':
47
+ $is_deleted = @unlink( wp_slimstat::$maxmind_path );
48
+
49
+ if ( $is_deleted ) {
50
+ wp_slimstat_admin::show_alert_message( __( 'The geolocation database has been uninstalled from your server.', 'wp-slimstat' ) );
51
+ }
52
+ else {
53
+ // Some users have reported that a directory is created, instead of a file
54
+ $is_deleted = @rmdir( wp_slimstat::$maxmind_path );
55
+
56
+ if ( $is_deleted ) {
57
+ wp_slimstat_admin::show_alert_message( __( 'The geolocation database has been uninstalled from your server.', 'wp-slimstat' ) );
58
+ }
59
+ else {
60
+ wp_slimstat_admin::show_alert_message( __( "The geolocation database could not be removed from your server. Please check your folder's permissions and try again.", 'wp-slimstat' ) );
61
+ }
62
+ }
63
  break;
64
 
65
  case 'download-maxmind':
176
  <th scope="row"><?php _e( 'Tracker Error', 'wp-slimstat' ) ?></th>
177
  <td>
178
  <?php echo ( !empty( wp_slimstat::$settings[ 'last_tracker_error' ][ 1 ] ) && !empty( wp_slimstat::$settings[ 'last_tracker_error' ][ 2 ] ) ) ? '<strong>[' . date_i18n( wp_slimstat::$settings[ 'date_format' ], wp_slimstat::$settings[ 'last_tracker_error' ][ 2 ], true ) . ' ' . date_i18n( wp_slimstat::$settings[ 'time_format' ], wp_slimstat::$settings[ 'last_tracker_error' ][ 2 ], true ) . '] ' . wp_slimstat::$settings[ 'last_tracker_error' ][ 0 ] . ' ' . wp_slimstat::$settings[ 'last_tracker_error' ][ 1 ] . '</strong><a class="slimstat-font-cancel" title="' . htmlentities( __( 'Reset this error', 'wp-slimstat' ), ENT_QUOTES, 'UTF-8' ) . '" href="' . wp_slimstat_admin::$config_url.$current_tab . '&amp;action=reset-tracker-error-status"></a>' : __( 'So far so good.', 'wp-slimstat' ); ?>
179
+ <span class="description"><?php _e( 'The information here above is useful to troubleshoot issues with the tracker. <strong>Errors</strong> are returned when the tracker could not record a page view for some reason, and are indicative of some kind of malfunction. Please include the message here above when sending a <a href="http://support.wp-slimstat.com" target="_blank">support request</a>.', 'wp-slimstat' ) ?></span>
180
  </td>
181
  </tr>
182
  <tr>
admin/view/index.php CHANGED
@@ -74,12 +74,14 @@
74
 
75
  <label for="slimstat-filter-month">Month</label>
76
  <select name="month" id="slimstat-filter-month">
77
- <option value="0"><?php _e('Month','wp-slimstat') ?></option><?php
78
- for($i=1;$i<=12;$i++){
79
- if(!empty(wp_slimstat_db::$filters_normalized['date']['month']) && wp_slimstat_db::$filters_normalized['date']['month'] == $i)
80
- echo "<option value='$i' selected='selected'>".substr($GLOBALS['month'][zeroise($i, 2)], 0, 3)."</option>";
81
- else
82
- echo "<option value='$i'>".substr($GLOBALS['month'][zeroise($i, 2)], 0, 3)."</option>";
 
 
83
  }
84
  ?>
85
  </select>
74
 
75
  <label for="slimstat-filter-month">Month</label>
76
  <select name="month" id="slimstat-filter-month">
77
+ <option value="0"><?php _e( 'Month', 'wp-slimstat' ) ?></option><?php
78
+ for ( $i=1; $i<=12; $i++ ) {
79
+ if ( !empty( wp_slimstat_db::$filters_normalized[ 'date' ][ 'month' ] ) && wp_slimstat_db::$filters_normalized[ 'date' ][ 'month' ] == $i ) {
80
+ echo "<option value='$i' selected='selected'>" . $GLOBALS[ 'wp_locale' ]->get_month_abbrev( $GLOBALS[ 'wp_locale' ]->get_month( $i ) ) . "</option>";
81
+ }
82
+ else {
83
+ echo "<option value='$i'>" . $GLOBALS[ 'wp_locale' ]->get_month_abbrev( $GLOBALS[ 'wp_locale' ]->get_month( $i ) ) . "</option>";
84
+ }
85
  }
86
  ?>
87
  </select>
admin/view/right-now.php CHANGED
@@ -79,7 +79,9 @@ else {
79
  $highlight_row = !empty($results[$i]['searchterms'])?' is-search-engine':(($results[$i]['browser_type'] != 1)?' is-direct':'');
80
 
81
  // Country
82
- $country_filtered = "<a class='slimstat-filter-link inline-icon' href='".wp_slimstat_reports::fs_url('country equals '.$results[$i]['country'])."'><img class='slimstat-tooltip-trigger' src='$plugin_url/images/flags/{$results[$i]['country']}.png' width='16' height='16' title='" . __('c-'.$results[$i]['country'],'wp-slimstat') . "'></a>";
 
 
83
 
84
  // City, if tracked
85
  $city_filtered = '';
79
  $highlight_row = !empty($results[$i]['searchterms'])?' is-search-engine':(($results[$i]['browser_type'] != 1)?' is-direct':'');
80
 
81
  // Country
82
+ if ( !empty( $results[ $i ][ 'country' ] ) ) {
83
+ $country_filtered = "<a class='slimstat-filter-link inline-icon' href='" . wp_slimstat_reports::fs_url( 'country equals ' . $results[ $i ][ 'country' ] ) . "'><img class='slimstat-tooltip-trigger' src='$plugin_url/images/flags/{$results[$i]['country']}.png' width='16' height='16' title='" . __( 'c-' . $results[ $i ][ 'country' ], 'wp-slimstat' ) . "'></a>";
84
+ }
85
 
86
  // City, if tracked
87
  $city_filtered = '';
admin/view/wp-slimstat-db.php CHANGED
@@ -349,7 +349,7 @@ class wp_slimstat_db {
349
  break;
350
  }
351
 
352
- if ( !empty( $where[ 1 ] ) ) {
353
  return $GLOBALS[ 'wpdb' ]->prepare( $where[ 0 ], $where[ 1 ] );
354
  }
355
  else {
@@ -475,8 +475,9 @@ class wp_slimstat_db {
475
  break;
476
 
477
  case 'content_id':
478
- if ( !empty( $a_filter[ 3 ] ) && $a_filter[ 3 ] == 'current' && !empty( $GLOBALS[ 'post' ]->ID ) ) {
479
- $filters_normalized[ 'columns' ][ $a_filter[ 1 ] ] = array( $a_filter[ 2 ], $GLOBALS[ 'post' ]->ID );
 
480
  break;
481
  }
482
  // no break here: if value IS numeric, go to the default parser here below
349
  break;
350
  }
351
 
352
+ if ( isset( $where[ 1 ] ) ) {
353
  return $GLOBALS[ 'wpdb' ]->prepare( $where[ 0 ], $where[ 1 ] );
354
  }
355
  else {
475
  break;
476
 
477
  case 'content_id':
478
+ if ( !empty( $a_filter[ 3 ] ) ) {
479
+ $content_id = ( $a_filter[ 3 ] == 'current' && !empty( $GLOBALS[ 'post' ]->ID ) ) ? $GLOBALS[ 'post' ]->ID : intval( $a_filter[ 3 ] );
480
+ $filters_normalized[ 'columns' ][ $a_filter[ 1 ] ] = array( $a_filter[ 2 ], $content_id );
481
  break;
482
  }
483
  // no break here: if value IS numeric, go to the default parser here below
admin/wp-slimstat-admin.php CHANGED
@@ -11,9 +11,9 @@ class wp_slimstat_admin {
11
  * Init -- Sets things up.
12
  */
13
  public static function init() {
14
- self::$admin_notice = "As those who have been using Slimstat for a while know, we never stop doing our good share of research and development to improve our plugin. One feature on our wishlist was to make the geolocation functionality more accurate. Specifically, users have been asking us to track not just the Country of origin, but possibly the state and city. In order to geolocate visitors, our code has been leveraging a third-party data file provided by <a href='https://www.maxmind.com/en/home' target='_blank'>MaxMind.com</a>. A while ago, they launched a new data format, which improves performance and offers a way to quickly determine the city of origin. However, the new library required a higher version of PHP, and up until now we had been hesitant to adopt it, to allow more people to use our plugin, over the chance of offering this feature. Now, after spending some time combing through their code, we found a way to get the best of both worlds: by customizing their PHP library, we were able to make it work with PHP 5.3! Which means that now Slimstat is able to tell you your visitors' city of origin (and State, when applicable) right out of the box. This information is available in the Access Log report and in a new 'Top Cities' report under the Audience tab. Please note: the MaxMind data file to enable this feature is approximately 60 Mb, and for this reason <strong>this new functionality is not enabled by default</strong>. You must go to Slimstat > Settings > Tracker and turn on the corresponding option. Then go to Slimstat > Settings > Maintenance and uninstall/install the GeoLite file to download the one that contains the city data. Please feel free to contact us if you have any questions.";
15
 
16
- self::$admin_notice .= '<br/><br/><a id="slimstat-hide-admin-notice" href="#" class="button-secondary">Got it, thanks</a>';
17
 
18
  // Load language files
19
  load_plugin_textdomain( 'wp-slimstat', WP_PLUGIN_DIR .'/wp-slimstat/languages', '/wp-slimstat/languages' );
@@ -452,6 +452,15 @@ class wp_slimstat_admin {
452
  }
453
  // --- END: Updates for version 4.7.2.2 ---
454
 
 
 
 
 
 
 
 
 
 
455
  // Now we can update the version stored in the database
456
  wp_slimstat::$settings[ 'version' ] = wp_slimstat::$version;
457
 
11
  * Init -- Sets things up.
12
  */
13
  public static function init() {
14
+ self::$admin_notice = "";
15
 
16
+ //self::$admin_notice .= '<br/><br/><a id="slimstat-hide-admin-notice" href="#" class="button-secondary">Got it, thanks</a>';
17
 
18
  // Load language files
19
  load_plugin_textdomain( 'wp-slimstat', WP_PLUGIN_DIR .'/wp-slimstat/languages', '/wp-slimstat/languages' );
452
  }
453
  // --- END: Updates for version 4.7.2.2 ---
454
 
455
+ // --- Updates for version 4.7.2.3 ---
456
+ if ( version_compare( wp_slimstat::$settings[ 'version' ], '4.7.2.3', '<' ) ) {
457
+ // Some users have reported that the MaxMind DB file has been created as an empty folder on their server
458
+ if ( file_exists( wp_slimstat::$maxmind_path ) && !is_file( wp_slimstat::$maxmind_path ) ) {
459
+ @rmdir( wp_slimstat::$maxmind_path );
460
+ }
461
+ }
462
+ // --- END: Updates for version 4.7.2.2 ---
463
+
464
  // Now we can update the version stored in the database
465
  wp_slimstat::$settings[ 'version' ] = wp_slimstat::$version;
466
 
maxmind.php CHANGED
@@ -2,7 +2,6 @@
2
 
3
  class maxmind_geolite2_connector {
4
  public static function get_geolocation_info( $_ip_address = '' ) {
5
-
6
  $ipnum = sprintf( '%u', ip2long( $_ip_address ) );
7
  $geo_output = array( 'country' => array( 'iso_code' => 'xx' ) );
8
 
@@ -13,7 +12,7 @@ class maxmind_geolite2_connector {
13
  ( $ipnum >= 3232235521 && $ipnum <= 3232301055 ) ) { // 192.168.0.1 - 192.168.255.255
14
  $geo_output[ 'country' ][ 'iso_code' ] = 'xy';
15
  }
16
- else if ( file_exists( wp_slimstat::$maxmind_path ) ) {
17
  // Do we need to update our data file?
18
  if ( false !== ( $file_stat = stat( wp_slimstat::$maxmind_path ) ) ) {
19
  // Is the database more than 30 days old?
@@ -29,6 +28,9 @@ class maxmind_geolite2_connector {
29
  $geo_output = $geo_maxmind;
30
  }
31
  }
 
 
 
32
 
33
  return apply_filters( 'slimstat_get_country', $geo_output, $_ip_address );
34
  }
2
 
3
  class maxmind_geolite2_connector {
4
  public static function get_geolocation_info( $_ip_address = '' ) {
 
5
  $ipnum = sprintf( '%u', ip2long( $_ip_address ) );
6
  $geo_output = array( 'country' => array( 'iso_code' => 'xx' ) );
7
 
12
  ( $ipnum >= 3232235521 && $ipnum <= 3232301055 ) ) { // 192.168.0.1 - 192.168.255.255
13
  $geo_output[ 'country' ][ 'iso_code' ] = 'xy';
14
  }
15
+ else if ( file_exists( wp_slimstat::$maxmind_path ) && is_file( wp_slimstat::$maxmind_path ) ) {
16
  // Do we need to update our data file?
17
  if ( false !== ( $file_stat = stat( wp_slimstat::$maxmind_path ) ) ) {
18
  // Is the database more than 30 days old?
28
  $geo_output = $geo_maxmind;
29
  }
30
  }
31
+ else if ( !is_file( wp_slimstat::$maxmind_path ) ) {
32
+ return array( 'country' => array( 'iso_code' => '99' ) );
33
+ }
34
 
35
  return apply_filters( 'slimstat_get_country', $geo_output, $_ip_address );
36
  }
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: analytics, statistics, counter, tracking, reports, wassup, geolocation, on
5
  Text Domain: wp-slimstat
6
  Requires at least: 3.8
7
  Tested up to: 4.8.2
8
- Stable tag: 4.7.2.2
9
 
10
  == Description ==
11
  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.
@@ -71,6 +71,13 @@ Our knowledge base is available on our [support center](http://docs.wp-slimstat.
71
  5. **Responsive layout** - Keep an eye on your reports on the go
72
 
73
  == Changelog ==
 
 
 
 
 
 
 
74
  = 4.7.2.2 =
75
  * [New] Added support for SCRIPT_DEBUG: by defining this constant in your `wp-config.php` will make Slimstat load the unminified version of the javascript tracker (thank you, Sasa)
76
  * [Update] Added new parameter to make the `admin-ajax.php` URL relative, to solve issues like [this one](https://wordpress.org/support/topic/xmlhttprequest-cannot-load-wp-adminadmin-ajax-php-3/).
5
  Text Domain: wp-slimstat
6
  Requires at least: 3.8
7
  Tested up to: 4.8.2
8
+ Stable tag: 4.7.3
9
 
10
  == Description ==
11
  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.
71
  5. **Responsive layout** - Keep an eye on your reports on the go
72
 
73
  == Changelog ==
74
+ = 4.7.3 =
75
+ * [Fix] A [few users](https://wordpress.org/support/topic/cannot-install-maxmind-geolite-db/) pointed out a weird behavior when installing the MaxMind Geolocation data file, where an empty folder would be created instead of the actual file. If you still experience issues related to this problem, please make sure to delete the empty folder "maxmind.mmdb" under `wp-content/uploads/wp-slimstat/`.
76
+ * [Fix] Apparently Microsoft Security Essentials [was not pleased with our code](https://wordpress.org/support/topic/trojandownloader097m-donoff-detected-in-archive/), and was returning a false positive alert that a virus was included with the source code (thank you, Sasa).
77
+ * [Fix] The "content_id" filter could not be used in a shortcode to reference other pages (i.e. `[slimstat f='count-all' w='id']content_id equals 2012[/slimstat]`). Thank you, Felipe.
78
+ * [Fix] Country flags were not being displayed properly under certain circumstances (thank you, [Catmaniax](https://wordpress.org/support/topic/minor-issue-missing-png-file/)).
79
+ * [Fix] Bug preventing the new Heatmap Add-on from working as expected.
80
+
81
  = 4.7.2.2 =
82
  * [New] Added support for SCRIPT_DEBUG: by defining this constant in your `wp-config.php` will make Slimstat load the unminified version of the javascript tracker (thank you, Sasa)
83
  * [Update] Added new parameter to make the `admin-ajax.php` URL relative, to solve issues like [this one](https://wordpress.org/support/topic/xmlhttprequest-cannot-load-wp-adminadmin-ajax-php-3/).
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.2.2
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.2.2';
19
  public static $settings = array();
20
 
21
  public static $wpdb = '';
@@ -496,8 +496,8 @@ class wp_slimstat {
496
  $long_masked_user_other_ip = substr( self::dtr_pton( self::$stat[ 'other_ip' ] ), 0 , $cidr_mask );
497
 
498
  if ( $long_masked_user_ip === $long_masked_ip_to_ignore || $long_masked_user_other_ip === $long_masked_ip_to_ignore ) {
499
- self::$stat['id'] = -307;
500
- self::_set_error_array( sprintf( __('IP address %s is blacklisted', 'wp-slimstat'), self::$stat[ 'ip' ] . ( !empty( self::$stat[ 'other_ip' ] ) ? ' (' . self::$stat[ 'other_ip' ] . ')' : '' ) ), true );
501
  return $_argument;
502
  }
503
  }
@@ -509,20 +509,31 @@ class wp_slimstat {
509
  include_once ( plugin_dir_path( __FILE__ ) . 'maxmind.php' );
510
  $geolocation_data = maxmind_geolite2_connector::get_geolocation_info( self::$stat[ 'ip' ] );
511
 
 
 
512
  if ( !empty( $geolocation_data[ 'country' ][ 'iso_code' ] ) ) {
513
- self::$stat[ 'country' ] = strtolower( $geolocation_data[ 'country' ][ 'iso_code' ] );
514
- }
 
 
 
 
 
 
 
515
 
516
- if ( !empty( $geolocation_data[ 'city' ][ 'names' ][ 'en' ] ) ) {
517
- self::$stat[ 'city' ] = $geolocation_data[ 'city' ][ 'names' ][ 'en' ];
518
- }
519
 
520
- if ( !empty( $geolocation_data[ 'subdivisions' ][ 0 ][ 'iso_code' ] ) && !empty( self::$stat[ 'city' ] ) ) {
521
- self::$stat[ 'city' ] .= ' (' . $geolocation_data[ 'subdivisions' ][ 0 ][ 'iso_code' ] . ')';
522
- }
523
 
524
- if ( !empty( $geolocation_data[ 'location' ][ 'latitude' ] ) && !empty( $geolocation_data[ 'location' ][ 'longitude' ] ) ) {
525
- self::$stat[ 'location' ] = $geolocation_data[ 'location' ][ 'latitude' ] . ',' . $geolocation_data[ 'location' ][ 'longitude' ];
 
 
526
  }
527
 
528
  unset( $geolocation_data );
@@ -1159,16 +1170,30 @@ class wp_slimstat {
1159
  mkdir( dirname( self::$maxmind_path ) );
1160
  }
1161
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1162
  // Download the most recent database directly from MaxMind's repository
1163
  if ( !function_exists( 'download_url' ) ) {
1164
  require_once( ABSPATH . 'wp-admin/includes/file.php' );
1165
  }
1166
 
1167
  if ( self::$settings[ 'geolocation_country' ] == 'on' ) {
1168
- $maxmind_tmp = download_url( 'http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz', 5 );
1169
  }
1170
  else {
1171
- $maxmind_tmp = download_url( 'http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz', 25 );
1172
  }
1173
 
1174
  if ( is_wp_error( $maxmind_tmp ) ) {
@@ -1204,6 +1229,12 @@ class wp_slimstat {
1204
  @gzclose( $zh );
1205
  @fclose( $fh );
1206
 
 
 
 
 
 
 
1207
  @unlink( $maxmind_tmp );
1208
 
1209
  return '';
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.3
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.3';
19
  public static $settings = array();
20
 
21
  public static $wpdb = '';
496
  $long_masked_user_other_ip = substr( self::dtr_pton( self::$stat[ 'other_ip' ] ), 0 , $cidr_mask );
497
 
498
  if ( $long_masked_user_ip === $long_masked_ip_to_ignore || $long_masked_user_other_ip === $long_masked_ip_to_ignore ) {
499
+ self::$stat[ 'id' ] = -307;
500
+ self::_set_error_array( sprintf( __( 'IP address %s is blacklisted', 'wp-slimstat' ), self::$stat[ 'ip' ] . ( !empty( self::$stat[ 'other_ip' ] ) ? ' (' . self::$stat[ 'other_ip' ] . ')' : '' ) ), true );
501
  return $_argument;
502
  }
503
  }
509
  include_once ( plugin_dir_path( __FILE__ ) . 'maxmind.php' );
510
  $geolocation_data = maxmind_geolite2_connector::get_geolocation_info( self::$stat[ 'ip' ] );
511
 
512
+ // Invalid MaxMind data file
513
+
514
  if ( !empty( $geolocation_data[ 'country' ][ 'iso_code' ] ) ) {
515
+
516
+ if ( $geolocation_data[ 'country' ][ 'iso_code' ] == '99' ) {
517
+ self::$stat[ 'id' ] = -205;
518
+ self::_set_error_array( __( 'Your MaxMind data file is invalid', 'wp-slimstat' ), false );
519
+ return $_argument;
520
+ }
521
+ else {
522
+ self::$stat[ 'country' ] = strtolower( $geolocation_data[ 'country' ][ 'iso_code' ] );
523
+
524
 
525
+ if ( !empty( $geolocation_data[ 'city' ][ 'names' ][ 'en' ] ) ) {
526
+ self::$stat[ 'city' ] = $geolocation_data[ 'city' ][ 'names' ][ 'en' ];
527
+ }
528
 
529
+ if ( !empty( $geolocation_data[ 'subdivisions' ][ 0 ][ 'iso_code' ] ) && !empty( self::$stat[ 'city' ] ) ) {
530
+ self::$stat[ 'city' ] .= ' (' . $geolocation_data[ 'subdivisions' ][ 0 ][ 'iso_code' ] . ')';
531
+ }
532
 
533
+ if ( !empty( $geolocation_data[ 'location' ][ 'latitude' ] ) && !empty( $geolocation_data[ 'location' ][ 'longitude' ] ) ) {
534
+ self::$stat[ 'location' ] = $geolocation_data[ 'location' ][ 'latitude' ] . ',' . $geolocation_data[ 'location' ][ 'longitude' ];
535
+ }
536
+ }
537
  }
538
 
539
  unset( $geolocation_data );
1170
  mkdir( dirname( self::$maxmind_path ) );
1171
  }
1172
 
1173
+ if ( file_exists( self::$maxmind_path ) ) {
1174
+ if ( is_file( self::$maxmind_path ) ) {
1175
+ $is_deleted = @unlink( self::$maxmind_path );
1176
+ }
1177
+ else {
1178
+ // This should not happen, but hey...
1179
+ $is_deleted = @rmdir( self::$maxmind_path );
1180
+ }
1181
+
1182
+ if ( !$is_deleted ) {
1183
+ return __( "The geolocation database cannot be updated. Please check your server's file permissions and try again.", 'wp-slimstat' );
1184
+ }
1185
+ }
1186
+
1187
  // Download the most recent database directly from MaxMind's repository
1188
  if ( !function_exists( 'download_url' ) ) {
1189
  require_once( ABSPATH . 'wp-admin/includes/file.php' );
1190
  }
1191
 
1192
  if ( self::$settings[ 'geolocation_country' ] == 'on' ) {
1193
+ $maxmind_tmp = download_url( 'http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz', 10 );
1194
  }
1195
  else {
1196
+ $maxmind_tmp = download_url( 'http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz', 30 );
1197
  }
1198
 
1199
  if ( is_wp_error( $maxmind_tmp ) ) {
1229
  @gzclose( $zh );
1230
  @fclose( $fh );
1231
 
1232
+ if ( !is_file( self::$maxmind_path ) ) {
1233
+ // Something went wrong, maybe a folder was created instead of a regular file
1234
+ @rmdir( self::$maxmind_path );
1235
+ return __( 'There was an error creating the MaxMind Geolite DB.', 'wp-slimstat' );
1236
+ }
1237
+
1238
  @unlink( $maxmind_tmp );
1239
 
1240
  return '';