Slimstat Analytics - Version 4.7.1

Version Description

  • [Fix] The new feature introduced in version 4.6.9.1 to allow our users to customize the default time range for the reports, had introduced a regression bug. Thank you to all our users who volunteered to test the bugfix.
  • [Fix] A vulnerability has been disclosed by Pluginvulnerabilities.com: an attacker with admin credentials could leverage the import/export mechanism for the plugin's settings to inject some malicious code. We recommend that you upgrade to the latest version of Slimstat as soon as possible.
  • [Fix] The new version of the Add-on Update Checker library, bundled with the previous release, was returning a fatal error under certain circumstances (thank you, Pepe).
Download this release

Release Info

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

Code changes from version 4.7 to 4.7.1

admin/config/index.php CHANGED
@@ -196,7 +196,7 @@ $settings = array(
196
  'restrict_authors_view' => array('description' => __('Restrict Authors','wp-slimstat'), 'type' => 'toggle', 'long_description' => __('Enable this option if you want your authors to only see stats related to their own content.','wp-slimstat')),
197
  'capability_can_view' => array('description' => __('Capability','wp-slimstat'), 'type' => 'text', 'long_description' => __("Specify the minimum <a href='http://codex.wordpress.org/Roles_and_Capabilities' target='_new'>capability</a> needed to access the reports (default: <code>activate_plugins</code>). If this field is empty, <strong>all your users</strong> (including subscribers) will have access to the reports, unless a 'Read access' whitelist has been specified here below. In this case, the list has precedence over the capability.",'wp-slimstat')),
198
  'can_view' => array('description' => __('Whitelist','wp-slimstat'), 'type' => 'textarea', 'long_description' => __("List all the users who should have access to the reports. Administrators are implicitly allowed, so you don't need to list them in here. Usernames are case sensitive.",'wp-slimstat'), 'skip_update' => true),
199
- 'rest_api_tokens' => array( 'description' => __( 'REST API Tokens', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "In order to send requests to the Slimstat REST API, you will need to pass a valid token to the endpoint (param ?token=XXX). Using the field here below, you can define as many tokens as you like, to distribute them to your API users. Please note: treat these tokens as passwords, as they will grant read access to your reports to anyone who knows them. Use a service like <a href='https://randomkeygen.com/#ci_key' target='_blank'>RandomKeyGen.com</a> to generate unique secure tokens.", 'wp-slimstat' ) ),
200
 
201
  'permissions_config_header' => array('description' => __('Settings','wp-slimstat'), 'type' => 'section_header'),
202
  'capability_can_admin' => array('description' => __('Capability','wp-slimstat'), 'type' => 'text', 'long_description' => __("Specify the minimum <a href='http://codex.wordpress.org/Roles_and_Capabilities' target='_new'>capability</a> required to configure Slimstat (default: <code>activate_plugins</code>). The whitelist here below can be used to override this option for specific users.",'wp-slimstat')),
196
  'restrict_authors_view' => array('description' => __('Restrict Authors','wp-slimstat'), 'type' => 'toggle', 'long_description' => __('Enable this option if you want your authors to only see stats related to their own content.','wp-slimstat')),
197
  'capability_can_view' => array('description' => __('Capability','wp-slimstat'), 'type' => 'text', 'long_description' => __("Specify the minimum <a href='http://codex.wordpress.org/Roles_and_Capabilities' target='_new'>capability</a> needed to access the reports (default: <code>activate_plugins</code>). If this field is empty, <strong>all your users</strong> (including subscribers) will have access to the reports, unless a 'Read access' whitelist has been specified here below. In this case, the list has precedence over the capability.",'wp-slimstat')),
198
  'can_view' => array('description' => __('Whitelist','wp-slimstat'), 'type' => 'textarea', 'long_description' => __("List all the users who should have access to the reports. Administrators are implicitly allowed, so you don't need to list them in here. Usernames are case sensitive.",'wp-slimstat'), 'skip_update' => true),
199
+ 'rest_api_tokens' => array( 'description' => __( 'REST API Tokens', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "In order to send requests to <a href='https://slimstat.freshdesk.com/support/solutions/articles/12000033661-slimstat-rest-api' target='_blank'>the Slimstat REST API</a>, you will need to pass a valid token to the endpoint (param ?token=XXX). Using the field here below, you can define as many tokens as you like, to distribute them to your API users. Please note: treat these tokens as passwords, as they will grant read access to your reports to anyone who knows them. Use a service like <a href='https://randomkeygen.com/#ci_key' target='_blank'>RandomKeyGen.com</a> to generate unique secure tokens.", 'wp-slimstat' ) ),
200
 
201
  'permissions_config_header' => array('description' => __('Settings','wp-slimstat'), 'type' => 'section_header'),
202
  'capability_can_admin' => array('description' => __('Capability','wp-slimstat'), 'type' => 'text', 'long_description' => __("Specify the minimum <a href='http://codex.wordpress.org/Roles_and_Capabilities' target='_new'>capability</a> required to configure Slimstat (default: <code>activate_plugins</code>). The whitelist here below can be used to override this option for specific users.",'wp-slimstat')),
admin/config/maintenance.php CHANGED
@@ -79,7 +79,8 @@ if ( !empty( $_REQUEST[ 'action' ] ) ) {
79
  break;
80
 
81
  case 'import-settings':
82
- $new_settings = @unserialize( stripslashes( $_POST[ 'import-slimstat-settings' ] ) );
 
83
  if ( is_array( $new_settings ) ) {
84
  $new_settings = array_intersect_key( $new_settings, wp_slimstat::$settings );
85
  if ( !empty( $new_settings ) ) {
@@ -312,7 +313,7 @@ $slim_browsers_exists =wp_slimstat::$wpdb->get_col( "SHOW TABLES LIKE '{$GLOBALS
312
  <form action="<?php echo wp_slimstat_admin::$config_url.$current_tab ?>" method="post">
313
  <?php wp_nonce_field( 'maintenance_wp_slimstat', 'maintenance_wp_slimstat_nonce', true, true ) ?>
314
  <input type="hidden" name="action" value="import-settings" />
315
- <textarea name="import-slimstat-settings" style="width:100%" rows="5" onClick="this.select();"><?php echo serialize( wp_slimstat::$settings ) ?></textarea><br/>
316
  <input type="submit" value="<?php _e('Import','wp-slimstat') ?>" class="button-secondary"
317
  onclick="return(confirm('<?php _e('Are you sure you want to OVERWRITE your current settings?','wp-slimstat'); ?>'))">
318
  </form>
79
  break;
80
 
81
  case 'import-settings':
82
+ $new_settings = @json_decode( stripslashes( $_POST[ 'import-slimstat-settings' ] ), true );
83
+
84
  if ( is_array( $new_settings ) ) {
85
  $new_settings = array_intersect_key( $new_settings, wp_slimstat::$settings );
86
  if ( !empty( $new_settings ) ) {
313
  <form action="<?php echo wp_slimstat_admin::$config_url.$current_tab ?>" method="post">
314
  <?php wp_nonce_field( 'maintenance_wp_slimstat', 'maintenance_wp_slimstat_nonce', true, true ) ?>
315
  <input type="hidden" name="action" value="import-settings" />
316
+ <textarea name="import-slimstat-settings" style="width:100%" rows="5" onClick="this.select();"><?php echo json_encode( wp_slimstat::$settings ) ?></textarea><br/>
317
  <input type="submit" value="<?php _e('Import','wp-slimstat') ?>" class="button-secondary"
318
  onclick="return(confirm('<?php _e('Are you sure you want to OVERWRITE your current settings?','wp-slimstat'); ?>'))">
319
  </form>
admin/update-checker/Puc/v4p2/Plugin/UpdateChecker.php CHANGED
@@ -537,10 +537,6 @@ if ( !class_exists('Puc_v4p2_Plugin_UpdateChecker', false) ):
537
  public function addResultFilter($callback) {
538
  $this->addFilter('request_info_result', $callback, 10, 2);
539
  }
540
-
541
- protected function createDebugBarExtension() {
542
- return new Puc_v4p2_DebugBar_PluginExtension($this);
543
- }
544
  }
545
 
546
  endif;
537
  public function addResultFilter($callback) {
538
  $this->addFilter('request_info_result', $callback, 10, 2);
539
  }
 
 
 
 
540
  }
541
 
542
  endif;
admin/update-checker/Puc/v4p2/Theme/UpdateChecker.php CHANGED
@@ -92,10 +92,6 @@ if ( !class_exists('Puc_v4p2_Theme_UpdateChecker', false) ):
92
  return $this->upgraderStatus->isThemeBeingUpgraded($this->stylesheet, $upgrader);
93
  }
94
 
95
- protected function createDebugBarExtension() {
96
- return new Puc_v4p2_DebugBar_Extension($this, 'Puc_v4p2_DebugBar_ThemePanel');
97
- }
98
-
99
  /**
100
  * Register a callback for filtering query arguments.
101
  *
92
  return $this->upgraderStatus->isThemeBeingUpgraded($this->stylesheet, $upgrader);
93
  }
94
 
 
 
 
 
95
  /**
96
  * Register a callback for filtering query arguments.
97
  *
admin/update-checker/Puc/v4p2/UpdateChecker.php CHANGED
@@ -123,13 +123,6 @@ if ( !class_exists('Puc_v4p2_UpdateChecker', false) ):
123
 
124
  //Allow HTTP requests to the metadata URL even if it's on a local host.
125
  add_filter('http_request_host_is_external', array($this, 'allowMetadataHost'), 10, 2);
126
-
127
- //DebugBar integration.
128
- if ( did_action('plugins_loaded') ) {
129
- $this->maybeInitDebugBar();
130
- } else {
131
- add_action('plugins_loaded', array($this, 'maybeInitDebugBar'));
132
- }
133
  }
134
 
135
  /**
@@ -794,34 +787,6 @@ if ( !class_exists('Puc_v4p2_UpdateChecker', false) ):
794
  * @return array Format: ['HeaderKey' => 'Header Name']
795
  */
796
  abstract protected function getHeaderNames();
797
-
798
- /* -------------------------------------------------------------------
799
- * DebugBar integration
800
- * -------------------------------------------------------------------
801
- */
802
-
803
- /**
804
- * Initialize the update checker Debug Bar plugin/add-on thingy.
805
- */
806
- public function maybeInitDebugBar() {
807
- if ( class_exists('Debug_Bar', false) && file_exists(dirname(__FILE__ . '/DebugBar')) ) {
808
- $this->createDebugBarExtension();
809
- }
810
- }
811
-
812
- protected function createDebugBarExtension() {
813
- return new Puc_v4p2_DebugBar_Extension($this);
814
- }
815
-
816
- /**
817
- * Display additional configuration details in the Debug Bar panel.
818
- *
819
- * @param Puc_v4p2_DebugBar_Panel $panel
820
- */
821
- public function onDisplayConfiguration($panel) {
822
- //Do nothing. Subclasses can use this to add additional info to the panel.
823
- }
824
-
825
  }
826
 
827
  endif;
123
 
124
  //Allow HTTP requests to the metadata URL even if it's on a local host.
125
  add_filter('http_request_host_is_external', array($this, 'allowMetadataHost'), 10, 2);
 
 
 
 
 
 
 
126
  }
127
 
128
  /**
787
  * @return array Format: ['HeaderKey' => 'Header Name']
788
  */
789
  abstract protected function getHeaderNames();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
790
  }
791
 
792
  endif;
admin/update-checker/Puc/v4p2/Vcs/PluginUpdateChecker.php CHANGED
@@ -188,13 +188,6 @@ if ( !class_exists('Puc_v4p2_Vcs_PluginUpdateChecker') ):
188
 
189
  return $update;
190
  }
