Slimstat Analytics - Version 4.0.1

Version Description

  • [Note] Version 4.0 had a bumpy start, but that's expected when something radically new is released to the public. We got in touch with some of our users to ask them to test 4.0 before it was released, but unfortunately people are busy, and out of 120 requests for testing, we only got feedback from 3 users. Such is life.
  • [Note] Make sure to uninstall the Dashboard Widgets add-on before upgrading to Slimstat 4.0, or you might get a white screen of death. If this is the case, please remove the folder wp-content/plugins/wp-slimstat-dashboard-widgets via FTP. You will not lose your data.
  • [New] Say hello to your new Dashboard Widgets. We decided to merge our free add-on into the main plugin: this way you don't have to deal with a separate software, our update cycle is streamlined, and performance increases. You can always deactivate this integration by using the corresponding option under Settings > General.
  • [Fix] A few people pointed out a Unexpected T_FUNCTION parse error. Slimstat officially requires PHP 5.3 to function properly. Nevertheless, we implemented a workaround so that people with PHP 5.2 can still enjoy all the power of our plugin. Thank you for your patience.
  • [Fix] MySQL Error 121 was preventing the plugin from creating the new table structure, if MySQL was configured to work in strict mode (thank you, wvploeg)
  • [Fix] If you compile PHP with certain flags on Ubuntu, gzopen is not available (thank you, larryisthere)
Download this release

Release Info

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

Code changes from version 4.0 to 4.0.1

