Slimstat Analytics - Version 4.1.1

Version Description

  • [Note] We are starting to hit the limits imposed by our current hosting provider, so it's time to move to a new more reliable server farm. We will be migrating our platform in the next few weeks, and this might cause some downtime for those trying to buy our premium add-ons. We apologize for the inconvenience.
  • [Update] Minor adjustments to our codebase to make Slimstat easily extensible. Now you can quickly add your own reports by just passing some simple information to the plugin. More information soon available on our knowledge base website.
  • [Update] Our premium add-on Export to Excel has been updated to be compatible with Slimstat 4.0.
  • [Fix] We took care of some other tenacious warnings displayed with DEBUG_MODE enabled.
Download this release

Release Info

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

Code changes from version 4.1 to 4.1.1

admin/config/addons.php CHANGED
@@ -9,7 +9,7 @@ if (!empty($_POST['licenses'])){
9
 
10
  $response = get_transient('wp_slimstat_addon_list');
11
  if (!empty($_GET['force_refresh']) || false === $response){
12
- $response = wp_remote_get('http://slimstat.getused.to.it/update-checker/', array('headers' => array('referer' => get_site_url())));
13
  if(is_wp_error($response) || $response['response']['code'] != 200){
14
  $error_message = is_wp_error($response)?$response->get_error_message():$response['response']['code'].' '. $response['response']['message'];
15
  echo '<p>'.__('There was an error retrieving the add-ons list from the server. Please try again later. Error Message:','wp-slimstat').' '.$error_message.'</p></div>';
9
 
10
  $response = get_transient('wp_slimstat_addon_list');
11
  if (!empty($_GET['force_refresh']) || false === $response){
12
+ $response = wp_remote_get('http://www.wp-slimstat.com/update-checker/', array('headers' => array('referer' => get_site_url())));
13
  if(is_wp_error($response) || $response['response']['code'] != 200){
14
  $error_message = is_wp_error($response)?$response->get_error_message():$response['response']['code'].' '. $response['response']['message'];
15
  echo '<p>'.__('There was an error retrieving the add-ons list from the server. Please try again later. Error Message:','wp-slimstat').' '.$error_message.'</p></div>';
admin/config/maintenance.php CHANGED
@@ -25,7 +25,7 @@ if (!empty($_REQUEST['action'])){
25
 
26
  case 'delete-records':
27
  $rows_affected = 0;
28
- if (key_exists($_POST['f'], wp_slimstat_db::$filters_names)){
29
  $rows_affected = wp_slimstat::$wpdb->query("
30
  DELETE t1.*
31
  FROM {$GLOBALS['wpdb']->prefix}slim_stats t1
@@ -258,7 +258,7 @@ $suffixes = array('bytes', 'KB', 'MB', 'GB', 'TB');
258
 
259
  <select name="f" id="slimstat-filter-name">
260
  <?php
261
- foreach (wp_slimstat_db::$filters_names as $a_filter_id => $a_filter_info){
262
  echo "<option value='$a_filter_id'>{$a_filter_info[0]}</option>";
263
  }
264
  ?>
25
 
26
  case 'delete-records':
27
  $rows_affected = 0;
28
+ if (key_exists($_POST['f'], wp_slimstat_db::$columns_names)){
29
  $rows_affected = wp_slimstat::$wpdb->query("
30
  DELETE t1.*
31
  FROM {$GLOBALS['wpdb']->prefix}slim_stats t1
258
 
259
  <select name="f" id="slimstat-filter-name">
260
  <?php
261
+ foreach (wp_slimstat_db::$columns_names as $a_filter_id => $a_filter_info){
262
  echo "<option value='$a_filter_id'>{$a_filter_info[0]}</option>";
263
  }
264
  ?>
admin/view/index.php CHANGED
@@ -6,7 +6,7 @@
6
  <form action="<?php echo wp_slimstat_reports::fs_url(); ?>" method="post" id="slimstat-filters-form">
7
  <fieldset id="slimstat-filters"><?php
8
  $filter_name_html = '<select name="f" id="slimstat-filter-name">';
9
- foreach (wp_slimstat_db::$filters_names as $a_filter_label => $a_filter_info){
10
  $filter_name_html .= "<option value='$a_filter_label'>{$a_filter_info[0]}</option>";
11
  }
12
  $filter_name_html .= '</select>';
6
  <form action="<?php echo wp_slimstat_reports::fs_url(); ?>" method="post" id="slimstat-filters-form">
7
  <fieldset id="slimstat-filters"><?php
8
  $filter_name_html = '<select name="f" id="slimstat-filter-name">';
9
+ foreach (wp_slimstat_db::$columns_names as $a_filter_label => $a_filter_info){
10
  $filter_name_html .= "<option value='$a_filter_label'>{$a_filter_info[0]}</option>";
11
  }
12
  $filter_name_html .= '</select>';
admin/view/right-now.php CHANGED
@@ -133,7 +133,7 @@ else {
133
  $base_host = $parse_url['host'];
134
  $base_url = '';
135
 
136
- if (!empty($results[$i]['resource'])){
137
  if (!empty($results[$i]['blog_id'])){
138
  $base_url = $parse_url['scheme'].'://'.$base_host;
139
  }
133
  $base_host = $parse_url['host'];
134
  $base_url = '';
135
 
136
+ if ( !empty( $results[$i]['resource'] ) ) {
137
  if (!empty($results[$i]['blog_id'])){
138
  $base_url = $parse_url['scheme'].'://'.$base_host;
139
  }
admin/view/wp-slimstat-db.php CHANGED
@@ -3,7 +3,7 @@
3
  // Let's define the main class with all the methods that we need
4
  class wp_slimstat_db {
5
  // Filters
6
- public static $filters_names = array();
7
  public static $filters_normalized = array();
8
 
9
  // Number and date formats
@@ -13,7 +13,7 @@ class wp_slimstat_db {
13
  public static $sql_where = array( 'columns' => '', 'time_range' => '' );
14
 
15
  // Filters that are not visible in the dropdown
16
- protected static $other_filters_names = array();
17
 
18
  /*
19
  * Sets the filters and other structures needed to store the data retrieved from the DB
@@ -31,7 +31,7 @@ class wp_slimstat_db {
31
  }
32
 
33
  // List of supported filters and their friendly names
34
- self::$filters_names = array(
35
  'no_filter_selected_1' => array( '&nbsp;', 'none' ),
36
  'browser' => array( __( 'Browser', 'wp-slimstat' ), 'varchar' ),
37
  'country' => array( __( 'Country Code', 'wp-slimstat' ), 'varchar' ),
@@ -64,7 +64,7 @@ class wp_slimstat_db {
64
  );
65
 
66
  // The following filters will not be displayed in the dropdown
67
- self::$other_filters_names = array(
68
  'minute' => array( __( 'Minute', 'wp-slimstat' ), 'int' ),
69
  'hour' => array( __( 'Hour', 'wp-slimstat' ), 'int' ),
70
  'day' => array( __( 'Day', 'wp-slimstat' ), 'int' ),
@@ -81,7 +81,7 @@ class wp_slimstat_db {
81
 
82
  // Misc Filters
83
  'strtotime' => array( 0, 'int' )
84
- );
85
 
86
  // Hook for the... filters
87
  $_filters = apply_filters( 'slimstat_db_pre_filters', $_filters );
@@ -120,7 +120,7 @@ class wp_slimstat_db {
120
  return '';
121
  }
122
 
123
- protected static function _get_combined_where( $_where = '', $_column = '*', $_use_time_range = true ) {
124
 
125
  if ( empty( $_where ) ) {
126
  if ( !empty( self::$sql_where[ 'columns' ] ) ) {
@@ -146,9 +146,9 @@ class wp_slimstat_db {
146
  }
147
  }
148
 
149
- if ( !empty( self::$filters_names[ $_column ] ) ) {
150
- $filter_empty = "$_column ".( ( self::$filters_names[ $_column ] [ 1 ] == 'varchar' ) ? 'IS NULL' : '= 0' );
151
- $filter_not_empty = "$_column ".( ( self::$filters_names[ $_column ] [ 1 ] == 'varchar' ) ? 'IS NOT NULL' : '<> 0' );
152
 
153
  if ( strpos( $_where, $filter_empty ) === false && strpos( $_where, $filter_not_empty) === false) {
154
  $_where = "$filter_not_empty AND $_where";
@@ -162,8 +162,8 @@ class wp_slimstat_db {
162
  * Translates user-friendly operators into SQL conditions
163
  */
164
  protected static function _get_single_where_clause( $_column = 'id', $_operator = 'equals', $_value = '' ) {
165
- $filter_empty = ( self::$filters_names[ $_column ] [ 1 ] == 'varchar' ) ? 'IS NULL' : '= 0';
166
- $filter_not_empty = ( self::$filters_names[ $_column ] [ 1 ] == 'varchar' ) ? 'IS NOT NULL' : '<> 0';
167
 
168
  switch( $_column ) {
169
  case 'ip':
@@ -286,18 +286,17 @@ class wp_slimstat_db {
286
 
287
  if ( !empty( $_filters ) ) {
288
  $matches = explode( '&&&', $_filters );
289
- $all_filters_names = self::$filters_names + self::$other_filters_names;
290
  foreach( $matches as $idx => $a_match ) {
291
  preg_match( '/([^\s]+)\s([^\s]+)\s(.+)?/', urldecode( $a_match ), $a_filter );
292
 
293
- if ( empty( $a_filter ) || ( ( !array_key_exists( $a_filter[ 1 ], $all_filters_names ) || strpos( $a_filter[ 1 ], 'no_filter' ) !== false ) && strpos( $a_filter[ 1 ], 'addon_' ) === false ) ) {
294
  continue;
295
  }
296
 
297
  switch( $a_filter[ 1 ] ) {
298
  case 'strtotime':
299
  $custom_date = strtotime( $a_filter[ 3 ].' UTC' );
300
- var_dump($custom_date);
301
  $filters_normalized[ 'date' ][ 'day' ] = date( 'j', $custom_date );
302
  $filters_normalized[ 'date' ][ 'month' ] = date( 'n', $custom_date );
303
  $filters_normalized[ 'date' ][ 'year' ] = date( 'Y', $custom_date );
@@ -520,7 +519,7 @@ var_dump($custom_date);
520
  // The following methods retrieve the information from the database
521
 
522
  public static function count_bouncing_pages() {
523
- $where = self::_get_combined_where( 'visit_id > 0 AND content_type <> "404"', 'resource' );
524
 
525
  return intval( self::_get_var( "
526
  SELECT COUNT(*) counthits
@@ -535,7 +534,7 @@ var_dump($custom_date);
535
  }
536
 
537
  public static function count_exit_pages() {
538
- $where = self::_get_combined_where( 'visit_id > 0', 'resource' );
539
 
540
  return intval( self::_get_var( "
541
  SELECT COUNT(*) counthits
@@ -551,7 +550,7 @@ var_dump($custom_date);
551
 
552
  public static function count_records( $_column = 'id', $_where = '', $_use_time_range = true ) {
553
  $distinct_column = ( $_column != 'id' ) ? "DISTINCT $_column" : $_column;
554
- $_where = self::_get_combined_where( $_where, $_column, $_use_time_range );
555
 
556
  return intval( self::_get_var( "
557
  SELECT COUNT($distinct_column) counthits
@@ -561,7 +560,7 @@ var_dump($custom_date);
561
  }
562
 
563
  public static function count_records_having( $_column = 'id', $_where = '', $_having = '' ) {
564
- $_where = self::_get_combined_where( $_where, $_column );
565
 
566
  return intval( self::_get_var( "
567
  SELECT COUNT(*) counthits FROM (
@@ -617,11 +616,11 @@ var_dump($custom_date);
617
 
618
  // Custom intervals don't have a comparison chart ('previous' range)
619
  if ( empty( self::$filters_normalized[ 'date' ][ 'interval' ] ) ) {
620
- $_where = self::_get_combined_where( $_where, '*', false );
621
  $previous_time_range = ' AND (dt BETWEEN '.$previous[ 'start' ].' AND '.$previous[ 'end' ].' OR dt BETWEEN '.self::$filters_normalized[ 'utime' ][ 'start' ].' AND '.self::$filters_normalized[ 'utime' ][ 'end' ].')';
622
  }
623
  else {
624
- $_where = self::_get_combined_where( $_where );
625
  $previous_time_range = '';
626
  }
627
 
@@ -695,7 +694,7 @@ var_dump($custom_date);
695
  }
696
 
697
  public static function get_max_and_average_pages_per_visit() {
698
- $where = self::_get_combined_where( 'visit_id > 0' );
699
 
700
  return self::_get_results( "
701
  SELECT AVG(ts1.counthits) AS avghits, MAX(ts1.counthits) AS maxhits FROM (
@@ -727,7 +726,7 @@ var_dump($custom_date);
727
  $_as_column = $_column;
728
  }
729
 
730
- $_where = self::_get_combined_where( $_where, $_column, $_use_time_range );
731
 
732
  if ( $_column == '*' ) {
733
  return self::_get_results( "
@@ -763,7 +762,7 @@ var_dump($custom_date);
763
  $_as_column = $_column;
764
  }
765
 
766
- $_where = self::_get_combined_where( $_where, $_as_column, $_use_time_range );
767
 
768
  return self::_get_results( "
769
  SELECT $_column, COUNT(*) counthits
@@ -779,7 +778,7 @@ var_dump($custom_date);
779
  }
780
 
781
  public static function get_top_complete( $_column = 'id', $_where = '', $_outer_select_column = '', $_aggr_function = 'MAX' ) {
782
- $_where = self::_get_combined_where( $_where, $_column );
783
 
784
  return self::_get_results( "
785
  SELECT $_outer_select_column, ts1.maxid, COUNT(*) counthits
3
  // Let's define the main class with all the methods that we need
4
  class wp_slimstat_db {
5
  // Filters
6
+ public static $columns_names = array();
7
  public static $filters_normalized = array();
8
 
9
  // Number and date formats
13
  public static $sql_where = array( 'columns' => '', 'time_range' => '' );
14
 
15
  // Filters that are not visible in the dropdown
16
+ public static $all_columns_names = array();
17
 
18
  /*
19
  * Sets the filters and other structures needed to store the data retrieved from the DB
31
  }
32
 
33
  // List of supported filters and their friendly names
34
+ self::$columns_names = array(
35
  'no_filter_selected_1' => array( '&nbsp;', 'none' ),
36
  'browser' => array( __( 'Browser', 'wp-slimstat' ), 'varchar' ),
37
  'country' => array( __( 'Country Code', 'wp-slimstat' ), 'varchar' ),
64
  );
65
 
66
  // The following filters will not be displayed in the dropdown
67
+ self::$all_columns_names = array_merge( array(
68
  'minute' => array( __( 'Minute', 'wp-slimstat' ), 'int' ),
69
  'hour' => array( __( 'Hour', 'wp-slimstat' ), 'int' ),
70
  'day' => array( __( 'Day', 'wp-slimstat' ), 'int' ),
81
 
82
  // Misc Filters
83
  'strtotime' => array( 0, 'int' )
84
+ ), self::$columns_names );
85
 
86
  // Hook for the... filters
87
  $_filters = apply_filters( 'slimstat_db_pre_filters', $_filters );
120
  return '';
121
  }
122
 
123
+ public static function get_combined_where( $_where = '', $_column = '*', $_use_time_range = true ) {
124
 
125
  if ( empty( $_where ) ) {
126
  if ( !empty( self::$sql_where[ 'columns' ] ) ) {
146
  }
147
  }
148
 
149
+ if ( !empty( self::$columns_names[ $_column ] ) ) {
150
+ $filter_empty = "$_column ".( ( self::$columns_names[ $_column ] [ 1 ] == 'varchar' ) ? 'IS NULL' : '= 0' );
151
+ $filter_not_empty = "$_column ".( ( self::$columns_names[ $_column ] [ 1 ] == 'varchar' ) ? 'IS NOT NULL' : '<> 0' );
152
 
153
  if ( strpos( $_where, $filter_empty ) === false && strpos( $_where, $filter_not_empty) === false) {
154
  $_where = "$filter_not_empty AND $_where";
162
  * Translates user-friendly operators into SQL conditions
163
  */
164
  protected static function _get_single_where_clause( $_column = 'id', $_operator = 'equals', $_value = '' ) {
165
+ $filter_empty = ( self::$columns_names[ $_column ] [ 1 ] == 'varchar' ) ? 'IS NULL' : '= 0';
166
+ $filter_not_empty = ( self::$columns_names[ $_column ] [ 1 ] == 'varchar' ) ? 'IS NOT NULL' : '<> 0';
167
 
168
  switch( $_column ) {
169
  case 'ip':
286
 
287
  if ( !empty( $_filters ) ) {
288
  $matches = explode( '&&&', $_filters );
 
289
  foreach( $matches as $idx => $a_match ) {
290
  preg_match( '/([^\s]+)\s([^\s]+)\s(.+)?/', urldecode( $a_match ), $a_filter );
291
 
292
+ if ( empty( $a_filter ) || ( ( !array_key_exists( $a_filter[ 1 ], self::$all_columns_names ) || strpos( $a_filter[ 1 ], 'no_filter' ) !== false ) && strpos( $a_filter[ 1 ], 'addon_' ) === false ) ) {
293
  continue;
294
  }
295
 
296
  switch( $a_filter[ 1 ] ) {
297
  case 'strtotime':
298
  $custom_date = strtotime( $a_filter[ 3 ].' UTC' );
299
+
300
  $filters_normalized[ 'date' ][ 'day' ] = date( 'j', $custom_date );
301
  $filters_normalized[ 'date' ][ 'month' ] = date( 'n', $custom_date );
302
  $filters_normalized[ 'date' ][ 'year' ] = date( 'Y', $custom_date );
519
  // The following methods retrieve the information from the database
520
 
521
  public static function count_bouncing_pages() {
522
+ $where = self::get_combined_where( 'visit_id > 0 AND content_type <> "404"', 'resource' );
523
 
524
  return intval( self::_get_var( "
525
  SELECT COUNT(*) counthits
534
  }
535
 
536
  public static function count_exit_pages() {
537
+ $where = self::get_combined_where( 'visit_id > 0', 'resource' );
538
 
539
  return intval( self::_get_var( "
540
  SELECT COUNT(*) counthits
550
 
551
  public static function count_records( $_column = 'id', $_where = '', $_use_time_range = true ) {
552
  $distinct_column = ( $_column != 'id' ) ? "DISTINCT $_column" : $_column;
553
+ $_where = self::get_combined_where( $_where, $_column, $_use_time_range );
554
 
555
  return intval( self::_get_var( "
556
  SELECT COUNT($distinct_column) counthits
560
  }
561
 
562
  public static function count_records_having( $_column = 'id', $_where = '', $_having = '' ) {
563
+ $_where = self::get_combined_where( $_where, $_column );
564
 
565
  return intval( self::_get_var( "
566
  SELECT COUNT(*) counthits FROM (
616
 
617
  // Custom intervals don't have a comparison chart ('previous' range)
618
  if ( empty( self::$filters_normalized[ 'date' ][ 'interval' ] ) ) {
619
+ $_where = self::get_combined_where( $_where, '*', false );
620
  $previous_time_range = ' AND (dt BETWEEN '.$previous[ 'start' ].' AND '.$previous[ 'end' ].' OR dt BETWEEN '.self::$filters_normalized[ 'utime' ][ 'start' ].' AND '.self::$filters_normalized[ 'utime' ][ 'end' ].')';
621
  }
622
  else {
623
+ $_where = self::get_combined_where( $_where );
624
  $previous_time_range = '';
625
  }
626
 
694
  }
695
 
696
  public static function get_max_and_average_pages_per_visit() {
697
+ $where = self::get_combined_where( 'visit_id > 0' );
698
 
699
  return self::_get_results( "
700
  SELECT AVG(ts1.counthits) AS avghits, MAX(ts1.counthits) AS maxhits FROM (
726
  $_as_column = $_column;
727
  }
728
 
729
+ $_where = self::get_combined_where( $_where, $_column, $_use_time_range );
730
 
731
  if ( $_column == '*' ) {
732
  return self::_get_results( "
762
  $_as_column = $_column;
763
  }
764
 
765
+ $_where = self::get_combined_where( $_where, $_as_column, $_use_time_range );
766
 
767
  return self::_get_results( "
768
  SELECT $_column, COUNT(*) counthits
778
  }
779
 
780
  public static function get_top_complete( $_column = 'id', $_where = '', $_outer_select_column = '', $_aggr_function = 'MAX' ) {
781
+ $_where = self::get_combined_where( $_where, $_column );
782
 
783
  return self::_get_results( "
784
  SELECT $_outer_select_column, ts1.maxid, COUNT(*) counthits
admin/view/wp-slimstat-reports.php CHANGED
@@ -77,10 +77,11 @@ class wp_slimstat_reports {
77
  self::$reports_info = array(
78
  'slim_p7_02' => array(
79
  'title' => __( 'Activity', 'wp-slimstat' ),
80
- 'callback' => 'show_activity_log',
81
  'callback_args' => array(
82
  'type' => 'recent',
83
- 'columns' => 'id'
 
84
  ),
85
  'classes' => array( 'tall' ),
86
  'screens' => array( 'wp-slim-view-1', 'raw' ),
@@ -89,10 +90,10 @@ class wp_slimstat_reports {
89
 
90
  'slim_p1_01' => array(
91
  'title' => __( 'Pageviews', 'wp-slimstat' ),
92
- 'callback' => 'show_chart',
93
  'callback_args' => array(
94
  'chart_data' => wp_slimstat_db::get_data_for_chart( 'COUNT(ip)', 'COUNT(DISTINCT(ip))' ),
95
- 'chart_labels' => array( __( 'Pageviews', 'wp-slimstat' ), __( 'Unique IPs', 'wp-slimstat' ) )
96
  ),
97
  'classes' => array( 'wide', 'chart' ),
98
  'screens' => array( 'wp-slim-view-2', 'dashboard' ),
@@ -100,24 +101,25 @@ class wp_slimstat_reports {
100
  ),
101
  'slim_p1_02' => array(
102
  'title' => __( 'About Slimstat', 'wp-slimstat' ),
103
- 'callback' => 'show_about_wpslimstat',
104
  'classes' => array( 'normal', 'hidden' ),
105
  'screens' => array( 'wp-slim-view-2' )
106
  ),
107
  'slim_p1_03' => array(
108
  'title' => __( 'At a Glance', 'wp-slimstat' ),
109
- 'callback' => 'show_overview_summary',
110
  'classes' => array( 'normal' ),
111
  'screens' => array( 'wp-slim-view-2', 'dashboard' )
112
  ),
113
  'slim_p1_04' => array(
114
  'title' => __( 'Currently Online', 'wp-slimstat' ),
115
- 'callback' => 'raw_results_to_html',
116
  'callback_args' => array(
117
  'type' => 'recent',
118
  'columns' => 'username',
119
  'where' => 'dt > '. ( date_i18n( 'U' ) - 300 ),
120
- 'use_date_filters' => false
 
121
  ),
122
  'classes' => array( 'normal' ),
123
  'screens' => array( 'wp-slim-view-2', 'dashboard', 'raw' ),
@@ -125,10 +127,11 @@ class wp_slimstat_reports {
125
  ),
126
  'slim_p1_06' => array(
127
  'title' => __( 'Recent Search Terms', 'wp-slimstat' ),
128
- 'callback' => 'raw_results_to_html',
129
  'callback_args' => array(
130
  'type' => 'recent',
131
- 'columns' => 'searchterms'
 
132
  ),
133
  'classes' => array( 'normal' ),
134
  'screens' => array( 'wp-slim-view-2', 'wp-slim-view-5', 'raw' ),
@@ -136,12 +139,13 @@ class wp_slimstat_reports {
136
  ),
137
  'slim_p1_08' => array(
138
  'title' => __( 'Top Pages', 'wp-slimstat' ),
139
- 'callback' => 'raw_results_to_html',
140
  'callback_args' => array(
141
  'type' => 'top',
142
  'columns' => 'SUBSTRING_INDEX(resource, "' . ( !get_option( 'permalink_structure' ) ? '&' : '?' ) . '", 1)',
143
  'as_column' => 'resource',
144
- 'filter_op' => 'contains'
 
145
  ),
146
  'classes' => array( 'normal' ),
147
  'screens' => array( 'wp-slim-view-2', 'dashboard', 'raw' ),
@@ -149,41 +153,45 @@ class wp_slimstat_reports {
149
  ),
150
  'slim_p1_10' => array(
151
  'title' => __('Top Traffic Sources', 'wp-slimstat'),
152
- 'callback' => 'raw_results_to_html',
153
  'callback_args' => array(
154
  'type' => 'top',
155
  'columns' => 'referer',
156
- 'where' => 'referer NOT LIKE "%' . home_url() . '%"'
 
157
  ),
158
  'classes' => array( 'normal' ),
159
  'screens' => array( 'wp-slim-view-2', 'wp-slim-view-5', 'dashboard', 'raw' )
160
  ),
161
  'slim_p1_11' => array(
162
  'title' => __( 'Top Known Visitors', 'wp-slimstat' ),
163
- 'callback' => 'raw_results_to_html',
164
  'callback_args' => array(
165
  'type' => 'top',
166
- 'columns' => 'username'
 
167
  ),
168
  'classes' => array( 'normal', 'hidden' ),
169
  'screens' => array( 'wp-slim-view-2', 'dashboard', 'raw' )
170
  ),
171
  'slim_p1_12' => array(
172
  'title' => __( 'Top Search Terms', 'wp-slimstat' ),
173
- 'callback' => 'raw_results_to_html',
174
  'callback_args' => array(
175
  'type' => 'top',
176
- 'columns' => 'searchterms'
 
177
  ),
178
  'classes' => array( 'normal' ),
179
  'screens' => array( 'wp-slim-view-2', 'wp-slim-view-4', 'wp-slim-view-5', 'dashboard', 'raw' )
180
  ),
181
  'slim_p1_13' => array(
182
  'title' => __( 'Top Countries', 'wp-slimstat' ),
183
- 'callback' => 'raw_results_to_html',
184
  'callback_args' => array(
185
  'type' => 'top',
186
- 'columns' => 'country'
 
187
  ),
188
  'classes' => array( 'normal', 'hidden' ),
189
  'screens' => array( 'wp-slim-view-2', 'wp-slim-view-3', 'wp-slim-view-5', 'dashboard', 'raw' ),
@@ -191,19 +199,20 @@ class wp_slimstat_reports {
191
  ),
192
  'slim_p1_15' => array(
193
  'title' => __( 'Rankings', 'wp-slimstat' ),
194
- 'callback' => 'show_rankings',
195
  'classes' => array( 'normal' ),
196
  'screens' => array( 'wp-slim-view-2' ),
197
  'tooltip' => __( "Slimstat retrieves live information from Alexa, Facebook and Google, to measures your site's rankings. Values are updated every 12 hours. Filters set above don't apply to this report.", 'wp-slimstat' )
198
  ),
199
  'slim_p1_17' => array(
200
  'title' => __( 'Top Language Families', 'wp-slimstat' ),
201
- 'callback' => 'raw_results_to_html',
202
  'callback_args' => array(
203
  'type' => 'top',
204
  'columns' => 'SUBSTRING(language, 1, 2)',
205
  'as_column' => 'language',
206
- 'filter_op' => 'contains'
 
207
  ),
208
  'classes' => array( 'normal', 'hidden' ),
209
  'screens' => array( 'wp-slim-view-2', 'raw' )
@@ -211,10 +220,11 @@ class wp_slimstat_reports {
211
 
212
  'slim_p2_01' => array(
213
  'title' => __( 'Human Visits', 'wp-slimstat' ),
214
- 'callback' => 'show_chart',
215
  'callback_args' => array(
216
  'chart_data' => wp_slimstat_db::get_data_for_chart( 'COUNT(DISTINCT visit_id)', 'COUNT(DISTINCT ip)', '(visit_id > 0 AND browser_type <> 1)' ),
217
- 'chart_labels' => array( __( 'Visits', 'wp-slimstat' ), __( 'Unique IPs', 'wp-slimstat' ) )
 
218
  ),
219
  'classes' => array( 'wide', 'chart' ),
220
  'screens' => array( 'wp-slim-view-3' ),
@@ -222,37 +232,40 @@ class wp_slimstat_reports {
222
  ),
223
  'slim_p2_02' => array(
224
  'title' => __( 'Audience Overview', 'wp-slimstat' ),
225
- 'callback' => 'show_visitors_summary',
226
  'classes' => array( 'normal' ),
227
  'screens' => array( 'wp-slim-view-3', 'dashboard' ),
228
  'tooltip' => __( 'Where not otherwise specified, the metrics in this report are referred to human visitors.', 'wp-slimstat' )
229
  ),
230
  'slim_p2_03' => array(
231
  'title' => __( 'Top Languages', 'wp-slimstat' ),
232
- 'callback' => 'raw_results_to_html',
233
  'callback_args' => array(
234
  'type' => 'top',
235
- 'columns' => 'language'
 
236
  ),
237
  'classes' => array( 'normal' ),
238
  'screens' => array( 'wp-slim-view-3', 'raw' )
239
  ),
240
  'slim_p2_04' => array(
241
  'title' => __( 'Top Browsers', 'wp-slimstat', 'dashboard' ),
242
- 'callback' => 'raw_results_to_html',
243
  'callback_args' => array(
244
  'type' => 'top',
245
- 'columns' => 'browser, browser_version'
 
246
  ),
247
  'classes' => array( 'normal' ),
248
  'screens' => array( 'wp-slim-view-3', 'raw' )
249
  ),
250
  'slim_p2_05' => array(
251
  'title' => __( 'Top Service Providers', 'wp-slimstat' ),
252
- 'callback' => 'raw_results_to_html',
253
  'callback_args' => array(
254
  'type' => 'top',
255
- 'columns' => 'ip'
 
256
  ),
257
  'classes' => array( 'wide', 'hidden' ),
258
  'screens' => array( 'wp-slim-view-3', 'raw' ),
@@ -260,10 +273,11 @@ class wp_slimstat_reports {
260
  ),
261
  'slim_p2_06' => array(
262
  'title' => __( 'Top Operating Systems', 'wp-slimstat' ),
263
- 'callback' => 'raw_results_to_html',
264
  'callback_args' => array(
265
  'type' => 'top',
266
- 'columns' => 'platform'
 
267
  ),
268
  'classes' => array( 'normal', 'hidden' ),
269
  'screens' => array( 'wp-slim-view-3', 'raw' ),
@@ -271,82 +285,89 @@ class wp_slimstat_reports {
271
  ),
272
  'slim_p2_07' => array(
273
  'title' => __( 'Top Screen Resolutions', 'wp-slimstat' ),
274
- 'callback' => 'raw_results_to_html',
275
  'callback_args' => array(
276
  'type' => 'top',
277
- 'columns' => 'resolution'
 
278
  ),
279
  'classes' => array( 'normal' ),
280
  'screens' => array( 'wp-slim-view-3', 'dashboard', 'raw' )
281
  ),
282
  'slim_p2_09' => array(
283
  'title' => __( 'Browser Capabilities', 'wp-slimstat' ),
284
- 'callback' => 'show_plugins',
285
  'classes' => array( 'normal', 'hidden' ),
286
- 'screens' => array( 'wp-slim-view-3', 'raw' )
287
  ),
288
  'slim_p2_12' => array(
289
  'title' => __( 'Visit Duration', 'wp-slimstat' ),
290
- 'callback' => 'show_visit_duration',
291
  'classes' => array( 'normal', 'hidden' ),
292
  'screens' => array( 'wp-slim-view-3' )
293
  ),
294
  'slim_p2_13' => array(
295
  'title' => __( 'Recent Countries', 'wp-slimstat' ),
296
- 'callback' => 'raw_results_to_html',
297
  'callback_args' => array(
298
  'type' => 'recent',
299
- 'columns' => 'country'
 
300
  ),
301
  'classes' => array( 'normal', 'hidden' ),
302
  'screens' => array( 'wp-slim-view-3', 'wp-slim-view-5', 'raw' )
303
  ),
304
  'slim_p2_14' => array(
305
  'title' => __( 'Recent Screen Resolutions', 'wp-slimstat' ),
306
- 'callback' => 'raw_results_to_html',
307
  'callback_args' => array(
308
  'type' => 'recent',
309
- 'columns' => 'resolution'
 
310
  ),
311
  'classes' => array( 'normal', 'hidden' ),
312
  'screens' => array( 'wp-slim-view-3', 'raw' )
313
  ),
314
  'slim_p2_15' => array(
315
  'title' => __( 'Recent Operating Systems', 'wp-slimstat' ),
316
- 'callback' => 'raw_results_to_html',
317
  'callback_args' => array(
318
  'type' => 'recent',
319
- 'columns' => 'platform'
 
320
  ),
321
  'classes' => array( 'normal', 'hidden' ),
322
  'screens' => array( 'wp-slim-view-3', 'raw' )
323
  ),
324
  'slim_p2_16' => array(
325
  'title' => __( 'Recent Browsers', 'wp-slimstat' ),
326
- 'callback' => 'raw_results_to_html',
327
  'callback_args' => array(
328
  'type' => 'recent',
329
- 'columns' => 'browser, browser_version'
 
330
  ),
331
  'classes' => array( 'normal', 'hidden' ),
332
  'screens' => array( 'wp-slim-view-3', 'raw' )
333
  ),
334
  'slim_p2_17' => array(
335
  'title' => __( 'Recent Languages', 'wp-slimstat' ),
336
- 'callback' => 'raw_results_to_html',
337
  'callback_args' => array(
338
  'type' => 'recent',
339
- 'columns' => 'language'
 
340
  ),
341
  'classes' => array( 'normal', 'hidden' ),
342
  'screens' => array( 'wp-slim-view-3', 'raw' )
343
  ),
344
  'slim_p2_18' => array(
345
  'title' => __( 'Top Browser Families', 'wp-slimstat' ),
346
- 'callback' => 'raw_results_to_html',
347
  'callback_args' => array(
348
  'type' => 'top',
349
- 'columns' => 'browser'
 
350
  ),
351
  'classes' => array( 'normal', 'hidden' ),
352
  'screens' => array( 'wp-slim-view-3', 'raw' ),
@@ -354,12 +375,13 @@ class wp_slimstat_reports {
354
  ),
355
  'slim_p2_19' => array(
356
  'title' => __( 'Top OS Families', 'wp-slimstat' ),
357
- 'callback' => 'raw_results_to_html',
358
  'callback_args' => array(
359
  'type' => 'top',
360
  'columns' => 'CONCAT("p-", SUBSTRING(platform, 1, 3))',
361
  'as_column' => 'platform',
362
- 'filter_op' => 'contains'
 
363
  ),
364
  'classes' => array( 'normal' ),
365
  'screens' => array( 'wp-slim-view-3', 'raw' ),
@@ -367,22 +389,24 @@ class wp_slimstat_reports {
367
  ),
368
  'slim_p2_20' => array(
369
  'title' => __( 'Recent Users', 'wp-slimstat' ),
370
- 'callback' => 'raw_results_to_html',
371
  'callback_args' => array(
372
  'type' => 'recent',
373
  'columns' => 'username',
374
- 'where' => 'notes LIKE "%user:%"'
 
375
  ),
376
  'classes' => array( 'normal' ),
377
  'screens' => array( 'wp-slim-view-3', 'raw' )
378
  ),
379
  'slim_p2_21' => array(
380
  'title' => __( 'Top Users', 'wp-slimstat' ),
381
- 'callback' => 'raw_results_to_html',
382
  'callback_args' => array(
383
  'type' => 'top',
384
  'columns' => 'username',
385
- 'where' => 'notes LIKE "%user:%"'
 
386
  ),
387
  'classes' => array( 'normal', 'hidden' ),
388
  'screens' => array( 'wp-slim-view-3', 'dashboard', 'raw' )
@@ -390,7 +414,7 @@ class wp_slimstat_reports {
390
 
391
  'slim_p3_01' => array(
392
  'title' => __( 'Traffic Sources', 'wp-slimstat' ),
393
- 'callback' => 'show_chart',
394
  'callback_args' => array(
395
  'chart_data' => wp_slimstat_db::get_data_for_chart( 'COUNT(DISTINCT(referer))', 'COUNT(DISTINCT(ip))', '(referer IS NOT NULL AND referer NOT LIKE "%' . home_url() . '%")' ),
396
  'chart_labels' => array( __( 'Domains', 'wp-slimstat' ), __( 'Unique IPs', 'wp-slimstat' ) )
@@ -401,27 +425,29 @@ class wp_slimstat_reports {
401
  ),
402
  'slim_p3_02' => array(
403
  'title' => __( 'Summary', 'wp-slimstat' ),
404
- 'callback' => 'show_traffic_sources_summary',
405
  'classes' => array( 'normal' ),
406
  'screens' => array( 'wp-slim-view-5' )
407
  ),
408
  'slim_p3_06' => array(
409
  'title' => __( 'Top Referring Search Engines', 'wp-slimstat' ),
410
- 'callback' => 'raw_results_to_html',
411
  'callback_args' => array(
412
  'type' => 'top',
413
  'columns' => 'referer',
414
- 'where' => "searchterms IS NOT NULL AND referer NOT LIKE '%".home_url()."%'"
 
415
  ),
416
  'classes' => array( 'normal' ),
417
  'screens' => array( 'wp-slim-view-5', 'dashboard', 'raw' )
418
  ),
419
  'slim_p3_11' => array(
420
  'title' => __( 'Recent Exit Pages', 'wp-slimstat' ),
421
- 'callback' => 'raw_results_to_html',
422
  'callback_args' => array(
423
  'type' => 'recent',
424
- 'columns' => 'visit_id' // raw_results_to_html knows to display the resource, when the column is visit_id
 
425
  ),
426
  'classes' => array( 'normal' ),
427
  'screens' => array( 'wp-slim-view-5', 'raw' )
@@ -430,7 +456,8 @@ class wp_slimstat_reports {
430
  /*
431
  'slim_p4_01' => array(
432
  'title' => __( 'Recent Outbound Links', 'wp-slimstat' ),
433
- 'callback' => 'raw_results_to_html',
 
434
  'classes' => array( 'wide' ),
435
  'screens' => array( 'wp-slim-view-4', 'raw' ),
436
  'tooltip' => ''
@@ -438,23 +465,25 @@ class wp_slimstat_reports {
438
  */
439
  'slim_p4_02' => array(
440
  'title' => __( 'Recent Posts', 'wp-slimstat' ),
441
- 'callback' => 'raw_results_to_html',
442
  'callback_args' => array(
443
  'type' => 'recent',
444
  'columns' => 'resource',
445
- 'where' => 'content_type => "post"'
 
446
  ),
447
  'classes' => array( 'normal' ),
448
  'screens' => array( 'wp-slim-view-4', 'raw' )
449
  ),
450
  'slim_p4_03' => array(
451
  'title' => __( 'Recent Bounce Pages', 'wp-slimstat' ),
452
- 'callback' => 'raw_results_to_html',
453
  'callback_args' => array(
454
  'type' => 'recent',
455
  'columns' => 'resource',
456
  'where' => 'content_type <> "404"',
457
- 'having' => 'HAVING COUNT(visit_id) => 1'
 
458
  ),
459
  'classes' => array( 'normal', 'hidden' ),
460
  'screens' => array( 'wp-slim-view-4', 'raw' ),
@@ -462,33 +491,36 @@ class wp_slimstat_reports {
462
  ),
463
  'slim_p4_04' => array(
464
  'title' => __( 'Recent Feeds', 'wp-slimstat' ),
465
- 'callback' => 'raw_results_to_html',
466
  'callback_args' => array(
467
  'type' => 'recent',
468
  'columns' => 'resource',
469
- 'where' => '(resource LIKE "%/feed%" OR resource LIKE "%?feed=>%" OR resource LIKE "%&feed=>%" OR content_type LIKE "%feed%")'
 
470
  ),
471
  'classes' => array( 'normal', 'hidden' ),
472
  'screens' => array( 'wp-slim-view-4', 'raw' )
473
  ),
474
  'slim_p4_05' => array(
475
  'title' => __( 'Recent Pages Not Found', 'wp-slimstat' ),
476
- 'callback' => 'raw_results_to_html',
477
  'callback_args' => array(
478
  'type' => 'recent',
479
  'columns' => 'resource',
480
- 'where' => '(resource LIKE "[404]%" OR content_type LIKE "%404%")'
 
481
  ),
482
  'classes' => array( 'normal' ),
483
  'screens' => array( 'wp-slim-view-4', 'raw' )
484
  ),
485
  'slim_p4_06' => array(
486
  'title' => __( 'Recent Internal Searches', 'wp-slimstat' ),
487
- 'callback' => 'raw_results_to_html',
488
  'callback_args' => array(
489
  'type' => 'recent',
490
  'columns' => 'searchterms',
491
- 'where' => 'content_type LIKE "%search%"'
 
492
  ),
493
  'classes' => array( 'normal', 'hidden' ),
494
  'screens' => array( 'wp-slim-view-4', 'raw' ),
@@ -496,11 +528,12 @@ class wp_slimstat_reports {
496
  ),
497
  'slim_p4_07' => array(
498
  'title' => __( 'Top Categories', 'wp-slimstat' ),
499
- 'callback' => 'raw_results_to_html',
500
  'callback_args' => array(
501
  'type' => 'top',
502
  'columns' => 'category',
503
- 'where' => 'content_type LIKE "%category%"'
 
504
  ),
505
  'classes' => array( 'normal', 'raw' ),
506
  'screens' => array( 'wp-slim-view-4', 'dashboard' )
@@ -509,9 +542,9 @@ class wp_slimstat_reports {
509
  NOTE TO SELF: don't forget to remove from deprecated, when implemented
510
  'slim_p4_09' => array(
511
  'title' => __( 'Top Downloads', 'wp-slimstat' ),
512
- 'callback' => 'raw_results_to_html',
513
  'callback_args' => array(
514
-
515
  ),
516
  'classes' => array( 'normal', 'hidden' ),
517
  'screens' => array( 'wp-slim-view-4', 'raw' ),
@@ -519,9 +552,10 @@ class wp_slimstat_reports {
519
  ),
520
  'slim_p4_10' => array(
521
  'title' => __( 'Recent Events', 'wp-slimstat' ),
522
- 'callback' => 'raw_results_to_html',
523
  'callback_args' => array(
524
 
 
525
  ),
526
  'classes' => array( 'normal', 'hidden' ),
527
  'screens' => array( 'wp-slim-view-4', 'raw' ),
@@ -530,102 +564,111 @@ class wp_slimstat_reports {
530
  */
531
  'slim_p4_11' => array(
532
  'title' => __( 'Top Posts', 'wp-slimstat' ),
533
- 'callback' => 'raw_results_to_html',
534
  'callback_args' => array(
535
  'type' => 'top',
536
  'columns' => 'resource',
537
- 'where' => 'content_type => "post"'
 
538
  ),
539
  'classes' => array( 'normal' ),
540
  'screens' => array( 'wp-slim-view-4', 'raw' )
541
  ),
542
  'slim_p4_13' => array(
543
  'title' => __( 'Top Internal Searches', 'wp-slimstat' ),
544
- 'callback' => 'raw_results_to_html',
545
  'callback_args' => array(
546
  'type' => 'top',
547
  'columns' => 'searchterms',
548
- 'where' => 'content_type LIKE "%search%"'
 
549
  ),
550
  'classes' => array( 'normal', 'hidden' ),
551
  'screens' => array( 'wp-slim-view-4', 'raw' )
552
  ),
553
  'slim_p4_15' => array(
554
  'title' => __( 'Recent Categories', 'wp-slimstat' ),
555
- 'callback' => 'raw_results_to_html',
556
  'callback_args' => array(
557
  'type' => 'recent',
558
  'columns' => 'resource',
559
- 'where' => '(content_type => "category" OR content_type => "tag")'
 
560
  ),
561
  'classes' => array( 'normal', 'hidden' ),
562
  'screens' => array( 'wp-slim-view-4', 'raw' )
563
  ),
564
  'slim_p4_16' => array(
565
  'title' => __( 'Top Pages Not Found', 'wp-slimstat' ),
566
- 'callback' => 'raw_results_to_html',
567
  'callback_args' => array(
568
  'type' => 'top',
569
  'columns' => 'resource',
570
- 'where' => 'content_type LIKE "%404%"'
 
571
  ),
572
  'classes' => array( 'normal' ),
573
  'screens' => array( 'wp-slim-view-4', 'raw' )
574
  ),
575
  'slim_p4_18' => array(
576
  'title' => __( 'Top Authors', 'wp-slimstat' ),
577
- 'callback' => 'raw_results_to_html',
578
  'callback_args' => array(
579
  'type' => 'top',
580
- 'columns' => 'author'
 
581
  ),
582
  'classes' => array( 'normal' ),
583
  'screens' => array( 'wp-slim-view-4', 'dashboard', 'raw' )
584
  ),
585
  'slim_p4_19' => array(
586
  'title' => __( 'Top Tags', 'wp-slimstat' ),
587
- 'callback' => 'raw_results_to_html',
588
  'callback_args' => array(
589
  'type' => 'top',
590
  'columns' => 'category',
591
- 'where' => '(content_type LIKE "%tag%")'
 
592
  ),
593
  'classes' => array( 'normal', 'hidden' ),
594
  'screens' => array( 'wp-slim-view-4', 'raw' )
595
  ),
596
  'slim_p4_20' => array(
597
  'title' => __( 'Recent Downloads', 'wp-slimstat' ),
598
- 'callback' => 'raw_results_to_html',
599
  'callback_args' => array(
600
 
 
601
  ),
602
  'classes' => array( 'wide', 'hidden' ),
603
  'screens' => array( 'wp-slim-view-4', 'raw' )
604
  ),
605
  'slim_p4_21' => array(
606
  'title' => __( 'Top Outbound Links', 'wp-slimstat' ),
607
- 'callback' => 'raw_results_to_html',
608
  'callback_args' => array(
609
 
 
610
  ),
611
  'classes' => array( 'normal', 'hidden' ),
612
  'screens' => array( 'wp-slim-view-4', 'raw' )
613
  ),
614
  'slim_p4_22' => array(
615
  'title' => __( 'Your Website', 'wp-slimstat' ),
616
- 'callback' => 'show_your_blog',
617
  'classes' => array( 'normal', 'hidden' ),
618
- 'screens' => array( 'wp-slim-view-4', 'raw' ),
619
  'tooltip' => __( 'Your content at a glance: posts, comments, pingbacks, etc. Please note that this report is not affected by the filters set here above.', 'wp-slimstat' )
620
  ),
621
  'slim_p4_23' => array(
622
  'title' => __( 'Top Bounce Pages', 'wp-slimstat' ),
623
- 'callback' => 'raw_results_to_html',
624
  'callback_args' => array(
625
  'type' => 'top',
626
  'columns' => 'resource',
627
  'where' => 'content_type <> "404"',
628
- 'having' => 'HAVING COUNT(visit_id) => 1'
 
629
  ),
630
  'classes' => array( 'normal', 'hidden' ),
631
  'screens' => array( 'wp-slim-view-4', 'raw' )
@@ -633,24 +676,26 @@ class wp_slimstat_reports {
633
  /* NOTE TO SELF: remove them from deprecated, when reimplemented
634
  'slim_p4_24' => array(
635
  'title' => __( 'Top Exit Pages', 'wp-slimstat' ),
636
- 'callback' => 'raw_results_to_html',
637
  'callback_args' => array(
638
  'type' => 'top_complete',
639
  'columns' => 'visit_id',
640
  'outer_select_column' => 'resource',
641
- 'aggr_function' => 'MAX'
 
642
  ),
643
  'classes' => array( 'normal', 'hidden' ),
644
  'screens' => array( 'wp-slim-view-4', 'raw' )
645
  ),
646
  'slim_p4_25' => array(
647
  'title' => __( 'Top Entry Pages', 'wp-slimstat' ),
648
- 'callback' => 'raw_results_to_html',
649
  'callback_args' => array(
650
  'type' => 'top_complete',
651
  'columns' => 'visit_id',
652
  'outer_select_column' => 'resource',
653
- 'aggr_function' => 'MIN'
 
654
  ),
655
  'classes' => array( 'normal', 'hidden' ),
656
  'screens' => array( 'wp-slim-view-4', 'raw' )
@@ -659,7 +704,7 @@ class wp_slimstat_reports {
659
 
660
  'slim_p6_01' => array(
661
  'title' => __( 'World Map', 'wp-slimstat' ),
662
- 'callback' => 'show_world_map',
663
  'classes' => array( 'tall' ),
664
  'screens' => array( 'wp-slim-view-6' ),
665
  'tooltip' => ''
@@ -715,7 +760,7 @@ class wp_slimstat_reports {
715
  if ( !empty( $hidden_reports ) && is_array( $hidden_reports ) ) {
716
  foreach ( self::$reports_info as $a_report_id => $a_report_info ) {
717
  if ( in_array( $a_report_id, $hidden_reports ) ) {
718
- if ( !in_array( 'hidden', $a_report_info[ 'classes' ] ) ) {
719
  self::$reports_info[ $a_report_id ][ 'classes' ][] = 'hidden';
720
  }
721
  }
@@ -791,6 +836,20 @@ class wp_slimstat_reports {
791
  return array();
792
  }
793
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
794
  switch ( $_args[ 'type' ] ) {
795
  case 'recent':
796
  $all_results = wp_slimstat_db::get_recent( $_args[ 'columns' ], $_args[ 'where' ], $_args[ 'having' ], $_args[ 'use_date_filters' ], $_args['as_column'] );
@@ -819,11 +878,11 @@ class wp_slimstat_reports {
819
  public static function callback_wrapper() {
820
  $_args = self::_check_args( func_get_args() );
821
 
822
- call_user_func( array( __CLASS__, $_args[ 'callback' ] ), $_args[ 'callback_args' ] );
823
  }
824
 
825
  public static function raw_results_to_html( $_args = array() ){
826
- $all_results = self::get_raw_results( $_args );
827
 
828
  $results = array_slice(
829
  $all_results,
@@ -1501,12 +1560,12 @@ class wp_slimstat_reports {
1501
 
1502
  if (!empty($filters_dropdown)){
1503
  foreach($filters_dropdown as $a_filter_label => $a_filter_details){
1504
- if (!array_key_exists($a_filter_label, wp_slimstat_db::$filters_names) || strpos($a_filter_label, 'no_filter') !== false){
1505
  continue;
1506
  }
1507
 
1508
  $a_filter_value_no_slashes = htmlentities(str_replace('\\','', $a_filter_details[1]), ENT_QUOTES, 'UTF-8');
1509
- $filters_html .= "<li>".strtolower(wp_slimstat_db::$filters_names[$a_filter_label][ 0 ]).' '.__(str_replace('_', ' ', $a_filter_details[0]),'wp-slimstat')." $a_filter_value_no_slashes <a class='slimstat-remove-filter slimstat-font-cancel' title='".htmlentities(__('Remove filter for','wp-slimstat'), ENT_QUOTES, 'UTF-8').' '.wp_slimstat_db::$filters_names[ $a_filter_label ][ 0 ]."' href='".self::fs_url("$a_filter_label equals ")."'></a></li>";
1510
  }
1511
  }
1512
  if (!empty($filters_html)){
@@ -1627,30 +1686,26 @@ class wp_slimstat_reports {
1627
  $_args = array_merge( array(
1628
  'title' => '',
1629
  'callback' => '',
1630
- 'callback_args' => '',
1631
- 'classes' => '',
1632
- 'screens' => '',
 
1633
  'tooltip' => ''
1634
  ), self::$reports_info[ $report_id ] );
1635
  }
1636
 
1637
- if ( !empty( self::$reports_info[ $report_id ][ 'callback_args' ] ) && is_array( self::$reports_info[ $report_id ][ 'callback_args' ] ) ) {
1638
- // Default values
1639
- $_args[ 'callback_args' ] = array_merge( array(
1640
- 'type' => '',
1641
- 'columns' => '',
1642
- 'where' => '',
1643
- 'having' => '',
1644
- 'as_column' => '',
1645
- 'filter_op' => 'equals',
1646
- 'outer_select_column' => '',
1647
- 'aggr_function' => 'MAX',
1648
- 'use_date_filters' => true,
1649
- 'echo' => true
1650
- ), self::$reports_info[ $report_id ][ 'callback_args' ] );
1651
- }
1652
-
1653
- $_args[ 'id' ] = $report_id;
1654
 
1655
  return $_args;
1656
  }
77
  self::$reports_info = array(
78
  'slim_p7_02' => array(
79
  'title' => __( 'Activity', 'wp-slimstat' ),
80
+ 'callback' => array( __CLASS__, 'show_activity_log' ),
81
  'callback_args' => array(
82
  'type' => 'recent',
83
+ 'columns' => 'id',
84
+ 'raw' => array( __CLASS__, 'get_raw_results' )
85
  ),
86
  'classes' => array( 'tall' ),
87
  'screens' => array( 'wp-slim-view-1', 'raw' ),
90
 
91
  'slim_p1_01' => array(
92
  'title' => __( 'Pageviews', 'wp-slimstat' ),
93
+ 'callback' => array( __CLASS__, 'show_chart' ),
94
  'callback_args' => array(
95
  'chart_data' => wp_slimstat_db::get_data_for_chart( 'COUNT(ip)', 'COUNT(DISTINCT(ip))' ),
96
+ 'chart_labels' => array( __( 'Pageviews', 'wp-slimstat' ), __( 'Unique IPs', 'wp-slimstat' ) ),
97
  ),
98
  'classes' => array( 'wide', 'chart' ),
99
  'screens' => array( 'wp-slim-view-2', 'dashboard' ),
101
  ),
102
  'slim_p1_02' => array(
103
  'title' => __( 'About Slimstat', 'wp-slimstat' ),
104
+ 'callback' => array( __CLASS__, 'show_about_wpslimstat' ),
105
  'classes' => array( 'normal', 'hidden' ),
106
  'screens' => array( 'wp-slim-view-2' )
107
  ),
108
  'slim_p1_03' => array(
109
  'title' => __( 'At a Glance', 'wp-slimstat' ),
110
+ 'callback' => array( __CLASS__, 'show_overview_summary' ),
111
  'classes' => array( 'normal' ),
112
  'screens' => array( 'wp-slim-view-2', 'dashboard' )
113
  ),
114
  'slim_p1_04' => array(
115
  'title' => __( 'Currently Online', 'wp-slimstat' ),
116
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
117
  'callback_args' => array(
118
  'type' => 'recent',
119
  'columns' => 'username',
120
  'where' => 'dt > '. ( date_i18n( 'U' ) - 300 ),
121
+ 'use_date_filters' => false,
122
+ 'raw' => array( __CLASS__, 'get_raw_results' )
123
  ),
124
  'classes' => array( 'normal' ),
125
  'screens' => array( 'wp-slim-view-2', 'dashboard', 'raw' ),
127
  ),
128
  'slim_p1_06' => array(
129
  'title' => __( 'Recent Search Terms', 'wp-slimstat' ),
130
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
131
  'callback_args' => array(
132
  'type' => 'recent',
133
+ 'columns' => 'searchterms',
134
+ 'raw' => array( __CLASS__, 'get_raw_results' )
135
  ),
136
  'classes' => array( 'normal' ),
137
  'screens' => array( 'wp-slim-view-2', 'wp-slim-view-5', 'raw' ),
139
  ),
140
  'slim_p1_08' => array(
141
  'title' => __( 'Top Pages', 'wp-slimstat' ),
142
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
143
  'callback_args' => array(
144
  'type' => 'top',
145
  'columns' => 'SUBSTRING_INDEX(resource, "' . ( !get_option( 'permalink_structure' ) ? '&' : '?' ) . '", 1)',
146
  'as_column' => 'resource',
147
+ 'filter_op' => 'contains',
148
+ 'raw' => array( __CLASS__, 'get_raw_results' )
149
  ),
150
  'classes' => array( 'normal' ),
151
  'screens' => array( 'wp-slim-view-2', 'dashboard', 'raw' ),
153
  ),
154
  'slim_p1_10' => array(
155
  'title' => __('Top Traffic Sources', 'wp-slimstat'),
156
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
157
  'callback_args' => array(
158
  'type' => 'top',
159
  'columns' => 'referer',
160
+ 'where' => 'referer NOT LIKE "%' . home_url() . '%"',
161
+ 'raw' => array( __CLASS__, 'get_raw_results' )
162
  ),
163
  'classes' => array( 'normal' ),
164
  'screens' => array( 'wp-slim-view-2', 'wp-slim-view-5', 'dashboard', 'raw' )
165
  ),
166
  'slim_p1_11' => array(
167
  'title' => __( 'Top Known Visitors', 'wp-slimstat' ),
168
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
169
  'callback_args' => array(
170
  'type' => 'top',
171
+ 'columns' => 'username',
172
+ 'raw' => array( __CLASS__, 'get_raw_results' )
173
  ),
174
  'classes' => array( 'normal', 'hidden' ),
175
  'screens' => array( 'wp-slim-view-2', 'dashboard', 'raw' )
176
  ),
177
  'slim_p1_12' => array(
178
  'title' => __( 'Top Search Terms', 'wp-slimstat' ),
179
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
180
  'callback_args' => array(
181
  'type' => 'top',
182
+ 'columns' => 'searchterms',
183
+ 'raw' => array( __CLASS__, 'get_raw_results' )
184
  ),
185
  'classes' => array( 'normal' ),
186
  'screens' => array( 'wp-slim-view-2', 'wp-slim-view-4', 'wp-slim-view-5', 'dashboard', 'raw' )
187
  ),
188
  'slim_p1_13' => array(
189
  'title' => __( 'Top Countries', 'wp-slimstat' ),
190
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
191
  'callback_args' => array(
192
  'type' => 'top',
193
+ 'columns' => 'country',
194
+ 'raw' => array( __CLASS__, 'get_raw_results' )
195
  ),
196
  'classes' => array( 'normal', 'hidden' ),
197
  'screens' => array( 'wp-slim-view-2', 'wp-slim-view-3', 'wp-slim-view-5', 'dashboard', 'raw' ),
199
  ),
200
  'slim_p1_15' => array(
201
  'title' => __( 'Rankings', 'wp-slimstat' ),
202
+ 'callback' => array( __CLASS__, 'show_rankings' ),
203
  'classes' => array( 'normal' ),
204
  'screens' => array( 'wp-slim-view-2' ),
205
  'tooltip' => __( "Slimstat retrieves live information from Alexa, Facebook and Google, to measures your site's rankings. Values are updated every 12 hours. Filters set above don't apply to this report.", 'wp-slimstat' )
206
  ),
207
  'slim_p1_17' => array(
208
  'title' => __( 'Top Language Families', 'wp-slimstat' ),
209
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
210
  'callback_args' => array(
211
  'type' => 'top',
212
  'columns' => 'SUBSTRING(language, 1, 2)',
213
  'as_column' => 'language',
214
+ 'filter_op' => 'contains',
215
+ 'raw' => array( __CLASS__, 'get_raw_results' )
216
  ),
217
  'classes' => array( 'normal', 'hidden' ),
218
  'screens' => array( 'wp-slim-view-2', 'raw' )
220
 
221
  'slim_p2_01' => array(
222
  'title' => __( 'Human Visits', 'wp-slimstat' ),
223
+ 'callback' => array( __CLASS__, 'show_chart' ),
224
  'callback_args' => array(
225
  'chart_data' => wp_slimstat_db::get_data_for_chart( 'COUNT(DISTINCT visit_id)', 'COUNT(DISTINCT ip)', '(visit_id > 0 AND browser_type <> 1)' ),
226
+ 'chart_labels' => array( __( 'Visits', 'wp-slimstat' ), __( 'Unique IPs', 'wp-slimstat' ) ),
227
+ 'raw' => array( __CLASS__, 'get_raw_results' )
228
  ),
229
  'classes' => array( 'wide', 'chart' ),
230
  'screens' => array( 'wp-slim-view-3' ),
232
  ),
233
  'slim_p2_02' => array(
234
  'title' => __( 'Audience Overview', 'wp-slimstat' ),
235
+ 'callback' => array( __CLASS__, 'show_visitors_summary' ),
236
  'classes' => array( 'normal' ),
237
  'screens' => array( 'wp-slim-view-3', 'dashboard' ),
238
  'tooltip' => __( 'Where not otherwise specified, the metrics in this report are referred to human visitors.', 'wp-slimstat' )
239
  ),
240
  'slim_p2_03' => array(
241
  'title' => __( 'Top Languages', 'wp-slimstat' ),
242
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
243
  'callback_args' => array(
244
  'type' => 'top',
245
+ 'columns' => 'language',
246
+ 'raw' => array( __CLASS__, 'get_raw_results' )
247
  ),
248
  'classes' => array( 'normal' ),
249
  'screens' => array( 'wp-slim-view-3', 'raw' )
250
  ),
251
  'slim_p2_04' => array(
252
  'title' => __( 'Top Browsers', 'wp-slimstat', 'dashboard' ),
253
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
254
  'callback_args' => array(
255
  'type' => 'top',
256
+ 'columns' => 'browser, browser_version',
257
+ 'raw' => array( __CLASS__, 'get_raw_results' )
258
  ),
259
  'classes' => array( 'normal' ),
260
  'screens' => array( 'wp-slim-view-3', 'raw' )
261
  ),
262
  'slim_p2_05' => array(
263
  'title' => __( 'Top Service Providers', 'wp-slimstat' ),
264
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
265
  'callback_args' => array(
266
  'type' => 'top',
267
+ 'columns' => 'ip',
268
+ 'raw' => array( __CLASS__, 'get_raw_results' )
269
  ),
270
  'classes' => array( 'wide', 'hidden' ),
271
  'screens' => array( 'wp-slim-view-3', 'raw' ),
273
  ),
274
  'slim_p2_06' => array(
275
  'title' => __( 'Top Operating Systems', 'wp-slimstat' ),
276
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
277
  'callback_args' => array(
278
  'type' => 'top',
279
+ 'columns' => 'platform',
280
+ 'raw' => array( __CLASS__, 'get_raw_results' )
281
  ),
282
  'classes' => array( 'normal', 'hidden' ),
283
  'screens' => array( 'wp-slim-view-3', 'raw' ),
285
  ),
286
  'slim_p2_07' => array(
287
  'title' => __( 'Top Screen Resolutions', 'wp-slimstat' ),
288
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
289
  'callback_args' => array(
290
  'type' => 'top',
291
+ 'columns' => 'resolution',
292
+ 'raw' => array( __CLASS__, 'get_raw_results' ),
293
  ),
294
  'classes' => array( 'normal' ),
295
  'screens' => array( 'wp-slim-view-3', 'dashboard', 'raw' )
296
  ),
297
  'slim_p2_09' => array(
298
  'title' => __( 'Browser Capabilities', 'wp-slimstat' ),
299
+ 'callback' => array( __CLASS__, 'show_plugins' ),
300
  'classes' => array( 'normal', 'hidden' ),
301
+ 'screens' => array( 'wp-slim-view-3' )
302
  ),
303
  'slim_p2_12' => array(
304
  'title' => __( 'Visit Duration', 'wp-slimstat' ),
305
+ 'callback' => array( __CLASS__, 'show_visit_duration' ),
306
  'classes' => array( 'normal', 'hidden' ),
307
  'screens' => array( 'wp-slim-view-3' )
308
  ),
309
  'slim_p2_13' => array(
310
  'title' => __( 'Recent Countries', 'wp-slimstat' ),
311
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
312
  'callback_args' => array(
313
  'type' => 'recent',
314
+ 'columns' => 'country',
315
+ 'raw' => array( __CLASS__, 'get_raw_results' )
316
  ),
317
  'classes' => array( 'normal', 'hidden' ),
318
  'screens' => array( 'wp-slim-view-3', 'wp-slim-view-5', 'raw' )
319
  ),
320
  'slim_p2_14' => array(
321
  'title' => __( 'Recent Screen Resolutions', 'wp-slimstat' ),
322
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
323
  'callback_args' => array(
324
  'type' => 'recent',
325
+ 'columns' => 'resolution',
326
+ 'raw' => array( __CLASS__, 'get_raw_results' )
327
  ),
328
  'classes' => array( 'normal', 'hidden' ),
329
  'screens' => array( 'wp-slim-view-3', 'raw' )
330
  ),
331
  'slim_p2_15' => array(
332
  'title' => __( 'Recent Operating Systems', 'wp-slimstat' ),
333
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
334
  'callback_args' => array(
335
  'type' => 'recent',
336
+ 'columns' => 'platform',
337
+ 'raw' => array( __CLASS__, 'get_raw_results' )
338
  ),
339
  'classes' => array( 'normal', 'hidden' ),
340
  'screens' => array( 'wp-slim-view-3', 'raw' )
341
  ),
342
  'slim_p2_16' => array(
343
  'title' => __( 'Recent Browsers', 'wp-slimstat' ),
344
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
345
  'callback_args' => array(
346
  'type' => 'recent',
347
+ 'columns' => 'browser, browser_version',
348
+ 'raw' => array( __CLASS__, 'get_raw_results' )
349
  ),
350
  'classes' => array( 'normal', 'hidden' ),
351
  'screens' => array( 'wp-slim-view-3', 'raw' )
352
  ),
353
  'slim_p2_17' => array(
354
  'title' => __( 'Recent Languages', 'wp-slimstat' ),
355
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
356
  'callback_args' => array(
357
  'type' => 'recent',
358
+ 'columns' => 'language',
359
+ 'raw' => array( __CLASS__, 'get_raw_results' )
360
  ),
361
  'classes' => array( 'normal', 'hidden' ),
362
  'screens' => array( 'wp-slim-view-3', 'raw' )
363
  ),
364
  'slim_p2_18' => array(
365
  'title' => __( 'Top Browser Families', 'wp-slimstat' ),
366
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
367
  'callback_args' => array(
368
  'type' => 'top',
369
+ 'columns' => 'browser',
370
+ 'raw' => array( __CLASS__, 'get_raw_results' )
371
  ),
372
  'classes' => array( 'normal', 'hidden' ),
373
  'screens' => array( 'wp-slim-view-3', 'raw' ),
375
  ),
376
  'slim_p2_19' => array(
377
  'title' => __( 'Top OS Families', 'wp-slimstat' ),
378
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
379
  'callback_args' => array(
380
  'type' => 'top',
381
  'columns' => 'CONCAT("p-", SUBSTRING(platform, 1, 3))',
382
  'as_column' => 'platform',
383
+ 'filter_op' => 'contains',
384
+ 'raw' => array( __CLASS__, 'get_raw_results' )
385
  ),
386
  'classes' => array( 'normal' ),
387
  'screens' => array( 'wp-slim-view-3', 'raw' ),
389
  ),
390
  'slim_p2_20' => array(
391
  'title' => __( 'Recent Users', 'wp-slimstat' ),
392
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
393
  'callback_args' => array(
394
  'type' => 'recent',
395
  'columns' => 'username',
396
+ 'where' => 'notes LIKE "%user:%"',
397
+ 'raw' => array( __CLASS__, 'get_raw_results' )
398
  ),
399
  'classes' => array( 'normal' ),
400
  'screens' => array( 'wp-slim-view-3', 'raw' )
401
  ),
402
  'slim_p2_21' => array(
403
  'title' => __( 'Top Users', 'wp-slimstat' ),
404
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
405
  'callback_args' => array(
406
  'type' => 'top',
407
  'columns' => 'username',
408
+ 'where' => 'notes LIKE "%user:%"',
409
+ 'raw' => array( __CLASS__, 'get_raw_results' )
410
  ),
411
  'classes' => array( 'normal', 'hidden' ),
412
  'screens' => array( 'wp-slim-view-3', 'dashboard', 'raw' )
414
 
415
  'slim_p3_01' => array(
416
  'title' => __( 'Traffic Sources', 'wp-slimstat' ),
417
+ 'callback' => array( __CLASS__, 'show_chart' ),
418
  'callback_args' => array(
419
  'chart_data' => wp_slimstat_db::get_data_for_chart( 'COUNT(DISTINCT(referer))', 'COUNT(DISTINCT(ip))', '(referer IS NOT NULL AND referer NOT LIKE "%' . home_url() . '%")' ),
420
  'chart_labels' => array( __( 'Domains', 'wp-slimstat' ), __( 'Unique IPs', 'wp-slimstat' ) )
425
  ),
426
  'slim_p3_02' => array(
427
  'title' => __( 'Summary', 'wp-slimstat' ),
428
+ 'callback' => array( __CLASS__, 'show_traffic_sources_summary' ),
429
  'classes' => array( 'normal' ),
430
  'screens' => array( 'wp-slim-view-5' )
431
  ),
432
  'slim_p3_06' => array(
433
  'title' => __( 'Top Referring Search Engines', 'wp-slimstat' ),
434
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
435
  'callback_args' => array(
436
  'type' => 'top',
437
  'columns' => 'referer',
438
+ 'where' => "searchterms IS NOT NULL AND referer NOT LIKE '%".home_url()."%'",
439
+ 'raw' => array( __CLASS__, 'get_raw_results' )
440
  ),
441
  'classes' => array( 'normal' ),
442
  'screens' => array( 'wp-slim-view-5', 'dashboard', 'raw' )
443
  ),
444
  'slim_p3_11' => array(
445
  'title' => __( 'Recent Exit Pages', 'wp-slimstat' ),
446
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
447
  'callback_args' => array(
448
  'type' => 'recent',
449
+ 'columns' => 'visit_id', // raw_results_to_html knows to display the resource, when the column is visit_id
450
+ 'raw' => array( __CLASS__, 'get_raw_results' )
451
  ),
452
  'classes' => array( 'normal' ),
453
  'screens' => array( 'wp-slim-view-5', 'raw' )
456
  /*
457
  'slim_p4_01' => array(
458
  'title' => __( 'Recent Outbound Links', 'wp-slimstat' ),
459
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
460
+ 'callback_raw' => array( __CLASS__, 'get_raw_results' ),
461
  'classes' => array( 'wide' ),
462
  'screens' => array( 'wp-slim-view-4', 'raw' ),
463
  'tooltip' => ''
465
  */
466
  'slim_p4_02' => array(
467
  'title' => __( 'Recent Posts', 'wp-slimstat' ),
468
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
469
  'callback_args' => array(
470
  'type' => 'recent',
471
  'columns' => 'resource',
472
+ 'where' => 'content_type = "post"',
473
+ 'raw' => array( __CLASS__, 'get_raw_results' )
474
  ),
475
  'classes' => array( 'normal' ),
476
  'screens' => array( 'wp-slim-view-4', 'raw' )
477
  ),
478
  'slim_p4_03' => array(
479
  'title' => __( 'Recent Bounce Pages', 'wp-slimstat' ),
480
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
481
  'callback_args' => array(
482
  'type' => 'recent',
483
  'columns' => 'resource',
484
  'where' => 'content_type <> "404"',
485
+ 'having' => 'HAVING COUNT(visit_id) => 1',
486
+ 'raw' => array( __CLASS__, 'get_raw_results' )
487
  ),
488
  'classes' => array( 'normal', 'hidden' ),
489
  'screens' => array( 'wp-slim-view-4', 'raw' ),
491
  ),
492
  'slim_p4_04' => array(
493
  'title' => __( 'Recent Feeds', 'wp-slimstat' ),
494
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
495
  'callback_args' => array(
496
  'type' => 'recent',
497
  'columns' => 'resource',
498
+ 'where' => '(resource LIKE "%/feed%" OR resource LIKE "%?feed=>%" OR resource LIKE "%&feed=>%" OR content_type LIKE "%feed%")',
499
+ 'raw' => array( __CLASS__, 'get_raw_results' )
500
  ),
501
  'classes' => array( 'normal', 'hidden' ),
502
  'screens' => array( 'wp-slim-view-4', 'raw' )
503
  ),
504
  'slim_p4_05' => array(
505
  'title' => __( 'Recent Pages Not Found', 'wp-slimstat' ),
506
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
507
  'callback_args' => array(
508
  'type' => 'recent',
509
  'columns' => 'resource',
510
+ 'where' => '(resource LIKE "[404]%" OR content_type LIKE "%404%")',
511
+ 'raw' => array( __CLASS__, 'get_raw_results' )
512
  ),
513
  'classes' => array( 'normal' ),
514
  'screens' => array( 'wp-slim-view-4', 'raw' )
515
  ),
516
  'slim_p4_06' => array(
517
  'title' => __( 'Recent Internal Searches', 'wp-slimstat' ),
518
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
519
  'callback_args' => array(
520
  'type' => 'recent',
521
  'columns' => 'searchterms',
522
+ 'where' => 'content_type LIKE "%search%"',
523
+ 'raw' => array( __CLASS__, 'get_raw_results' )
524
  ),
525
  'classes' => array( 'normal', 'hidden' ),
526
  'screens' => array( 'wp-slim-view-4', 'raw' ),
528
  ),
529
  'slim_p4_07' => array(
530
  'title' => __( 'Top Categories', 'wp-slimstat' ),
531
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
532
  'callback_args' => array(
533
  'type' => 'top',
534
  'columns' => 'category',
535
+ 'where' => 'content_type LIKE "%category%"',
536
+ 'raw' => array( __CLASS__, 'get_raw_results' )
537
  ),
538
  'classes' => array( 'normal', 'raw' ),
539
  'screens' => array( 'wp-slim-view-4', 'dashboard' )
542
  NOTE TO SELF: don't forget to remove from deprecated, when implemented
543
  'slim_p4_09' => array(
544
  'title' => __( 'Top Downloads', 'wp-slimstat' ),
545
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
546
  'callback_args' => array(
547
+ 'raw' => array( __CLASS__, 'get_raw_results' )
548
  ),
549
  'classes' => array( 'normal', 'hidden' ),
550
  'screens' => array( 'wp-slim-view-4', 'raw' ),
552
  ),
553
  'slim_p4_10' => array(
554
  'title' => __( 'Recent Events', 'wp-slimstat' ),
555
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
556
  'callback_args' => array(
557
 
558
+ 'raw' => array( __CLASS__, 'get_raw_results' )
559
  ),
560
  'classes' => array( 'normal', 'hidden' ),
561
  'screens' => array( 'wp-slim-view-4', 'raw' ),
564
  */
565
  'slim_p4_11' => array(
566
  'title' => __( 'Top Posts', 'wp-slimstat' ),
567
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
568
  'callback_args' => array(
569
  'type' => 'top',
570
  'columns' => 'resource',
571
+ 'where' => 'content_type = "post"',
572
+ 'raw' => array( __CLASS__, 'get_raw_results' )
573
  ),
574
  'classes' => array( 'normal' ),
575
  'screens' => array( 'wp-slim-view-4', 'raw' )
576
  ),
577
  'slim_p4_13' => array(
578
  'title' => __( 'Top Internal Searches', 'wp-slimstat' ),
579
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
580
  'callback_args' => array(
581
  'type' => 'top',
582
  'columns' => 'searchterms',
583
+ 'where' => 'content_type LIKE "%search%"',
584
+ 'raw' => array( __CLASS__, 'get_raw_results' )
585
  ),
586
  'classes' => array( 'normal', 'hidden' ),
587
  'screens' => array( 'wp-slim-view-4', 'raw' )
588
  ),
589
  'slim_p4_15' => array(
590
  'title' => __( 'Recent Categories', 'wp-slimstat' ),
591
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
592
  'callback_args' => array(
593
  'type' => 'recent',
594
  'columns' => 'resource',
595
+ 'where' => '(content_type => "category" OR content_type => "tag")',
596
+ 'raw' => array( __CLASS__, 'get_raw_results' )
597
  ),
598
  'classes' => array( 'normal', 'hidden' ),
599
  'screens' => array( 'wp-slim-view-4', 'raw' )
600
  ),
601
  'slim_p4_16' => array(
602
  'title' => __( 'Top Pages Not Found', 'wp-slimstat' ),
603
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
604
  'callback_args' => array(
605
  'type' => 'top',
606
  'columns' => 'resource',
607
+ 'where' => 'content_type LIKE "%404%"',
608
+ 'raw' => array( __CLASS__, 'get_raw_results' )
609
  ),
610
  'classes' => array( 'normal' ),
611
  'screens' => array( 'wp-slim-view-4', 'raw' )
612
  ),
613
  'slim_p4_18' => array(
614
  'title' => __( 'Top Authors', 'wp-slimstat' ),
615
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
616
  'callback_args' => array(
617
  'type' => 'top',
618
+ 'columns' => 'author',
619
+ 'raw' => array( __CLASS__, 'get_raw_results' )
620
  ),
621
  'classes' => array( 'normal' ),
622
  'screens' => array( 'wp-slim-view-4', 'dashboard', 'raw' )
623
  ),
624
  'slim_p4_19' => array(
625
  'title' => __( 'Top Tags', 'wp-slimstat' ),
626
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
627
  'callback_args' => array(
628
  'type' => 'top',
629
  'columns' => 'category',
630
+ 'where' => '(content_type LIKE "%tag%")',
631
+ 'raw' => array( __CLASS__, 'get_raw_results' )
632
  ),
633
  'classes' => array( 'normal', 'hidden' ),
634
  'screens' => array( 'wp-slim-view-4', 'raw' )
635
  ),
636
  'slim_p4_20' => array(
637
  'title' => __( 'Recent Downloads', 'wp-slimstat' ),
638
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
639
  'callback_args' => array(
640
 
641
+ 'raw' => array( __CLASS__, 'get_raw_results' )
642
  ),
643
  'classes' => array( 'wide', 'hidden' ),
644
  'screens' => array( 'wp-slim-view-4', 'raw' )
645
  ),
646
  'slim_p4_21' => array(
647
  'title' => __( 'Top Outbound Links', 'wp-slimstat' ),
648
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
649
  'callback_args' => array(
650
 
651
+ 'raw' => array( __CLASS__, 'get_raw_results' )
652
  ),
653
  'classes' => array( 'normal', 'hidden' ),
654
  'screens' => array( 'wp-slim-view-4', 'raw' )
655
  ),
656
  'slim_p4_22' => array(
657
  'title' => __( 'Your Website', 'wp-slimstat' ),
658
+ 'callback' => array( __CLASS__, 'show_your_blog' ),
659
  'classes' => array( 'normal', 'hidden' ),
660
+ 'screens' => array( 'wp-slim-view-4' ),
661
  'tooltip' => __( 'Your content at a glance: posts, comments, pingbacks, etc. Please note that this report is not affected by the filters set here above.', 'wp-slimstat' )
662
  ),
663
  'slim_p4_23' => array(
664
  'title' => __( 'Top Bounce Pages', 'wp-slimstat' ),
665
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
666
  'callback_args' => array(
667
  'type' => 'top',
668
  'columns' => 'resource',
669
  'where' => 'content_type <> "404"',
670
+ 'having' => 'HAVING COUNT(visit_id) => 1',
671
+ 'raw' => array( __CLASS__, 'get_raw_results' )
672
  ),
673
  'classes' => array( 'normal', 'hidden' ),
674
  'screens' => array( 'wp-slim-view-4', 'raw' )
676
  /* NOTE TO SELF: remove them from deprecated, when reimplemented
677
  'slim_p4_24' => array(
678
  'title' => __( 'Top Exit Pages', 'wp-slimstat' ),
679
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
680
  'callback_args' => array(
681
  'type' => 'top_complete',
682
  'columns' => 'visit_id',
683
  'outer_select_column' => 'resource',
684
+ 'aggr_function' => 'MAX',
685
+ 'raw' => array( __CLASS__, 'get_raw_results' )
686
  ),
687
  'classes' => array( 'normal', 'hidden' ),
688
  'screens' => array( 'wp-slim-view-4', 'raw' )
689
  ),
690
  'slim_p4_25' => array(
691
  'title' => __( 'Top Entry Pages', 'wp-slimstat' ),
692
+ 'callback' => array( __CLASS__, 'raw_results_to_html' ),
693
  'callback_args' => array(
694
  'type' => 'top_complete',
695
  'columns' => 'visit_id',
696
  'outer_select_column' => 'resource',
697
+ 'aggr_function' => 'MIN',
698
+ 'raw' => array( __CLASS__, 'get_raw_results' )
699
  ),
700
  'classes' => array( 'normal', 'hidden' ),
701
  'screens' => array( 'wp-slim-view-4', 'raw' )
704
 
705
  'slim_p6_01' => array(
706
  'title' => __( 'World Map', 'wp-slimstat' ),
707
+ 'callback' => array( __CLASS__, 'show_world_map' ),
708
  'classes' => array( 'tall' ),
709
  'screens' => array( 'wp-slim-view-6' ),
710
  'tooltip' => ''
760
  if ( !empty( $hidden_reports ) && is_array( $hidden_reports ) ) {
761
  foreach ( self::$reports_info as $a_report_id => $a_report_info ) {
762
  if ( in_array( $a_report_id, $hidden_reports ) ) {
763
+ if ( is_array( self::$reports_info[ $a_report_id ][ 'classes' ] ) && !in_array( 'hidden', $a_report_info[ 'classes' ] ) ) {
764
  self::$reports_info[ $a_report_id ][ 'classes' ][] = 'hidden';
765
  }
766
  }
836
  return array();
837
  }
838
 
839
+ // Default Values
840
+ $_args = array_merge( array(
841
+ 'type' => '',
842
+ 'columns' => '',
843
+ 'where' => '',
844
+ 'having' => '',
845
+ 'as_column' => '',
846
+ 'filter_op' => 'equals',
847
+ 'outer_select_column' => '',
848
+ 'aggr_function' => 'MAX',
849
+ 'use_date_filters' => true
850
+ ), $_args );
851
+
852
+
853
  switch ( $_args[ 'type' ] ) {
854
  case 'recent':
855
  $all_results = wp_slimstat_db::get_recent( $_args[ 'columns' ], $_args[ 'where' ], $_args[ 'having' ], $_args[ 'use_date_filters' ], $_args['as_column'] );
878
  public static function callback_wrapper() {
879
  $_args = self::_check_args( func_get_args() );
880
 
881
+ call_user_func( $_args[ 'callback' ] , $_args[ 'callback_args' ] );
882
  }
883
 
884
  public static function raw_results_to_html( $_args = array() ){
885
+ $all_results = call_user_func( $_args[ 'raw' ] , $_args );
886
 
887
  $results = array_slice(
888
  $all_results,
1560
 
1561
  if (!empty($filters_dropdown)){
1562
  foreach($filters_dropdown as $a_filter_label => $a_filter_details){
1563
+ if (!array_key_exists($a_filter_label, wp_slimstat_db::$columns_names) || strpos($a_filter_label, 'no_filter') !== false){
1564
  continue;
1565
  }
1566
 
1567
  $a_filter_value_no_slashes = htmlentities(str_replace('\\','', $a_filter_details[1]), ENT_QUOTES, 'UTF-8');
1568
+ $filters_html .= "<li>".strtolower(wp_slimstat_db::$columns_names[$a_filter_label][ 0 ]).' '.__(str_replace('_', ' ', $a_filter_details[0]),'wp-slimstat')." $a_filter_value_no_slashes <a class='slimstat-remove-filter slimstat-font-cancel' title='".htmlentities(__('Remove filter for','wp-slimstat'), ENT_QUOTES, 'UTF-8').' '.wp_slimstat_db::$columns_names[ $a_filter_label ][ 0 ]."' href='".self::fs_url("$a_filter_label equals ")."'></a></li>";
1569
  }
1570
  }
1571
  if (!empty($filters_html)){
1686
  $_args = array_merge( array(
1687
  'title' => '',
1688
  'callback' => '',
1689
+ 'callback_args' => array(),
1690
+ 'callback_raw' => '',
1691
+ 'classes' => array(),
1692
+ 'screens' => array(),
1693
  'tooltip' => ''
1694
  ), self::$reports_info[ $report_id ] );
1695
  }
1696
 
1697
+ // Default callback args
1698
+ $_args[ 'callback_args' ] = array_merge( array(
1699
+ 'type' => '',
1700
+ 'columns' => '',
1701
+ 'where' => '',
1702
+ 'having' => '',
1703
+ 'as_column' => '',
1704
+ 'filter_op' => 'equals',
1705
+ 'outer_select_column' => '',
1706
+ 'aggr_function' => 'MAX',
1707
+ 'use_date_filters' => true
1708
+ ), $_args[ 'callback_args' ] );
 
 
 
 
 
1709
 
1710
  return $_args;
1711
  }
admin/wp-slimstat-admin.php CHANGED
@@ -130,7 +130,7 @@ class wp_slimstat_admin{
130
  $report_id = sanitize_title( $_POST[ 'report_id' ], 'slim_p0_00' );
131
 
132
  if ( !empty( wp_slimstat_reports::$reports_info[ $report_id ] ) ) {
133
- add_action('wp_ajax_slimstat_load_report', array('wp_slimstat_reports', wp_slimstat_reports::$reports_info[ $report_id ][ 'callback' ] ), 10, 2 );
134
  }
135
  }
136
  }
@@ -663,10 +663,12 @@ class wp_slimstat_admin{
663
  $minimum_capability = wp_slimstat::$options['capability_can_admin'];
664
  }
665
 
666
- $new_entry = add_submenu_page(null, __('Settings','wp-slimstat'), __('Settings','wp-slimstat'), $minimum_capability, 'wp-slim-config', array(__CLASS__, 'wp_slimstat_include_config'));
667
  if (wp_slimstat::$options['use_separate_menu'] == 'yes'){
668
  $new_entry = add_submenu_page('wp-slim-view-1', __('Settings','wp-slimstat'), __('Settings','wp-slimstat'), $minimum_capability, 'wp-slim-config', array(__CLASS__, 'wp_slimstat_include_config'));
669
  }
 
 
 
670
 
671
  // Load styles and Javascript needed to make the reports look nice and interactive
672
  add_action('load-'.$new_entry, array(__CLASS__, 'wp_slimstat_stylesheet'));
@@ -863,7 +865,7 @@ class wp_slimstat_admin{
863
  $filter_html = $filter_strings = array();
864
  foreach ($a_filter_data as $a_filter_label => $a_filter_details){
865
  $filter_value_no_slashes = htmlentities(str_replace('\\','', $a_filter_details[1]), ENT_QUOTES, 'UTF-8');
866
- $filter_html[] = strtolower(wp_slimstat_db::$filters_names[$a_filter_label][0]).' '.__(str_replace('_', ' ', $a_filter_details[0]),'wp-slimstat').' '.$filter_value_no_slashes;
867
  $filter_strings[] = "$a_filter_label {$a_filter_details[0]} $filter_value_no_slashes";
868
  }
869
  echo '<p><a class="slimstat-font-cancel slimstat-delete-filter" data-filter-id="'.$a_filter_id.'" title="'.__('Delete this filter','wp-slimstat').'" href="#"></a> <a class="slimstat-filter-link" data-reset-filters="true" href="' . wp_slimstat_reports::fs_url( implode( '&&&', $filter_strings ) ).'">'.implode(', ', $filter_html).'</a> <a href="#"></a></p>';
130
  $report_id = sanitize_title( $_POST[ 'report_id' ], 'slim_p0_00' );
131
 
132
  if ( !empty( wp_slimstat_reports::$reports_info[ $report_id ] ) ) {
133
+ add_action('wp_ajax_slimstat_load_report', array( 'wp_slimstat_reports', 'callback_wrapper' ), 10, 2 );
134
  }
135
  }
136
  }
663
  $minimum_capability = wp_slimstat::$options['capability_can_admin'];
664
  }
665
 
 
666
  if (wp_slimstat::$options['use_separate_menu'] == 'yes'){
667
  $new_entry = add_submenu_page('wp-slim-view-1', __('Settings','wp-slimstat'), __('Settings','wp-slimstat'), $minimum_capability, 'wp-slim-config', array(__CLASS__, 'wp_slimstat_include_config'));
668
  }
669
+ else {
670
+ $new_entry = add_submenu_page('admin.php', __('Settings','wp-slimstat'), __('Settings','wp-slimstat'), $minimum_capability, 'wp-slim-config', array(__CLASS__, 'wp_slimstat_include_config'));
671
+ }
672
 
673
  // Load styles and Javascript needed to make the reports look nice and interactive
674
  add_action('load-'.$new_entry, array(__CLASS__, 'wp_slimstat_stylesheet'));
865
  $filter_html = $filter_strings = array();
866
  foreach ($a_filter_data as $a_filter_label => $a_filter_details){
867
  $filter_value_no_slashes = htmlentities(str_replace('\\','', $a_filter_details[1]), ENT_QUOTES, 'UTF-8');
868
+ $filter_html[] = strtolower(wp_slimstat_db::$columns_names[$a_filter_label][0]).' '.__(str_replace('_', ' ', $a_filter_details[0]),'wp-slimstat').' '.$filter_value_no_slashes;
869
  $filter_strings[] = "$a_filter_label {$a_filter_details[0]} $filter_value_no_slashes";
870
  }
871
  echo '<p><a class="slimstat-font-cancel slimstat-delete-filter" data-filter-id="'.$a_filter_id.'" title="'.__('Delete this filter','wp-slimstat').'" href="#"></a> <a class="slimstat-filter-link" data-reset-filters="true" href="' . wp_slimstat_reports::fs_url( implode( '&&&', $filter_strings ) ).'">'.implode(', ', $filter_html).'</a> <a href="#"></a></p>';
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_i
4
  Tags: analytics, tracking, reports, analyze, wassup, geolocation, online users, spider, tracker, pageviews, stats, maxmind, statistics, statpress
5
  Requires at least: 3.8
6
  Tested up to: 4.2
7
- Stable tag: 4.1
8
 
9
  == Description ==
10
  [youtube https://www.youtube.com/watch?v=iJCtjxArq4U]
@@ -13,7 +13,7 @@ Stable tag: 4.1
13
  * Real-time activity log, server latency, heatmaps, email reports, export data to Excel, and much more
14
  * Compatible with W3 Total Cache, WP SuperCache and most caching plugins
15
  * Accurate IP geolocation, browser and platform detection (courtesy of [MaxMind](http://www.maxmind.com/) and [Browscap](http://browscap.org))
16
- * Available in multiple languages: English, Chinese (沐熙工作室), Farsi ([Dean](http://www.mangallery.net)), French (Michael Bastin, Jean-Michel Venet, Yves Pouplard, Henrick Kac), German (TechnoViel), Italian, Japanese (h_a_l_f), Portuguese, Russian ([Vitaly](http://www.visbiz.org/)), Spanish ([WebHostingHub](http://www.webhostinghub.com/)), Swedish (Per Soderman). Is your language missing or incomplete? [Contact Us](http://support.getused.to.it/) if you would like to share your localization.
17
  * World Map that works on your mobile device, too (courtesy of [amMap](http://www.ammap.com/)).
18
 
19
  = What are people saying about Slimstat? =
@@ -32,7 +32,7 @@ Stable tag: 4.1
32
  * IE9+ or any browser supporting HTML5, to access the reports
33
 
34
  = Premium Add-ons =
35
- Visit [our website](http://slimstat.getused.to.it/addons/) for a list of available extensions.
36
 
37
  == Installation ==
38
 
@@ -47,7 +47,7 @@ Please note: if you decide to uninstall Slimstat, all the stats will be **PERMAN
47
 
48
  == Frequently Asked Questions ==
49
 
50
- Our knowledge base is available on our [support center](https://slimstat.freshdesk.com/support/solutions) website.
51
 
52
  == Screenshots ==
53
 
@@ -59,11 +59,17 @@ Our knowledge base is available on our [support center](https://slimstat.freshde
59
 
60
  == Changelog ==
61
 
 
 
 
 
 
 
62
  = 4.1 =
63
  * [Note] We'd like to hear from you: have you noticed any performance improvements after switching to Slimstat 4.0? Let us know through the forum or contant our support team.
64
  * [New] Our dev team is moving forward with their effort to give Slimstat's source code a good scrub. After cleaning up the database library, it was now the report library's turn. Again, if you developed your own custom report, you will probably need to update your code to make it work with our new library. We are going to update our online documentation in the next few days.
65
  * [New] The DB library function wp_slimstat_db::get_popular has been renamed wp_slimstat_db::get_top for consistency with the rest our codebase. Please update your code accordingly.
66
- * [New] Say hello to your new shortcodes. We merged the ShortCodes add-on directly into our main plugin. This improves the overall performance and streamlines our software lifecycle. Please note: the shortcode syntax has been updated and simplified (you need to replace 'popular' with 'top'). All the information is being added to our [knowledge base](https://slimstat.freshdesk.com/support/solutions) for your convenience. Stay tuned or contact our support team for more information.
67
  * [Update] [AmMap](http://www.amcharts.com/javascript-maps/) has been updated to version 3.14.2. Please consider supporting this project by [purchasing a license](http://www.amcharts.com/online-store/).
68
  * [Fix] We took care of various warnings displayed with DEBUG_MODE enabled.
69
  * [Fix] The data import script failed to do its job in some multisite environments (thank you, pepe).
@@ -122,7 +128,6 @@ Our knowledge base is available on our [support center](https://slimstat.freshde
122
  * [Update] Removed banner from our partner ManageWP
123
 
124
  = 3.9.8 =
125
- * [Note] The team who manages the WordPress Plugin Repository notified us that since the [MaxMind GeoLite library](http://dev.maxmind.com/geoip/legacy/geolite/) used by Slimstat to geolocate visitors is released under the Creative Commons BY-SA 3.0 license, it violates the repository guidelines, and cannot be bundled with the plugin. We were required to remove the code and alter the plugin so that this functionality becomes optional. We apologize for the inconvenience. However, the only immediate consequence is that your visitors' country will not be identified; everything else will still work as usual. You can download the geolocation DB as a [separate add-on](http://slimstat.getused.to.it/downloads/get-country/) on our store, free of charge. Don't forget to enter your license key in the corresponding field under Slimstat > Add-ons, to receive free updates!
126
  * [New] A few new options under Slimstat > Settings > General tab > WordPress Integration section, allow you to have more control over the information displayed in the Posts admin screen (thank you, Brad).
127
 
128
  = 3.9.7 =
@@ -146,16 +151,16 @@ Our knowledge base is available on our [support center](https://slimstat.freshde
146
  * [Fix] Report filters could not be removed after being set.
147
 
148
  = 3.9.5 =
149
- * [Note] Some of our add-ons had a bug preventing them from properly checking for updates. Please [contact us](http://support.getused.to.it) if you need to obtain the latest version of your add-ons.
150
  * [Update] The Save button in the settings is now always visible, so that there is no need to scroll all the way to the bottom to save your options.
151
  * [Update] More data layer updates introduced in wp_slimstat_db. Keep an eye on your custom add-ons!
152
  * [Fix] Pagination was not working as expected when a date range was set in the filters (thank you, [nick-v](https://wordpress.org/support/topic/paging-is-broke))
153
 
154
  = 3.9.4 =
155
  * [Note] The URL of the CDN has changed, and is now using the official WordPress repository as a source: cdn.jsdelivr.net/wp/wp-slimstat/trunk/wp-slimstat.js - Please update your "external" tracking codes accordingly.
156
- * [Note] The structure of the array **wp_slimstat_db::$sql_filters** has changed! Please make sure to update your custom code accordingly. Feel free to [contact us](http://support.getused.to.it) for more information.
157
- * [New] The wait is over. Our heatmap add-on is finally [available on our store](http://slimstat.getused.to.it/downloads/heatmap/)! We would like to thank all those who provided helpful feedback to improve this initial release!
158
- * [New] Our [knowledge base](https://slimstat.freshdesk.com/support/solutions) has been extended with a list of all the actions and filters available in Slimstat.
159
  * [Fix] The Add-on update checker had a bug preventing the functionality to work as expected. Please make sure to get the latest version of your premium add-ons!
160
  * [Fix] Date intervals were not accurate because of a bug related to calculating timezones in MySQL (thank you, [Chrisssssi](https://wordpress.org/support/topic/conflicting-data)).
161
  * [Fix] Line height of report rows has been added to avoid conflicts with other plugins tweaking this parameter in the admin (thank you, [yk11](https://wordpress.org/support/topic/widgets-bottom-is-cut-off)).
@@ -281,7 +286,7 @@ Thomas Weiss,
281
  Wayne Liebman,
282
  Willow Ridge Press
283
 
284
- == Tools of the trade, in alphabetical order ==
285
  [Duri.Me](http://duri.me/),
286
  [Filezilla](https://filezilla-project.org/),
287
  [Fontello](http://fontello.com/),
4
  Tags: analytics, tracking, reports, analyze, wassup, geolocation, online users, spider, tracker, pageviews, stats, maxmind, statistics, statpress
5
  Requires at least: 3.8
6
  Tested up to: 4.2
7
+ Stable tag: 4.1.1
8
 
9
  == Description ==
10
  [youtube https://www.youtube.com/watch?v=iJCtjxArq4U]
13
  * Real-time activity log, server latency, heatmaps, email reports, export data to Excel, and much more
14
  * Compatible with W3 Total Cache, WP SuperCache and most caching plugins
15
  * Accurate IP geolocation, browser and platform detection (courtesy of [MaxMind](http://www.maxmind.com/) and [Browscap](http://browscap.org))
16
+ * Available in multiple languages: English, Chinese (沐熙工作室), Farsi ([Dean](http://www.mangallery.net)), French (Michael Bastin, Jean-Michel Venet, Yves Pouplard, Henrick Kac), German (TechnoViel), Italian, Japanese (h_a_l_f), Portuguese, Russian ([Vitaly](http://www.visbiz.org/)), Spanish ([WebHostingHub](http://www.webhostinghub.com/)), Swedish (Per Soderman). Is your language missing or incomplete? [Contact Us](http://support.wp-slimstat.com/) if you would like to share your localization.
17
  * World Map that works on your mobile device, too (courtesy of [amMap](http://www.ammap.com/)).
18
 
19
  = What are people saying about Slimstat? =
32
  * IE9+ or any browser supporting HTML5, to access the reports
33
 
34
  = Premium Add-ons =
35
+ Visit [our website](http://www.wp-slimstat.com/addons/) for a list of available extensions.
36
 
37
  == Installation ==
38
 
47
 
48
  == Frequently Asked Questions ==
49
 
50
+ Our knowledge base is available on our [support center](http://docs.wp-slimstat.com/) website.
51
 
52
  == Screenshots ==
53
 
59
 
60
  == Changelog ==
61
 
62
+ = 4.1.1 =
63
+ * [Note] We are starting to hit the limits imposed by our current hosting provider, so it's time to move to a new more reliable server farm. We will be migrating our platform in the next few weeks, and this might cause some downtime for those trying to buy our premium add-ons. We apologize for the inconvenience.
64
+ * [Update] Minor adjustments to our codebase to make Slimstat easily extensible. Now you can quickly add your own reports by just passing some simple information to the plugin. More information soon available on our knowledge base website.
65
+ * [Update] Our premium add-on Export to Excel has been updated to be compatible with Slimstat 4.0.
66
+ * [Fix] We took care of some other tenacious warnings displayed with DEBUG_MODE enabled.
67
+
68
  = 4.1 =
69
  * [Note] We'd like to hear from you: have you noticed any performance improvements after switching to Slimstat 4.0? Let us know through the forum or contant our support team.
70
  * [New] Our dev team is moving forward with their effort to give Slimstat's source code a good scrub. After cleaning up the database library, it was now the report library's turn. Again, if you developed your own custom report, you will probably need to update your code to make it work with our new library. We are going to update our online documentation in the next few days.
71
  * [New] The DB library function wp_slimstat_db::get_popular has been renamed wp_slimstat_db::get_top for consistency with the rest our codebase. Please update your code accordingly.
72
+ * [New] Say hello to your new shortcodes. We merged the ShortCodes add-on directly into our main plugin. This improves the overall performance and streamlines our software lifecycle. Please note: the shortcode syntax has been updated and simplified (you need to replace 'popular' with 'top'). All the information is being added to our [knowledge base](http://docs.wp-slimstat.com/) for your convenience. Stay tuned or contact our support team for more information.
73
  * [Update] [AmMap](http://www.amcharts.com/javascript-maps/) has been updated to version 3.14.2. Please consider supporting this project by [purchasing a license](http://www.amcharts.com/online-store/).
74
  * [Fix] We took care of various warnings displayed with DEBUG_MODE enabled.
75
  * [Fix] The data import script failed to do its job in some multisite environments (thank you, pepe).
128
  * [Update] Removed banner from our partner ManageWP
129
 
130
  = 3.9.8 =
 
131
  * [New] A few new options under Slimstat > Settings > General tab > WordPress Integration section, allow you to have more control over the information displayed in the Posts admin screen (thank you, Brad).
132
 
133
  = 3.9.7 =
151
  * [Fix] Report filters could not be removed after being set.
152
 
153
  = 3.9.5 =
154
+ * [Note] Some of our add-ons had a bug preventing them from properly checking for updates. Please [contact us](http://support.wp-slimstat.com) if you need to obtain the latest version of your add-ons.
155
  * [Update] The Save button in the settings is now always visible, so that there is no need to scroll all the way to the bottom to save your options.
156
  * [Update] More data layer updates introduced in wp_slimstat_db. Keep an eye on your custom add-ons!
157
  * [Fix] Pagination was not working as expected when a date range was set in the filters (thank you, [nick-v](https://wordpress.org/support/topic/paging-is-broke))
158
 
159
  = 3.9.4 =
160
  * [Note] The URL of the CDN has changed, and is now using the official WordPress repository as a source: cdn.jsdelivr.net/wp/wp-slimstat/trunk/wp-slimstat.js - Please update your "external" tracking codes accordingly.
161
+ * [Note] The structure of the array **wp_slimstat_db::$sql_filters** has changed! Please make sure to update your custom code accordingly. Feel free to [contact us](http://support.wp-slimstat.com) for more information.
162
+ * [New] The wait is over. Our heatmap add-on is finally [available on our store](http://www.wp-slimstat.com/downloads/heatmap/)! We would like to thank all those who provided helpful feedback to improve this initial release!
163
+ * [New] Our [knowledge base](http://docs.wp-slimstat.com/) has been extended with a list of all the actions and filters available in Slimstat.
164
  * [Fix] The Add-on update checker had a bug preventing the functionality to work as expected. Please make sure to get the latest version of your premium add-ons!
165
  * [Fix] Date intervals were not accurate because of a bug related to calculating timezones in MySQL (thank you, [Chrisssssi](https://wordpress.org/support/topic/conflicting-data)).
166
  * [Fix] Line height of report rows has been added to avoid conflicts with other plugins tweaking this parameter in the admin (thank you, [yk11](https://wordpress.org/support/topic/widgets-bottom-is-cut-off)).
286
  Wayne Liebman,
287
  Willow Ridge Press
288
 
289
+ == Tools of the trade
290
  [Duri.Me](http://duri.me/),
291
  [Filezilla](https://filezilla-project.org/),
292
  [Fontello](http://fontello.com/),
wp-slimstat.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: WP Slimstat
4
  Plugin URI: http://wordpress.org/plugins/wp-slimstat/
5
  Description: The leading web analytics plugin for WordPress
6
- Version: 4.1
7
  Author: Camu
8
  Author URI: http://slimstat.getused.to.it/
9
  */
@@ -11,7 +11,7 @@ Author URI: http://slimstat.getused.to.it/
11
  if (!empty(wp_slimstat::$options)) return true;
12
 
13
  class wp_slimstat{
14
- public static $version = '4.1';
15
  public static $options = array();
16
 
17
  public static $wpdb = '';
3
  Plugin Name: WP Slimstat
4
  Plugin URI: http://wordpress.org/plugins/wp-slimstat/
5
  Description: The leading web analytics plugin for WordPress
6
+ Version: 4.1.1
7
  Author: Camu
8
  Author URI: http://slimstat.getused.to.it/
9
  */
11
  if (!empty(wp_slimstat::$options)) return true;
12
 
13
  class wp_slimstat{
14
+ public static $version = '4.1.1';
15
  public static $options = array();
16
 
17
  public static $wpdb = '';