191
-
192
- public function onDisplayConfiguration($panel) {
193
- parent::onDisplayConfiguration($panel);
194
- $panel->row('Branch', $this->branch);
195
- $panel->row('Authentication enabled', $this->api->isAuthenticationEnabled() ? 'Yes' : 'No');
196
- $panel->row('API client', get_class($this->api));
197
- }
198
  }
199
 
200
  endif;
188
 
189
  return $update;
190
  }
 
 
 
 
 
 
 
191
  }
192
 
193
  endif;
admin/update-checker/Puc/v4p2/Vcs/ThemeUpdateChecker.php CHANGED
@@ -89,13 +89,6 @@ if ( !class_exists('Puc_v4p2_Vcs_ThemeUpdateChecker', false) ):
89
 
90
  return $update;
91
  }
92
-
93
- public function onDisplayConfiguration($panel) {
94
- parent::onDisplayConfiguration($panel);
95
- $panel->row('Branch', $this->branch);
96
- $panel->row('Authentication enabled', $this->api->isAuthenticationEnabled() ? 'Yes' : 'No');
97
- $panel->row('API client', get_class($this->api));
98
- }
99
  }
100
 
101
  endif;
89
 
90
  return $update;
91
  }
 
 
 
 
 
 
 
92
  }
93
 