admin/config/index.php CHANGED
@@ -25,7 +25,8 @@ switch ($config_tabs[$current_tab-1]){
25
 
26
  'general_integration_header' => array('description' => __('WordPress Integration','wp-slimstat'), 'type' => 'section_header'),
27
  'use_separate_menu' => array( 'description' => __('Menu Position','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Choose between a standalone admin menu for Slimstat or a drop down in the admin bar (if visible).','wp-slimstat'), 'custom_label_yes' => __('Side Menu','wp-slimstat'), 'custom_label_no' => __('Admin Bar','wp-slimstat') ),
28
- 'add_posts_column' => array( 'description' => __('Add Stats to Posts and Pages','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Add a new column to the Edit Posts/Pages screens, with the number of hits per post in the last 365 days.','wp-slimstat') ),
 
29
  'posts_column_day_interval' => array( 'description' => __('Report Interval','wp-slimstat'), 'type' => 'integer', 'long_description' => __('Enter the time range, in days, that should be used to calculate the value here above.','wp-slimstat') ),
30
  'posts_column_pageviews' => array( 'description' => __('Report Type','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Select what kind of information you would like to see displayed on the Posts admin screen. Pageviews include all the hits regardless of the user, Unique IPs consider only one hit per user in the given time range.','wp-slimstat'), 'custom_label_yes' => __('Pageviews','wp-slimstat'), 'custom_label_no' => __('Unique IPs','wp-slimstat') ),
31
 
25
 
26
  'general_integration_header' => array('description' => __('WordPress Integration','wp-slimstat'), 'type' => 'section_header'),
27
  'use_separate_menu' => array( 'description' => __('Menu Position','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Choose between a standalone admin menu for Slimstat or a drop down in the admin bar (if visible).','wp-slimstat'), 'custom_label_yes' => __('Side Menu','wp-slimstat'), 'custom_label_no' => __('Admin Bar','wp-slimstat') ),
28
+ 'add_posts_column' => array( 'description' => __('Posts and Pages','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Add a new column to the Edit Posts/Pages screens, with the number of hits per post in the last 365 days.','wp-slimstat') ),
29
+ 'add_dashboard_widgets' => array( 'description' => __('Dashboard Widgets','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Choose if you want to have the most important reports on your WordPress Dashboard. Use the Screen Options dropdown to select which ones to display.','wp-slimstat') ),
30
  'posts_column_day_interval' => array( 'description' => __('Report Interval','wp-slimstat'), 'type' => 'integer', 'long_description' => __('Enter the time range, in days, that should be used to calculate the value here above.','wp-slimstat') ),
31
  'posts_column_pageviews' => array( 'description' => __('Report Type','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Select what kind of information you would like to see displayed on the Posts admin screen. Pageviews include all the hits regardless of the user, Unique IPs consider only one hit per user in the given time range.','wp-slimstat'), 'custom_label_yes' => __('Pageviews','wp-slimstat'), 'custom_label_no' => __('Unique IPs','wp-slimstat') ),
32
 
admin/view/wp-slimstat-reports.php CHANGED
@@ -40,7 +40,7 @@ class wp_slimstat_reports {
40
  'title' => __( 'Pageviews', 'wp-slimstat' ),
41
  'callback' => 'report_body',
42
  'classes' => array( 'wide', 'chart' ),
43
- 'screens' => array( 'wp-slim-view-2' ),
44
  'tooltip' => $chart_tooltip
45
  ),
46
  'slim_p1_02' => array(
@@ -54,14 +54,14 @@ class wp_slimstat_reports {
54
  'title' => __( 'At a Glance', 'wp-slimstat' ),
55
  'callback' => 'report_body',
56
  'classes' => array( 'normal' ),
57
- 'screens' => array( 'wp-slim-view-2' ),
58
  'tooltip' => ''
59
  ),
60
  'slim_p1_04' => array(
61
  'title' => __( 'Currently Online', 'wp-slimstat' ),
62
  'callback' => 'report_body',
63
  'classes' => array( 'normal' ),
64
- 'screens' => array( 'wp-slim-view-2' ),
65
  'tooltip' => __( 'When visitors leave a comment on your blog, WordPress assigns them a cookie. Slimstat leverages this information to identify returning visitors. Please note that visitors also include registered users.', 'wp-slimstat' )
66
  ),
67
  'slim_p1_06' => array(
@@ -75,35 +75,35 @@ class wp_slimstat_reports {
75
  'title' => __( 'Top Pages', 'wp-slimstat' ),
76
  'callback' => 'report_body',
77
  'classes' => array( 'normal' ),
78
- 'screens' => array( 'wp-slim-view-2' ),
79
  'tooltip' => __( 'Here a "page" is not just a WordPress page type, but any web page on your website, including posts, products, categories, and so on.', 'wp-slimstat' )
80
  ),
81
  'slim_p1_10' => array(
82
  'title' => __('Top Traffic Sources', 'wp-slimstat'),
83
  'callback' => 'report_body',
84
  'classes' => array( 'normal' ),
85
- 'screens' => array( 'wp-slim-view-2', 'wp-slim-view-5' ),
86
  'tooltip' => ''
87
  ),
88
  'slim_p1_11' => array(
89
  'title' => __( 'Top Known Visitors', 'wp-slimstat' ),
90
  'callback' => 'report_body',
91
  'classes' => array( 'normal', 'hidden' ),
92
- 'screens' => array( 'wp-slim-view-2' ),
93
  'tooltip' => ''
94
  ),
95
  'slim_p1_12' => array(
96
  'title' => __( 'Top Search Terms', 'wp-slimstat' ),
97
  'callback' => 'report_body',
98
  'classes' => array( 'normal' ),
99
- 'screens' => array( 'wp-slim-view-2', 'wp-slim-view-4', 'wp-slim-view-5' ),
100
  'tooltip' => ''
101
  ),
102
  'slim_p1_13' => array(
103
  'title' => __( 'Top Countries', 'wp-slimstat' ),
104
  'callback' => 'report_body',
105
  'classes' => array( 'normal', 'hidden' ),
106
- 'screens' => array( 'wp-slim-view-2', 'wp-slim-view-3', 'wp-slim-view-5' ),
107
  'tooltip' => __( 'You can configure Slimstat to ignore a specific Country by setting the corresponding filter under Settings > Slimstat > Filters.', 'wp-slimstat' )
108
  ),
109
  'slim_p1_15' => array(
@@ -132,7 +132,7 @@ class wp_slimstat_reports {
132
  'title' => __( 'Audience Overview', 'wp-slimstat' ),
133
  'callback' => 'report_body',
134
  'classes' => array( 'normal' ),
135
- 'screens' => array( 'wp-slim-view-3' ),
136
  'tooltip' => __( 'Where not otherwise specified, the metrics in this report are referred to human visitors.', 'wp-slimstat' )
137
  ),
138
  'slim_p2_03' => array(
@@ -143,7 +143,7 @@ class wp_slimstat_reports {
143
  'tooltip' => ''
144
  ),
145
  'slim_p2_04' => array(
146
- 'title' => __( 'Top Browsers', 'wp-slimstat' ),
147
  'callback' => 'report_body',
148
  'classes' => array( 'normal' ),
149
  'screens' => array( 'wp-slim-view-3' ),
@@ -167,7 +167,7 @@ class wp_slimstat_reports {
167
  'title' => __( 'Top Screen Resolutions', 'wp-slimstat' ),
168
  'callback' => 'report_body',
169
  'classes' => array( 'normal' ),
170
- 'screens' => array( 'wp-slim-view-3' ),
171
  'tooltip' => ''
172
  ),
173
  'slim_p2_09' => array(
@@ -244,7 +244,7 @@ class wp_slimstat_reports {
244
  'title' => __( 'Top Users', 'wp-slimstat' ),
245
  'callback' => 'report_body',
246
  'classes' => array( 'normal', 'hidden' ),
247
- 'screens' => array( 'wp-slim-view-3' ),
248
  'tooltip' => ''
249
  ),
250
 
@@ -266,7 +266,7 @@ class wp_slimstat_reports {
266
  'title' => __( 'Top Referring Search Engines', 'wp-slimstat' ),
267
  'callback' => 'report_body',
268
  'classes' => array( 'normal' ),
269
- 'screens' => array( 'wp-slim-view-5' ),
270
  'tooltip' => ''
271
  ),
272
  'slim_p3_11' => array(
@@ -325,7 +325,7 @@ class wp_slimstat_reports {
325
  'title' => __( 'Top Categories', 'wp-slimstat' ),
326
  'callback' => 'report_body',
327
  'classes' => array( 'normal' ),
328
- 'screens' => array( 'wp-slim-view-4' ),
329
  'tooltip' => ''
330
  ),
331
  /*
@@ -377,7 +377,7 @@ class wp_slimstat_reports {
377
  'title' => __( 'Top Authors', 'wp-slimstat' ),
378
  'callback' => 'report_body',
379
  'classes' => array( 'normal' ),
380
- 'screens' => array( 'wp-slim-view-4' ),
381
  'tooltip' => ''
382
  ),
383
  'slim_p4_19' => array(
@@ -544,16 +544,20 @@ class wp_slimstat_reports {
544
  }
545
  // end init
546
 
547
- public static function report_body($_report_id = 'p0', $_force_return = false) {
548
  $is_ajax = false;
 
549
  if ( !empty( $_POST[ 'report_id' ] ) ) {
550
  // Let's make sure the request is coming from the right place
551
  check_ajax_referer( 'meta-box-order', 'security' );
552
  $_report_id = $_POST[ 'report_id' ];
553
  $is_ajax = true;
554
  }
 
 
 
555
 
556
- if ( !$_force_return && !$is_ajax && ( in_array( 'hidden', self::$reports_info[ $_report_id ][ 'classes' ] ) || wp_slimstat::$options['async_load'] == 'yes' ) ) {
557
  return 0;
558
  }
559
 
@@ -1567,12 +1571,20 @@ class wp_slimstat_reports {
1567
  public static function fs_url($_filters = ''){
1568
 
1569
  // Allow only legitimate requests
1570
- if ( !array_key_exists( $_REQUEST[ 'page' ], self::$screens_info ) ){
 
 
 
 
 
 
 
 
1571
  return '';
1572
  }
1573
 
1574
- $filtered_url = ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ? explode( '?', $_SERVER["HTTP_REFERER"] ) : explode( '?', $_SERVER['REQUEST_URI'] );
1575
- $filtered_url = $filtered_url[ 0 ] . '?page=' . $_REQUEST[ 'page' ];
1576
 
1577
  // Columns
1578
  $filters_normalized = wp_slimstat_db::parse_filters( $_filters, false );
40
  'title' => __( 'Pageviews', 'wp-slimstat' ),
41
  'callback' => 'report_body',
42
  'classes' => array( 'wide', 'chart' ),
43
+ 'screens' => array( 'wp-slim-view-2', 'dashboard' ),
44
  'tooltip' => $chart_tooltip
45
  ),
46
  'slim_p1_02' => array(
54
  'title' => __( 'At a Glance', 'wp-slimstat' ),
55
  'callback' => 'report_body',
56
  'classes' => array( 'normal' ),
57
+ 'screens' => array( 'wp-slim-view-2', 'dashboard' ),
58
  'tooltip' => ''
59
  ),
60
  'slim_p1_04' => array(
61
  'title' => __( 'Currently Online', 'wp-slimstat' ),
62
  'callback' => 'report_body',
63
  'classes' => array( 'normal' ),
64
+ 'screens' => array( 'wp-slim-view-2', 'dashboard' ),
65
  'tooltip' => __( 'When visitors leave a comment on your blog, WordPress assigns them a cookie. Slimstat leverages this information to identify returning visitors. Please note that visitors also include registered users.', 'wp-slimstat' )
66
  ),
67
  'slim_p1_06' => array(
75
  'title' => __( 'Top Pages', 'wp-slimstat' ),
76
  'callback' => 'report_body',
77
  'classes' => array( 'normal' ),
78
+ 'screens' => array( 'wp-slim-view-2', 'dashboard' ),
79
  'tooltip' => __( 'Here a "page" is not just a WordPress page type, but any web page on your website, including posts, products, categories, and so on.', 'wp-slimstat' )
80
  ),
81
  'slim_p1_10' => array(
82
  'title' => __('Top Traffic Sources', 'wp-slimstat'),
83
  'callback' => 'report_body',
84
  'classes' => array( 'normal' ),
85
+ 'screens' => array( 'wp-slim-view-2', 'wp-slim-view-5', 'dashboard' ),
86
  'tooltip' => ''
87
  ),
88
  'slim_p1_11' => array(
89
  'title' => __( 'Top Known Visitors', 'wp-slimstat' ),
90
  'callback' => 'report_body',
91
  'classes' => array( 'normal', 'hidden' ),
92
+ 'screens' => array( 'wp-slim-view-2', 'dashboard' ),
93
  'tooltip' => ''
94
  ),
95
  'slim_p1_12' => array(
96
  'title' => __( 'Top Search Terms', 'wp-slimstat' ),
97
  'callback' => 'report_body',
98
  'classes' => array( 'normal' ),
99
+ 'screens' => array( 'wp-slim-view-2', 'wp-slim-view-4', 'wp-slim-view-5', 'dashboard' ),
100
  'tooltip' => ''
101
  ),
102
  'slim_p1_13' => array(
103
  'title' => __( 'Top Countries', 'wp-slimstat' ),
104
  'callback' => 'report_body',
105
  'classes' => array( 'normal', 'hidden' ),
106
+ 'screens' => array( 'wp-slim-view-2', 'wp-slim-view-3', 'wp-slim-view-5', 'dashboard' ),
107
  'tooltip' => __( 'You can configure Slimstat to ignore a specific Country by setting the corresponding filter under Settings > Slimstat > Filters.', 'wp-slimstat' )
108
  ),
109
  'slim_p1_15' => array(
132
  'title' => __( 'Audience Overview', 'wp-slimstat' ),
133
  'callback' => 'report_body',
134
  'classes' => array( 'normal' ),
135
+ 'screens' => array( 'wp-slim-view-3', 'dashboard' ),
136
  'tooltip' => __( 'Where not otherwise specified, the metrics in this report are referred to human visitors.', 'wp-slimstat' )
137
  ),
138
  'slim_p2_03' => array(
143
  'tooltip' => ''
144
  ),
145
  'slim_p2_04' => array(
146
+ 'title' => __( 'Top Browsers', 'wp-slimstat', 'dashboard' ),
147
  'callback' => 'report_body',
148
  'classes' => array( 'normal' ),
149
  'screens' => array( 'wp-slim-view-3' ),
167
  'title' => __( 'Top Screen Resolutions', 'wp-slimstat' ),
168
  'callback' => 'report_body',
169
  'classes' => array( 'normal' ),
170
+ 'screens' => array( 'wp-slim-view-3', 'dashboard' ),
171
  'tooltip' => ''
172
  ),
173
  'slim_p2_09' => array(
244
  'title' => __( 'Top Users', 'wp-slimstat' ),
245
  'callback' => 'report_body',
246
  'classes' => array( 'normal', 'hidden' ),
247
+ 'screens' => array( 'wp-slim-view-3', 'dashboard' ),
248
  'tooltip' => ''
249
  ),
250
 
266
  'title' => __( 'Top Referring Search Engines', 'wp-slimstat' ),
267
  'callback' => 'report_body',
268
  'classes' => array( 'normal' ),
269
+ 'screens' => array( 'wp-slim-view-5', 'dashboard' ),
270
  'tooltip' => ''
271
  ),
272
  'slim_p3_11' => array(
325
  'title' => __( 'Top Categories', 'wp-slimstat' ),
326
  'callback' => 'report_body',
327
  'classes' => array( 'normal' ),
328
+ 'screens' => array( 'wp-slim-view-4', 'dashboard' ),
329
  'tooltip' => ''
330
  ),
331
  /*
377
  'title' => __( 'Top Authors', 'wp-slimstat' ),
378
  'callback' => 'report_body',
379
  'classes' => array( 'normal' ),
380
+ 'screens' => array( 'wp-slim-view-4', 'dashboard' ),
381
  'tooltip' => ''
382
  ),
383
  'slim_p4_19' => array(
544
  }
545
  // end init
546
 
547
+ public static function report_body( $_report_id = '', $_args = false ) {
548
  $is_ajax = false;
549
+
550
  if ( !empty( $_POST[ 'report_id' ] ) ) {
551
  // Let's make sure the request is coming from the right place
552
  check_ajax_referer( 'meta-box-order', 'security' );
553
  $_report_id = $_POST[ 'report_id' ];
554
  $is_ajax = true;
555
  }
556
+ else if ( !empty( $_args[ 'id' ] ) ){
557
+ $_report_id = $_args[ 'id' ];
558
+ }
559
 
560
+ if ( !$is_ajax && ( in_array( 'hidden', self::$reports_info[ $_report_id ][ 'classes' ] ) || wp_slimstat::$options['async_load'] == 'yes' ) ) {
561
  return 0;
562
  }
563
 
1571
  public static function fs_url($_filters = ''){
1572
 
1573
  // Allow only legitimate requests
1574
+ $request_uri = $_SERVER['REQUEST_URI'];
1575
+ $request_page = $_REQUEST[ 'page' ];
1576
+
1577
+ // Are we on the Dashboard?
1578
+ if ( empty( $request_page ) ) {
1579
+ $request_uri = str_replace( 'index.php', 'admin.php', $request_uri );
1580
+ $request_page = 'wp-slim-view-1';
1581
+ }
1582
+ else if ( !array_key_exists( $_REQUEST[ 'page' ], self::$screens_info ) ){
1583
  return '';
1584
  }
1585
 
1586
+ $filtered_url = ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ? explode( '?', $_SERVER["HTTP_REFERER"] ) : explode( '?', $request_uri );
1587
+ $filtered_url = $filtered_url[ 0 ] . '?page=' . $request_page;
1588
 
1589
  // Columns
1590
  $filters_normalized = wp_slimstat_db::parse_filters( $_filters, false );
admin/wp-slimstat-admin.php CHANGED
@@ -12,6 +12,7 @@ class wp_slimstat_admin{
12
  public static function init(){
13
  if ((wp_slimstat::$options['enable_ads_network'] == 'yes' || wp_slimstat::$options['enable_ads_network'] == 'no')){
14
  self::$admin_notice = "Happy birthday, Slimstat. Nine years ago version 0.8.7 was released to the public, starting the unbelievable journey that has taken us here today. We would like to thank all the 100,000+ users (according to WordPress.org) who appreciate and support our work in many great ways. We wouldn't have more than 1.4 million downloads, 4.8 out of 5 overall rating, 16 add-ons, video tutorials, etc... if it weren't for <strong>you</strong>! To celebrate this special occasion, we decided to get to work and improve the overall performance of our plugin. Version 4.0 comes with a new simplified table structure (<a href='http://blog.codinghorror.com/maybe-normalizing-isnt-normal/' target='_blank'>denormalization, anyone</a>?), which will make your reports load so fast that your jaw will drop. Sure, the main table will be about 35% bigger, but in the age where disk space is cheap, the precioussss resource becomes time. The time you won't have to wait for your reports to load! <strong>Please note</strong>: if you have more than 750k records in your table, the import script will not run automatically. Go to Settings > Maintentance and click the Import Old Data button. Feel free to contact us if you need help.";
 
15
  }
16
  else {
17
  self::$admin_notice = "
@@ -129,6 +130,17 @@ class wp_slimstat_admin{
129
  add_action('wp_ajax_slimstat_load_report', array('wp_slimstat_reports', wp_slimstat_reports::$reports_info[ $report_id ][ 'callback' ] ) );
130
  }
131
 
 
 
 
 
 
 
 
 
 
 
 
132
  // AJAX Handlers
133
  if (defined('DOING_AJAX') && DOING_AJAX){
134
  add_action('wp_ajax_slimstat_hide_admin_notice', array(__CLASS__, 'hide_admin_notice'));
@@ -250,8 +262,8 @@ class wp_slimstat_admin{
250
  dt INT(10) UNSIGNED DEFAULT 0,
251
 
252
  CONSTRAINT PRIMARY KEY (event_id),
253
- INDEX idx_{$GLOBALS['wpdb']->prefix}slim_events (dt),
254
- CONSTRAINT fk_{$GLOBALS['wpdb']->prefix}id FOREIGN KEY (id) REFERENCES {$GLOBALS['wpdb']->prefix}slim_stats(id) ON UPDATE CASCADE ON DELETE CASCADE
255
  ) COLLATE utf8_general_ci $use_innodb";
256
 
257
  $archive_table_sql = "
@@ -487,6 +499,30 @@ class wp_slimstat_admin{
487
  }
488
  // end update_tables_and_options
489
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
490
  /**
491
  * Removes 'spammers' from the database when the corresponding comments are marked as spam
492
  */
@@ -535,10 +571,10 @@ class wp_slimstat_admin{
535
  }
536
  // end wp_slimstat_userdefined_stylesheet
537
 
538
- public static function wp_slimstat_enqueue_scripts(){
539
  wp_enqueue_script('dashboard');
540
  wp_enqueue_script('jquery-ui-datepicker');
541
- wp_enqueue_script('slimstat_admin', plugins_url('/admin/js/slimstat.admin.js', dirname(__FILE__)), array('jquery-ui-dialog'), null);
542
 
543
  // Pass some information to Javascript
544
  $params = array(
12
  public static function init(){
13
  if ((wp_slimstat::$options['enable_ads_network'] == 'yes' || wp_slimstat::$options['enable_ads_network'] == 'no')){
14
  self::$admin_notice = "Happy birthday, Slimstat. Nine years ago version 0.8.7 was released to the public, starting the unbelievable journey that has taken us here today. We would like to thank all the 100,000+ users (according to WordPress.org) who appreciate and support our work in many great ways. We wouldn't have more than 1.4 million downloads, 4.8 out of 5 overall rating, 16 add-ons, video tutorials, etc... if it weren't for <strong>you</strong>! To celebrate this special occasion, we decided to get to work and improve the overall performance of our plugin. Version 4.0 comes with a new simplified table structure (<a href='http://blog.codinghorror.com/maybe-normalizing-isnt-normal/' target='_blank'>denormalization, anyone</a>?), which will make your reports load so fast that your jaw will drop. Sure, the main table will be about 35% bigger, but in the age where disk space is cheap, the precioussss resource becomes time. The time you won't have to wait for your reports to load! <strong>Please note</strong>: if you have more than 750k records in your table, the import script will not run automatically. Go to Settings > Maintentance and click the Import Old Data button. Feel free to contact us if you need help.";
15
+ self::$admin_notice .= '<br/><br/><a id="slimstat-hide-admin-notice" href="#" class="button-secondary">I got it, thanks</a>';
16
  }
17
  else {
18
  self::$admin_notice = "
130
  add_action('wp_ajax_slimstat_load_report', array('wp_slimstat_reports', wp_slimstat_reports::$reports_info[ $report_id ][ 'callback' ] ) );
131
  }
132
 
133
+ // Dashboard Widgets
134
+ if ( wp_slimstat::$options[ 'add_dashboard_widgets' ] == 'yes' ) {
135
+ $temp = strlen( $_SERVER['REQUEST_URI'] ) - 10;
136
+
137
+ if( strpos( $_SERVER['REQUEST_URI'], 'index.php' ) !== false || ( $temp >= 0 && strpos($_SERVER['REQUEST_URI'], '/wp-admin/', $temp) !== false ) ) {
138
+ add_action( 'admin_enqueue_scripts', array(__CLASS__, 'wp_slimstat_enqueue_scripts' ) );
139
+ add_action( 'admin_enqueue_scripts', array(__CLASS__, 'wp_slimstat_stylesheet' ) );
140
+ }
141
+ add_action( 'wp_dashboard_setup', array( __CLASS__, 'add_dashboard_widgets' ) );
142
+ }
143
+
144
  // AJAX Handlers
145
  if (defined('DOING_AJAX') && DOING_AJAX){
146
  add_action('wp_ajax_slimstat_hide_admin_notice', array(__CLASS__, 'hide_admin_notice'));
262
  dt INT(10) UNSIGNED DEFAULT 0,
263
 
264
  CONSTRAINT PRIMARY KEY (event_id),
265
+ INDEX idx_{$GLOBALS['wpdb']->prefix}slim_stat_events (dt),
266
+ CONSTRAINT fk_{$GLOBALS['wpdb']->prefix}slim_events_id FOREIGN KEY (id) REFERENCES {$GLOBALS['wpdb']->prefix}slim_stats(id) ON UPDATE CASCADE ON DELETE CASCADE
267
  ) COLLATE utf8_general_ci $use_innodb";
268
 
269
  $archive_table_sql = "
499
  }
500
  // end update_tables_and_options
501
 
502
+ public static function add_dashboard_widgets(){
503
+
504
+ // If this user is whitelisted, we use the minimum capability
505
+ if ( strpos( wp_slimstat::$options[ 'can_view' ], $GLOBALS[ 'current_user' ]->user_login) === false ){
506
+ $minimum_capability = wp_slimstat::$options[ 'capability_can_view' ];
507
+ }
508
+ else{
509
+ $minimum_capability = 'read';
510
+ }
511
+
512
+ if ( !current_user_can( $minimum_capability ) ) {
513
+ return;
514
+ }
515
+
516
+ include_once(dirname(__FILE__).'/view/wp-slimstat-reports.php');
517
+ wp_slimstat_reports::init();
518
+
519
+ foreach ( wp_slimstat_reports::$reports_info as $a_report_id => $a_report_info ) {
520
+ if ( in_array( 'dashboard', $a_report_info[ 'screens' ] ) ) {
521
+ wp_add_dashboard_widget( $a_report_id, $a_report_info[ 'title' ], array( 'wp_slimstat_reports', $a_report_info[ 'callback' ] ) );
522
+ }
523
+ }
524
+ }
525
+
526
  /**
527
  * Removes 'spammers' from the database when the corresponding comments are marked as spam
528
  */
571
  }
572
  // end wp_slimstat_userdefined_stylesheet
573
 
574
+ public static function wp_slimstat_enqueue_scripts( $_hook = '' ) {
575
  wp_enqueue_script('dashboard');
576
  wp_enqueue_script('jquery-ui-datepicker');
577
+ wp_enqueue_script('slimstat_admin', plugins_url('/admin/js/slimstat.admin.js', dirname(__FILE__)), array('jquery-ui-dialog'), null, false);
578
 
579
  // Pass some information to Javascript
580
  $params = array(
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.0
8
 
9
  == Description ==
10
  [youtube https://www.youtube.com/watch?v=iJCtjxArq4U]
@@ -35,7 +35,6 @@ Stable tag: 4.0
35
  Visit [our website](http://slimstat.getused.to.it/addons/) for a list of available extensions.
36
 
37
  = Free Add-ons =
38
- * [WP Slimstat Dashboard Widgets](http://wordpress.org/extend/plugins/wp-slimstat-dashboard-widgets) adds the most important reports right on your WordPress Dashboard
39
  * [WP Slimstat Shortcodes](http://wordpress.org/extend/plugins/wp-slimstat-shortcodes/) allows you to share your reports with your readers
40
 
41
  == Installation ==
@@ -64,6 +63,14 @@ Our knowledge base is available on our [support center](https://slimstat.freshde
64
 
65
  == Changelog ==
66
 
 
 
 
 
 
 
 
 
67
  = 4.0 =
68
  * [Note] A brave new world is now ready to be explored: Slimstat 4.0. This version introduces a totally redesigned database architecture, new streamlined tracking code, new heuristic user agent parser, new filters and much more. You will surely notice the performance improvements!
69
  * [Note] Our dev team should have read [this article](http://blog.codinghorror.com/maybe-normalizing-isnt-normal/) a long time ago. But it's never too late, and we can guarantee you that the new denormalized table structure will make your report generation so quick that your jaw will drop. Sure, the table size will increase 50%, but in the age where space is cheap, the real precious resource is time. The time you won't have to wait for your report to appear!
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.0.1
8
 
9
  == Description ==
10
  [youtube https://www.youtube.com/watch?v=iJCtjxArq4U]
35
  Visit [our website](http://slimstat.getused.to.it/addons/) for a list of available extensions.
36
 
37
  = Free Add-ons =
 
38
  * [WP Slimstat Shortcodes](http://wordpress.org/extend/plugins/wp-slimstat-shortcodes/) allows you to share your reports with your readers
39
 
40
  == Installation ==
63
 
64
  == Changelog ==
65
 
66
+ = 4.0.1 =
67
+ * [Note] Version 4.0 had a bumpy start, but that's expected when something radically new is released to the public. We got in touch with some of our users to ask them to test 4.0 before it was released, but unfortunately people are busy, and out of 120 requests for testing, we only got feedback from 3 users. Such is life.
68
+ * [Note] Make sure to uninstall the Dashboard Widgets add-on before upgrading to Slimstat 4.0, or you might get a white screen of death. If this is the case, please remove the folder wp-content/plugins/wp-slimstat-dashboard-widgets via FTP. You will not lose your data.
69
+ * [New] Say hello to your new Dashboard Widgets. We decided to merge our free add-on into the main plugin: this way you don't have to deal with a separate software, our update cycle is streamlined, and performance increases. You can always deactivate this integration by using the corresponding option under Settings > General.
70
+ * [Fix] A few people pointed out a Unexpected T_FUNCTION parse error. Slimstat officially requires PHP 5.3 to function properly. Nevertheless, we implemented a workaround so that people with PHP 5.2 can still enjoy all the power of our plugin. Thank you for your patience.
71
+ * [Fix] MySQL Error 121 was preventing the plugin from creating the new table structure, if MySQL was configured to work in strict mode (thank you, [wvploeg](https://wordpress.org/support/topic/after-update-it-stopped-working?replies=6))
72
+ * [Fix] If you compile PHP with certain flags on Ubuntu, gzopen is not available (thank you, [larryisthere](https://wordpress.org/support/topic/geolite-db-installation-issue-on-ubuntu-trusty?replies=2))
73
+
74
  = 4.0 =
75
  * [Note] A brave new world is now ready to be explored: Slimstat 4.0. This version introduces a totally redesigned database architecture, new streamlined tracking code, new heuristic user agent parser, new filters and much more. You will surely notice the performance improvements!
76
  * [Note] Our dev team should have read [this article](http://blog.codinghorror.com/maybe-normalizing-isnt-normal/) a long time ago. But it's never too late, and we can guarantee you that the new denormalized table structure will make your report generation so quick that your jaw will drop. Sure, the table size will increase 50%, but in the age where space is cheap, the real precious resource is time. The time you won't have to wait for your report to appear!
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.0
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.0';
15
  public static $options = array();
16
 
17
  public static $wpdb = '';
@@ -22,6 +22,7 @@ class wp_slimstat{
22
  protected static $options_signature = '';
23
 
24
  protected static $browser = array();
 
25
  protected static $pidx = array('id' => false, 'response' => '');
26
 
27
  /**
@@ -899,71 +900,59 @@ class wp_slimstat{
899
  $browser['browser'] = $match['browser'][0];
900
  $browser['browser_version'] = $match['version'][0];
901
 
902
- $find = function ($search, &$key) use ($match){
903
- $xkey = array_search(strtolower($search), array_map('strtolower', $match['browser']));
904
- if ($xkey !== false) {
905
- $key = $xkey;
906
- return true;
907
- }
908
- return false;
909
- };
910
-
911
- $key = 0;
912
  $ekey = 0;
913
  if ($browser['browser'] == 'Iceweasel'){
914
  $browser['browser'] = 'Firefox';
915
  }
916
- elseif ($find('Playstation Vita', $key)){
917
  $browser['platform'] = 'CellOS';
918
  $browser['browser'] = 'PlayStation';
919
  $browser['browser_type'] = 2;
920
  }
921
- elseif ($find('Kindle Fire Build', $key) || $find('Silk', $key)){
922
- $browser['browser'] = $match['browser'][$key] == 'Silk' ? 'Silk' : 'Kindle';
923
  $browser['platform'] = 'Android';
924
- if ($browser['browser_version'] != $match['version'][$key] || !is_numeric($browser['browser_version'][0])){
925
  $browser['browser_version'] = $match['version'][array_search('Version', $match['browser'])];
926
  }
927
  $browser['browser_type'] = 2;
928
  }
929
- elseif ($find('Kindle', $key)){
930
- $browser['browser'] = $match['browser'][$key];
931
  $browser['platform'] = 'Android';
932
- $browser['browser_version'] = $match['version'][$key];
933
  $browser['browser_type'] = 2;
934
  }
935
- elseif ($find('OPR', $key)){
936
  $browser['browser'] = 'Opera';
937
- $browser['browser_version'] = $match['version'][$key];
938
  }
939
- elseif ($find('Opera', $key)){
940
  $browser['browser'] = 'Opera';
941
- $find('Version', $key);
942
- $browser['browser_version'] = $match['version'][$key];
943
  }
944
- elseif ($find('Midori', $key)){
945
  $browser['browser'] = 'Midori';
946
- $browser['browser_version'] = $match['version'][$key];
947
  }
948
- elseif ($browser['browser'] == 'MSIE' || ($rv_result && $find('Trident', $key)) || $find('Edge', $ekey)){
949
  $browser['browser'] = 'IE';
950
- if( $find('IEMobile', $key) ) {
951
  $browser['browser'] = 'IE';
952
- $browser['browser_version'] = $match['version'][$key];
953
  $browser['browser_type'] = 2;
954
- } elseif( $ekey ) {
955
- $browser['browser_version'] = $match['version'][$ekey];
956
  } else {
957
- $browser['browser_version'] = $rv_result ?: $match['version'][$key];
958
  }
959
- } elseif( $find('Vivaldi', $key) ) {
960
  $browser['browser'] = 'Vivaldi';
961
- $browser['browser_version'] = $match['version'][$key];
962
- } elseif( $find('Chrome', $key) ) {
963
  $browser['browser'] = 'Chrome';
964
- $browser['browser_version'] = $match['version'][$key];
965
  } elseif( $browser['browser'] == 'AppleWebKit' ) {
966
- if( ($browser['platform'] == 'Android' && !($key = 0)) ) {
967
  $browser['browser'] = 'Android Browser';
968
  $browser['browser_type'] = 2;
969
  } elseif( strpos($browser['platform'], 'BB') === 0 ) {
@@ -973,17 +962,18 @@ class wp_slimstat{
973
  } elseif( $browser['platform'] == 'BlackBerry' || $browser['platform'] == 'PlayBook' ) {
974
  $browser['browser'] = 'BlackBerry';
975
  $browser['browser_type'] = 2;
976
- } elseif( $find('Safari', $key) ) {
977
  $browser['browser'] = 'Safari';
978
- } elseif( $find('TizenBrowser', $key) ) {
979
  $browser['browser'] = 'TizenBrowser';
980
  }
981
 
982
- $find('Version', $key);
983
 
984
- $browser['browser_version'] = $match['version'][$key];
985
- } elseif( $key = preg_grep('/playstation \d/i', array_map('strtolower', $match['browser'])) ) {
986
- $key = reset($key);
 
987
 
988
  $browser['platform'] = 'CellOS';
989
  $browser['browser'] = 'NetFront';
@@ -1008,7 +998,18 @@ class wp_slimstat{
1008
  // end _get_browser
1009
 
1010
  /**
1011
- * Helper function for get_browser [courtesy of: GaretJax/PHPBrowsCap]
 
 
 
 
 
 
 
 
 
 
 
1012
  */
1013
  protected static function _preg_unquote($pattern, $matches){
1014
  $search = array('\\@', '\\.', '\\\\', '\\+', '\\[', '\\^', '\\]', '\\$', '\\(', '\\)', '\\{', '\\}', '\\=', '\\!', '\\<', '\\>', '\\|', '\\:', '\\-', '.*', '.', '\\?');
@@ -1180,15 +1181,29 @@ class wp_slimstat{
1180
  $maxmind_tmp = download_url('http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz', 5);
1181
 
1182
  if (is_wp_error($maxmind_tmp)){
1183
- return __('There was an error downloading the MaxMind Geolite DB:','wp-slimstat').' '.$maxmind_tmp->get_error_message();
1184
  }
1185
 
1186
- if (false === ($zh = gzopen($maxmind_tmp, 'rb'))){
1187
- return __('There was an error opening the zipped MaxMind Geolite DB','wp-slimstat');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1188
  }
1189
 
1190
- if (false === ($fh = fopen(self::$maxmind_path, 'wb'))){
1191
- return __('There was an error opening the unzipped MaxMind Geolite DB','wp-slimstat');
1192
  }
1193
 
1194
  while(($data = gzread($zh, 4096)) != false){
@@ -1234,6 +1249,7 @@ class wp_slimstat{
1234
  'enable_javascript' => $val_yes,
1235
  'javascript_mode' => $val_yes,
1236
  'add_posts_column' => $val_no,
 
1237
  'posts_column_day_interval' => 30,
1238
  'posts_column_pageviews' => $val_yes,
1239
  'use_separate_menu' => $val_yes,
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.0.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.0.1';
15
  public static $options = array();
16
 
17
  public static $wpdb = '';
22
  protected static $options_signature = '';
23
 
24
  protected static $browser = array();
25
+ protected static $heuristic_key = 0;
26
  protected static $pidx = array('id' => false, 'response' => '');
27
 
28
  /**
900
  $browser['browser'] = $match['browser'][0];
901
  $browser['browser_version'] = $match['version'][0];
902
 
 
 
 
 
 
 
 
 
 
 
903
  $ekey = 0;
904
  if ($browser['browser'] == 'Iceweasel'){
905
  $browser['browser'] = 'Firefox';
906
  }
907
+ elseif (self::_heuristic_find('Playstation Vita', $match)){
908
  $browser['platform'] = 'CellOS';
909
  $browser['browser'] = 'PlayStation';
910
  $browser['browser_type'] = 2;
911
  }
912
+ elseif ( self::_heuristic_find( 'Kindle Fire Build', $match ) || self::_heuristic_find( 'Silk', $match ) ) {
913
+ $browser['browser'] = $match['browser'][self::$heuristic_key] == 'Silk' ? 'Silk' : 'Kindle';
914
  $browser['platform'] = 'Android';
915
+ if ($browser['browser_version'] != $match['version'][self::$heuristic_key] || !is_numeric($browser['browser_version'][0])){
916
  $browser['browser_version'] = $match['version'][array_search('Version', $match['browser'])];
917
  }
918
  $browser['browser_type'] = 2;
919
  }
920
+ elseif ( self::_heuristic_find( 'Kindle', $match ) ) {
921
+ $browser['browser'] = $match['browser'][self::$heuristic_key];
922
  $browser['platform'] = 'Android';
923
+ $browser['browser_version'] = $match['version'][self::$heuristic_key];
924
  $browser['browser_type'] = 2;
925
  }
926
+ elseif ( self::_heuristic_find( 'OPR', $match ) ) {
927
  $browser['browser'] = 'Opera';
928
+ $browser['browser_version'] = $match['version'][self::$heuristic_key];
929
  }
930
+ elseif ( self::_heuristic_find( 'Opera', $match ) ) {
931
  $browser['browser'] = 'Opera';
932
+ self::_heuristic_find('Version', $match);
933
+ $browser['browser_version'] = $match['version'][self::$heuristic_key];
934
  }
935
+ elseif (self::_heuristic_find('Midori', $match)){
936
  $browser['browser'] = 'Midori';
937
+ $browser['browser_version'] = $match['version'][self::$heuristic_key];
938
  }
939
+ elseif ($browser['browser'] == 'MSIE' || ($rv_result && self::_heuristic_find('Trident', $match)) || self::_heuristic_find('Edge', $match)){
940
  $browser['browser'] = 'IE';
941
+ if( self::_heuristic_find('IEMobile', $match) ) {
942
  $browser['browser'] = 'IE';
943
+ $browser['browser_version'] = $match['version'][self::$heuristic_key];
944
  $browser['browser_type'] = 2;
 
 
945
  } else {
946
+ $browser['browser_version'] = $rv_result ?: $match['version'][self::$heuristic_key];
947
  }
948
+ } elseif( self::_heuristic_find('Vivaldi', $match) ) {
949
  $browser['browser'] = 'Vivaldi';
950
+ $browser['browser_version'] = $match['version'][self::$heuristic_key];
951
+ } elseif( self::_heuristic_find('Chrome', $match) ) {
952
  $browser['browser'] = 'Chrome';
953
+ $browser['browser_version'] = $match['version'][self::$heuristic_key];
954
  } elseif( $browser['browser'] == 'AppleWebKit' ) {
955
+ if( ($browser['platform'] == 'Android' && !(self::$heuristic_key = 0)) ) {
956
  $browser['browser'] = 'Android Browser';
957
  $browser['browser_type'] = 2;
958
  } elseif( strpos($browser['platform'], 'BB') === 0 ) {
962
  } elseif( $browser['platform'] == 'BlackBerry' || $browser['platform'] == 'PlayBook' ) {
963
  $browser['browser'] = 'BlackBerry';
964
  $browser['browser_type'] = 2;
965
+ } elseif( self::_heuristic_find('Safari', $match) ) {
966
  $browser['browser'] = 'Safari';
967
+ } elseif( self::_heuristic_find('TizenBrowser', $match) ) {
968
  $browser['browser'] = 'TizenBrowser';
969
  }
970
 
971
+ self::_heuristic_find('Version', $match);
972
 
973
+ $browser['browser_version'] = $match['version'][self::$heuristic_key];
974
+ } elseif( self::$heuristic_key = preg_grep('/playstation \d/i', array_map('strtolower', $match['browser'])) ) {
975
+ self::$heuristic_key = reset(self::$heuristic_key);
976
+ self::$heuristic_key = reset(self::$heuristic_key);
977
 
978
  $browser['platform'] = 'CellOS';
979
  $browser['browser'] = 'NetFront';
998
  // end _get_browser
999
 
1000
  /**
1001
+ * Helper function for get_browser [ courtesy of: https://github.com/donatj/PhpUserAgent ]
1002
+ */
1003
+ protected static function _heuristic_find( $search, $match ) {
1004
+ $xkey = array_search( strtolower( $search ), array_map( 'strtolower', $match[ 'browser' ] ) );
1005
+ if ( $xkey !== false ) {
1006
+ self::$heuristic_key = $xkey;
1007
+ return true;
1008
+ }
1009
+ return false;
1010
+ }
1011
+ /**
1012
+ * Helper function for get_browser [ courtesy of: GaretJax/PHPBrowsCap ]
1013
  */
1014
  protected static function _preg_unquote($pattern, $matches){
1015
  $search = array('\\@', '\\.', '\\\\', '\\+', '\\[', '\\^', '\\]', '\\$', '\\(', '\\)', '\\{', '\\}', '\\=', '\\!', '\\<', '\\>', '\\|', '\\:', '\\-', '.*', '.', '\\?');
1181
  $maxmind_tmp = download_url('http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz', 5);
1182
 
1183
  if (is_wp_error($maxmind_tmp)){
1184
+ return __('There was an error downloading the MaxMind Geolite DB:', 'wp-slimstat').' '.$maxmind_tmp->get_error_message();
1185
  }
1186
 
1187
+ $zh = false;
1188
+
1189
+ if ( !function_exists( 'gzopen' ) ) {
1190
+ if ( function_exists( 'gzopen64' ) ) {
1191
+ if ( false === ( $zh = gzopen64( $maxmind_tmp, 'rb' ) ) ) {
1192
+ return __( 'There was an error opening the zipped MaxMind Geolite DB.', 'wp-slimstat' );
1193
+ }
1194
+ }
1195
+ else {
1196
+ return __( 'Function gzopen not defined. Aborting.', 'wp-slimstat' );
1197
+ }
1198
+ }
1199
+ else{
1200
+ if ( false === ( $zh = gzopen( $maxmind_tmp, 'rb' ) ) ) {
1201
+ return __( 'There was an error opening the zipped MaxMind Geolite DB.', 'wp-slimstat' );
1202
+ }
1203
  }
1204
 
1205
+ if ( false === ( $fh = fopen( self::$maxmind_path, 'wb' ) ) ) {
1206
+ return __('There was an error opening the unzipped MaxMind Geolite DB.','wp-slimstat');
1207
  }
1208
 
1209
  while(($data = gzread($zh, 4096)) != false){
1249
  'enable_javascript' => $val_yes,
1250
  'javascript_mode' => $val_yes,
1251
  'add_posts_column' => $val_no,
1252
+ 'add_dashboard_widgets' => $val_yes,
1253
  'posts_column_day_interval' => 30,
1254
  'posts_column_pageviews' => $val_yes,
1255
  'use_separate_menu' => $val_yes,