94
  endif;
admin/view/index.php CHANGED
@@ -120,7 +120,7 @@
120
  !empty(wp_slimstat_db::$filters_normalized['date']['interval']) ||
121
  !empty(wp_slimstat_db::$filters_normalized['date']['interval_hours']) ||
122
  !empty(wp_slimstat_db::$filters_normalized['date']['interval_minutes'])): ?>
123
- <a class="slimstat-filter-link button-secondary noslimstat" href="<?php echo wp_slimstat_reports::fs_url('minute equals 0&&&hour equals 0&&&day equals 0&&&month equals 0&&&year equals 0&&&interval_direction equals 1&&&interval equals 0&&&interval_hours equals 0&&&interval_minutes equals 0') ?>"><?php _e('Reset Filters','wp-slimstat') ?></a>
124
  <?php endif ?>
125
  </div>
126
  </fieldset><!-- .slimstat-date-filters -->
120
  !empty(wp_slimstat_db::$filters_normalized['date']['interval']) ||
121
  !empty(wp_slimstat_db::$filters_normalized['date']['interval_hours']) ||
122
  !empty(wp_slimstat_db::$filters_normalized['date']['interval_minutes'])): ?>
123
+ <a class="slimstat-filter-link button-secondary noslimstat" href="<?php echo wp_slimstat_reports::fs_url('minute equals 0&&&hour equals 0&&&day equals 0&&&month equals 0&&&year equals 0&&&interval_direction equals 1&&&interval equals 0&&&interval_hours equals 0&&&interval_minutes equals 0') ?>"><?php _e( 'Reset Filters', 'wp-slimstat' ) ?></a>
124
  <?php endif ?>
125
  </div>
126
  </fieldset><!-- .slimstat-date-filters -->
admin/view/wp-slimstat-db.php CHANGED
@@ -481,6 +481,26 @@ class wp_slimstat_db {
481
  }
482
  }
483
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
484
  // Temporarily disable any filters on date_i18n
485
  wp_slimstat::toggle_date_i18n_filters( false );
486
 
@@ -544,24 +564,6 @@ class wp_slimstat_db {
544
  ) - 1;
545
  $filters_normalized[ 'utime' ][ 'type' ] = 'm';
546
  }
547
- else if ( !empty( wp_slimstat::$settings[ 'use_current_month_timespan' ] ) && wp_slimstat::$settings[ 'use_current_month_timespan' ] == 'no' ) {
548
- $filters_normalized[ 'utime' ][ 'end' ] = mktime(
549
- date_i18n( 'H' ),
550
- date_i18n( 'i' ),
551
- date_i18n( 's' ),
552
- !empty( $filters_normalized[ 'date' ][ 'month' ] ) ? $filters_normalized[ 'date' ][ 'month' ] : date_i18n( 'n' ),
553
- !empty( $filters_normalized[ 'date' ][ 'month' ] ) ? $filters_normalized[ 'date' ][ 'day' ] : date_i18n( 'd' ),
554
- !empty( $filters_normalized[ 'date' ][ 'year' ] ) ? $filters_normalized[ 'date' ][ 'year' ] : date_i18n( 'Y' )
555
- );
556
-
557
- $filters_normalized[ 'utime' ][ 'start' ] = $filters_normalized[ 'utime' ][ 'end' ] - ( intval( wp_slimstat::$settings[ 'posts_column_day_interval' ] ) * 86400 );
558
- $filters_normalized[ 'utime' ][ 'type' ] = 'interval';
559
-
560
- if ( isset( $filters_normalized[ 'date' ][ 'interval' ] ) ) {
561
- $filters_normalized[ 'date' ][ 'interval' ] = $filters_normalized[ 'date' ][ 'interval' ];
562
- $filters_normalized[ 'date' ][ 'interval_direction' ] = 1;
563
- }
564
- }
565
  else {
566
  $filters_normalized[ 'utime' ][ 'start' ] = mktime(
567
  0,
@@ -573,10 +575,9 @@ class wp_slimstat_db {
573
  );
574
 
575
  $filters_normalized[ 'utime' ][ 'end' ] = strtotime(
576
- ( !empty( $filters_normalized[ 'date' ][ 'year' ] )?$filters_normalized[ 'date' ][ 'year' ]:date_i18n( 'Y' ) ).'-'.
577
- ( !empty( $filters_normalized[ 'date' ][ 'month' ] )?$filters_normalized[ 'date' ][ 'month' ]:date_i18n( 'n' ) ).
578
- '-01 00:00 +1 month UTC'
579
- )-1;
580
  $filters_normalized[ 'utime' ][ 'type' ] = 'm';
581
  }
582
  }
@@ -741,13 +742,13 @@ class wp_slimstat_db {
741
  }
742
 
743
  // Custom intervals don't have a comparison chart ('previous' range)
744
- if ( !empty( $previous[ 'start' ] ) ) {
745
- $_args[ 'where' ] = self::get_combined_where( $_args[ 'where' ], '*', false );
746
- $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' ].')';
747
  }
748
  else {
749
- $_args[ 'where' ] = self::get_combined_where( $_args[ 'where' ] );
750
- $previous_time_range = '';
751
  }
752
 
753
  // Build the SQL query
@@ -766,13 +767,13 @@ class wp_slimstat_db {
766
  $group_by_string, 'SUM(first_metric) AS first_metric, SUM(second_metric) AS second_metric' );
767
 
768
  // Fill the output array
769
- if ( !empty( $previous[ 'start' ] ) ) {
770
  $output[ 'current' ][ 'label' ] = gmdate( $label_date_format, self::$filters_normalized[ 'utime' ][ 'start' ] );
771
  $output[ 'previous' ][ 'label' ] = gmdate( $label_date_format, $previous[ 'start' ] );
772
- }
773
 
774
- $output[ 'previous' ][ 'first_metric' ] = array_fill( $values_in_interval[ 2 ], $values_in_interval[ 0 ], 0 );
775
- $output[ 'previous' ][ 'second_metric' ] = array_fill( $values_in_interval[ 2 ], $values_in_interval[ 0 ], 0 );
 
776
 
777
  $today_limit = floatval( date_i18n( 'Ymd.Hi' ) );
778
  for ( $i = $values_in_interval[ 2 ]; $i <= $values_in_interval[ 1 ]; $i++ ) {
481
  }
482
  }
483
 
484
+ // If the setting to use the last X days as default time span is enabled, we need to setup the "interval" variables
485
+ if ( ( empty( wp_slimstat::$settings[ 'use_current_month_timespan' ] ) || wp_slimstat::$settings[ 'use_current_month_timespan' ] != 'yes' ) ) {
486
+ // Do not set the interval if another date filter has already been set
487
+ $is_date_filter_empty = true;
488
+ if ( !empty( $filters_normalized[ 'date' ] ) ) {
489
+ $filters_to_check = array_diff( $filters_normalized[ 'date' ], array( 'interval_direction' => 1 ) );
490
+ foreach( $filters_to_check as $a_filter ) {
491
+ if ( !empty( $a_filter ) ) {
492
+ $is_date_filter_empty = false;
493
+ break;
494
+ }
495
+ }
496
+ }
497
+
498
+ if ( $is_date_filter_empty ) {
499
+ $filters_normalized[ 'date' ][ 'interval' ] = abs( wp_slimstat::$settings[ 'posts_column_day_interval' ] );
500
+ $filters_normalized[ 'date' ][ 'interval_direction' ] = 1;
501
+ }
502
+ }
503
+
504
  // Temporarily disable any filters on date_i18n
505
  wp_slimstat::toggle_date_i18n_filters( false );
506
 
564
  ) - 1;
565
  $filters_normalized[ 'utime' ][ 'type' ] = 'm';
566
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
567
  else {
568
  $filters_normalized[ 'utime' ][ 'start' ] = mktime(
569
  0,
575
  );
576
 
577
  $filters_normalized[ 'utime' ][ 'end' ] = strtotime(
578
+ ( !empty( $filters_normalized[ 'date' ][ 'year' ] ) ? $filters_normalized[ 'date' ][ 'year' ] : date_i18n( 'Y' ) ) . '-' .
579
+ ( !empty( $filters_normalized[ 'date' ][ 'month' ] ) ? $filters_normalized[ 'date' ][ 'month' ] : date_i18n( 'n' ) ) . '-01 00:00 +1 month UTC'
580
+ ) - 1;
 
581
  $filters_normalized[ 'utime' ][ 'type' ] = 'm';
582
  }
583
  }
742
  }
743
 
744
  // Custom intervals don't have a comparison chart ('previous' range)
745
+ if ( self::$filters_normalized[ 'utime' ][ 'type' ] == 'interval' ) {
746
+ $_args[ 'where' ] = self::get_combined_where( $_args[ 'where' ] );
747
+ $previous_time_range = '';
748
  }
749
  else {
750
+ $_args[ 'where' ] = self::get_combined_where( $_args[ 'where' ], '*', false );
751
+ $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' ].')';
752
  }
753
 
754
  // Build the SQL query
767
  $group_by_string, 'SUM(first_metric) AS first_metric, SUM(second_metric) AS second_metric' );
768
 
769
  // Fill the output array
770
+ if ( self::$filters_normalized[ 'utime' ][ 'type' ] != 'interval' ) {
771
  $output[ 'current' ][ 'label' ] = gmdate( $label_date_format, self::$filters_normalized[ 'utime' ][ 'start' ] );
772
  $output[ 'previous' ][ 'label' ] = gmdate( $label_date_format, $previous[ 'start' ] );
 
773
 
774
+ $output[ 'previous' ][ 'first_metric' ] = array_fill( $values_in_interval[ 2 ], $values_in_interval[ 0 ], 0 );
775
+ $output[ 'previous' ][ 'second_metric' ] = array_fill( $values_in_interval[ 2 ], $values_in_interval[ 0 ], 0 );
776
+ }
777
 
778
  $today_limit = floatval( date_i18n( 'Ymd.Hi' ) );
779
  for ( $i = $values_in_interval[ 2 ]; $i <= $values_in_interval[ 1 ]; $i++ ) {
admin/view/wp-slimstat-reports.php CHANGED
@@ -923,6 +923,10 @@ class wp_slimstat_reports {
923
  // end init
924
 
925
  public static function report_header( $_report_id = '' ) {
 
 
 
 
926
  $header_classes = !empty( self::$reports_info[ $_report_id ][ 'classes' ] ) ? implode( ' ', self::$reports_info[ $_report_id ][ 'classes' ] ) : '';
927
  $header_buttons = '';
928
  $header_tooltip = '';
@@ -1954,7 +1958,7 @@ class wp_slimstat_reports {
1954
  }
1955
 
1956
  if ( !empty( $filters_html ) ) {
1957
- $filters_html = "<ul class='slimstat-filter-list'>$filters_html</ul><a href='#' id='slimstat-save-filter' class='slimstat-filter-action-button button-secondary noslimstat' data-filter-array='" . htmlentities( serialize( $_filters_array ), ENT_QUOTES, 'UTF-8' ) . "'>" . __( 'Save', 'wp-slimstat' ) . '</a>';
1958
  }
1959
 
1960
  if ( count( $_filters_array ) > 1 ) {
923
  // end init
924
 
925
  public static function report_header( $_report_id = '' ) {
926
+ if ( empty( self::$reports_info[ $_report_id ] ) ) {
927
+ return false;
928
+ }
929
+
930
  $header_classes = !empty( self::$reports_info[ $_report_id ][ 'classes' ] ) ? implode( ' ', self::$reports_info[ $_report_id ][ 'classes' ] ) : '';
931
  $header_buttons = '';
932
  $header_tooltip = '';
1958
  }
1959
 
1960
  if ( !empty( $filters_html ) ) {
1961
+ $filters_html = "<ul class='slimstat-filter-list'>$filters_html</ul><a href='#' id='slimstat-save-filter' class='slimstat-filter-action-button button-secondary noslimstat' data-filter-array='" . htmlentities( json_encode( $_filters_array ), ENT_QUOTES, 'UTF-8' ) . "'>" . __( 'Save', 'wp-slimstat' ) . '</a>';
1962
  }
1963
 
1964
  if ( count( $_filters_array ) > 1 ) {
admin/wp-slimstat-admin.php CHANGED
@@ -1084,7 +1084,7 @@ class wp_slimstat_admin {
1084
 
1085
  switch( $_POST[ 'type' ] ) {
1086
  case 'save':
1087
- $new_filter = unserialize( stripslashes_deep( $_POST[ 'filter_array' ] ) );
1088
 
1089
  // Check if this filter is already saved
1090
  foreach ( $saved_filters as $a_saved_filter ) {
@@ -1113,8 +1113,8 @@ class wp_slimstat_admin {
1113
  break;
1114
 
1115
  case 'delete':
1116
- unset($saved_filters[intval($_POST['filter_id'])]);
1117
- update_option('slimstat_filters', $saved_filters);
1118
 
1119
  // No break here - We want to return the new list of filters!
1120
 
1084
 
1085
  switch( $_POST[ 'type' ] ) {
1086
  case 'save':
1087
+ $new_filter = json_decode( stripslashes_deep( $_POST[ 'filter_array' ] ), true );
1088
 
1089
  // Check if this filter is already saved
1090
  foreach ( $saved_filters as $a_saved_filter ) {
1113
  break;
1114
 
1115
  case 'delete':
1116
+ unset( $saved_filters[ intval( $_POST[ 'filter_id' ] ) ] );
1117
+ update_option( 'slimstat_filters', $saved_filters );
1118
 
1119
  // No break here - We want to return the new list of filters!
1120
 
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: analytics, statistics, counter, tracking, reports, wassup, geolocation, on
5
  Text Domain: wp-slimstat
6
  Requires at least: 3.8
7
  Tested up to: 4.8.2
8
- Stable tag: 4.7
9
 
10
  == Description ==
11
  The leading web analytics plugin for WordPress. Track returning customers and registered users, monitor Javascript events, detect intrusions, analyze email campaigns. Thousands of WordPress sites are already using it.
@@ -71,6 +71,11 @@ Our knowledge base is available on our [support center](http://docs.wp-slimstat.
71
  5. **Responsive layout** - Keep an eye on your reports on the go
72
 
73
  == Changelog ==
 
 
 
 
 
74
  = 4.7 =
75
  * [New] After receiving a few requests to implement a REST API within Slimstat, and given that WordPress now offers a mature and stable interface for extending its built-in REST API, we decided to finally move forward and implement this feature. Please refer to our [online knowledge base](https://slimstat.freshdesk.com/solution/articles/12000033661-slimstat-rest-api) to learn more about how to use it.
76
  * [Update] The [Add-on Update Checker library](https://github.com/YahnisElsts/plugin-update-checker) has been updated to version 4.2, to solve an incompatibility issue with PHP 7.0 (thank you, [Sasa](https://wordpress.org/support/topic/possible-incompatibility-with-php-7-0/) and Per).
5
  Text Domain: wp-slimstat
6
  Requires at least: 3.8
7
  Tested up to: 4.8.2
8
+ Stable tag: 4.7.1
9
 
10
  == Description ==
11
  The leading web analytics plugin for WordPress. Track returning customers and registered users, monitor Javascript events, detect intrusions, analyze email campaigns. Thousands of WordPress sites are already using it.
71
  5. **Responsive layout** - Keep an eye on your reports on the go
72
 
73
  == Changelog ==
74
+ = 4.7.1 =
75
+ * [Fix] The new feature introduced in version 4.6.9.1 to allow our users to customize the default time range for the reports, had introduced a regression bug. Thank you to all our users who volunteered to test the bugfix.
76
+ * [Fix] A vulnerability has been disclosed by [Pluginvulnerabilities.com](pluginvulnerabilities.com): an attacker with admin credentials could leverage the import/export mechanism for the plugin's settings to inject some malicious code. We recommend that you upgrade to the latest version of Slimstat as soon as possible.
77
+ * [Fix] The new version of the [Add-on Update Checker library](https://github.com/YahnisElsts/plugin-update-checker), bundled with the previous release, was returning a fatal error under certain circumstances (thank you, Pepe).
78
+
79
  = 4.7 =
80
  * [New] After receiving a few requests to implement a REST API within Slimstat, and given that WordPress now offers a mature and stable interface for extending its built-in REST API, we decided to finally move forward and implement this feature. Please refer to our [online knowledge base](https://slimstat.freshdesk.com/solution/articles/12000033661-slimstat-rest-api) to learn more about how to use it.
81
  * [Update] The [Add-on Update Checker library](https://github.com/YahnisElsts/plugin-update-checker) has been updated to version 4.2, to solve an incompatibility issue with PHP 7.0 (thank you, [Sasa](https://wordpress.org/support/topic/possible-incompatibility-with-php-7-0/) and Per).
wp-slimstat.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Slimstat Analytics
4
  Plugin URI: http://wordpress.org/plugins/wp-slimstat/
5
  Description: The leading web analytics plugin for WordPress
6
- Version: 4.7
7
  Author: Jason Crouse
8
  Author URI: http://www.wp-slimstat.com/
9
  Text Domain: wp-slimstat
@@ -15,9 +15,8 @@ if ( !empty( wp_slimstat::$settings ) ) {
15
  }
16
 
17
  class wp_slimstat {
18
- public static $version = '4.7';
19
  public static $settings = array();
20
- public static $options = array(); // To be removed, here just for backward compatibility
21
 
22
  public static $wpdb = '';
23
  public static $upload_dir = '';
@@ -52,9 +51,6 @@ class wp_slimstat {
52
  // Allow third party tools to edit the options
53
  self::$settings = apply_filters( 'slimstat_init_options', self::$settings );
54
 
55
- // To be removed - Backward compatibility
56
- self::$options = self::$settings;
57
-
58
  // Determine the options' signature: if it hasn't changed, there's no need to update/save them in the database
59
  self::$settings_signature = md5( serialize( self::$settings ) );
60
 
@@ -1293,6 +1289,10 @@ class wp_slimstat {
1293
  break;
1294
 
1295
  case 'widget':
 
 
 
 
1296
  wp_register_style( 'wp-slimstat-frontend', plugins_url( '/admin/css/slimstat.frontend.css', __FILE__ ) );
1297
  wp_enqueue_style( 'wp-slimstat-frontend' );
1298
 
3
  Plugin Name: Slimstat Analytics
4
  Plugin URI: http://wordpress.org/plugins/wp-slimstat/
5
  Description: The leading web analytics plugin for WordPress
6
+ Version: 4.7.1
7
  Author: Jason Crouse
8
  Author URI: http://www.wp-slimstat.com/
9
  Text Domain: wp-slimstat
15
  }
16
 
17
  class wp_slimstat {
18
+ public static $version = '4.7.1';
19
  public static $settings = array();
 
20
 
21
  public static $wpdb = '';
22
  public static $upload_dir = '';
51
  // Allow third party tools to edit the options
52
  self::$settings = apply_filters( 'slimstat_init_options', self::$settings );
53
 
 
 
 
54
  // Determine the options' signature: if it hasn't changed, there's no need to update/save them in the database
55
  self::$settings_signature = md5( serialize( self::$settings ) );
56
 
1289
  break;
1290
 
1291
  case 'widget':
1292
+ if ( empty( wp_slimstat_reports::$reports_info[ $w ] ) ) {
1293
+ return __( 'Undefined report ID', 'wp-slimstat' );
1294
+ }
1295
+
1296
  wp_register_style( 'wp-slimstat-frontend', plugins_url( '/admin/css/slimstat.frontend.css', __FILE__ ) );
1297
  wp_enqueue_style( 'wp-slimstat-frontend' );
1298