Slimstat Analytics - Version 4.8.7.3

Version Description

  • [New] Implemented a simple query cache to minimize the number of requests needed to crunch and display the data in the reports.
  • [Update] Extended tracker to also record the 'fragment' portion of the URL, if available (this feature is only available in Client Mode).
  • [Update] Do not show the resource title in Network View mode.
  • [Fix] Some reports were not optimized for our Network Analytics add-on (thank you, Peter).
  • [Fix] The notice displayed to share the latest news with our users would not disappear even after clicking the X button to close it (thank you, Anton).
  • [Fix] The 'Top Web Pages' reports was listing duplicate entries.
  • [Fix] A regression bug was affecting the Currently Online report, by showing incorrect information for the IP addresses.
  • [Fix] After resetting the Customizer view, all reports were being listed twice (thank you, Anton).
  • [Fix] A new feature introduced by our Javascript tracker was not working as expected in IE11 (thank you, 51nullacht).
Download this release

Release Info

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

Code changes from version 4.8.7.2 to 4.8.7.3

CHANGELOG.md CHANGED
@@ -1,4 +1,15 @@
1
  ## Changelog ##
 
 
 
 
 
 
 
 
 
 
 
2
  ### 4.8.7.2 ###
3
  * [Fix] The new tracker was having problems recording clicks on SVG elements within a link (thank you, [pollensteyn](https://wordpress.org/support/topic/javascript-error-typeerror/#post-11926542)).
4
  * [Fix] The event handler is now capable of tracking events on BUTTONs within FORM elements.
@@ -22,3 +33,108 @@
22
  * [Fix] A bug was affecting certain shortcodes when PHP 7.2 was enabled (thank you, Peter).
23
  * [Fix] Emptying one of the settings and saving did not produce the desired effect.
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ## Changelog ##
2
+ ### 4.8.7.3 ###
3
+ * [New] Implemented a simple query cache to minimize the number of requests needed to crunch and display the data in the reports.
4
+ * [Update] Extended tracker to also record the 'fragment' portion of the URL, if available (this feature is only available in Client Mode).
5
+ * [Update] Do not show the resource title in Network View mode.
6
+ * [Fix] Some reports were not optimized for our Network Analytics add-on (thank you, Peter).
7
+ * [Fix] The notice displayed to share the latest news with our users would not disappear even after clicking the X button to close it (thank you, Anton).
8
+ * [Fix] The 'Top Web Pages' reports was listing duplicate entries.
9
+ * [Fix] A regression bug was affecting the Currently Online report, by showing incorrect information for the IP addresses.
10
+ * [Fix] After resetting the Customizer view, all reports were being listed twice (thank you, Anton).
11
+ * [Fix] A new feature introduced by our Javascript tracker was not working as expected in IE11 (thank you, [51nullacht](https://wordpress.org/support/topic/js-error-in-wp-slimstat-js321/)).
12
+
13
  ### 4.8.7.2 ###
14
  * [Fix] The new tracker was having problems recording clicks on SVG elements within a link (thank you, [pollensteyn](https://wordpress.org/support/topic/javascript-error-typeerror/#post-11926542)).
15
  * [Fix] The event handler is now capable of tracking events on BUTTONs within FORM elements.
33
  * [Fix] A bug was affecting certain shortcodes when PHP 7.2 was enabled (thank you, Peter).
34
  * [Fix] Emptying one of the settings and saving did not produce the desired effect.
35
 
36
+ ### 4.8.6.2 ###
37
+ * [Update] We tweaked the SQL query to retrieve 'recent' results, and added a GROUP BY clause to remove duplicates. This might affect some custom reports you might have created, so please don't hesitate to contact us if you have any question or experience any issues.
38
+ * [Fix] The button to delete all the records from the database was not working as expected (thank you, [Softfully](https://wordpress.org/support/topic/delete-all-records-doesnt-work/)).
39
+
40
+ ### 4.8.6.1 ###
41
+ * [Fix] A regression bug was introduced in 4.8.6, affecting some of the shortcodes and reports.
42
+
43
+ ### 4.8.6 ###
44
+ * [New] Slimstat can now track most WordPress redirects and mark them with the appropriate content type.
45
+ * [Update] The GDPR compliance through third-party tools is now more flexible and allows admins to specify name/value pairs so that the cookie must CONTAIN the given string.
46
+ * [Update] Simplified code that manages the sidebar menu.
47
+ * [Update] Reorganized code that manages the plugin options.
48
+ * [Update] Rewrote the portion of code that manages tracker errors, which are now saved in a separate field in the database.
49
+ * [Update] Reintroduced feature to hide certain report pages when no reports are assigned to them.
50
+ * [Update] Decrease the number of database requests needed to record a new pageview.
51
+ * [Fix] Entries with a trailing slash and ones without were being listed as separate in Top Web Pages.
52
+ * [Fix] Typo in one of the conditions definining the Top Bots report.
53
+
54
+ ### 4.8.5.1 ###
55
+ * [Fix] A bug was affecting the way shortcodes were being displayed on the website (thank you, [inndesign](https://wordpress.org/support/topic/crashes-avada-theme-in-chrome/)).
56
+ * [Fix] Some icons in the Access Log were broken and not displayed as expected.
57
+ * [Fix] Added extra code to make sure a callback function is defined for any given report.
58
+ * [Fix] Top reports where displaying an incorrect percentage value on the WordPress dashboard (thank you, [scruffy1 and a305587](https://wordpress.org/support/topic/dashboard-widgets-showing-0)).
59
+
60
+ ### 4.8.5 ###
61
+ * [New] Introduced option to not track pageviews based on the ACCEPT-LANGUAGE header sent by the browser.
62
+ * [New] Introduced option to display a pageview count instead of the percentage in Top reports.
63
+ * [New] Introduced two new reports under the Audience tab: Tob Bots and Top Human Browsers.
64
+ * [Update] Removed the option to hide reports on tabs, as it was confusing users who couldn't find them. Now you can simply use the Customizer to arrange your reports, and place the ones you don't need in the Inactive box.
65
+ * [Update] Rewritten the code that manages which reports are displayed on which screen (Customizer), streamlined data structures and optimized their use. Please update all the add-ons to the latest version available. Don't hesitate to contact us if you have any questions!
66
+ * [Fix] The HTML markup in the opt-out message field was being stripped out (thank you, [paulmcmanus](https://wordpress.org/support/topic/saving-settings-flips-opt-out-message-to-plain-text/)).
67
+ * [Fix] Reports could not be properly deleted in the Customizer, if the Slimstat menu was displayed in the Admin Bar.
68
+ * [Fix] A fatal error thrown by the Maxmind library when the data file is corrupted has been addressed.
69
+ * [Fix] The icon filename for Windows 8.1 was incorrect (thank you, Dimitri).
70
+
71
+ ### 4.8.4.1 ###
72
+ * [Note] As anticipated a few weeks ago, this update drops the information about your visitors' browser plugins, which had been deprecated as not useful and oftentimes unreliable. Please make sure to backup your Slimstat tables if you need to preserve this information for some reason.
73
+ * [Update] We received quite a few messages complaining about our decision to change the default position of the Slimstat menu from the sidebar to the admin bar. We are rolling back this change, and we apologize for any confusion this might have caused.
74
+ * [Update] Added visitor's language to the Activity Log report.
75
+ * [Update] Introduced code optimizations to improve performance when localizing strings related to operating systems, languages, countries, etc.
76
+ * [Fix] Page URLs were not being displayed correctly if the option to display page titles was turned off.
77
+ * [Fix] Not storing empty values in the database: leave as NULL. This will squeeze a few more bytes out of each row stored in the database.
78
+
79
+ ### 4.8.4 ###
80
+ * [Note] If you're using any of our premium add-ons, please make sure to update them to the latest version available (see Slimstat > Add-ons) as we've updated some references in our code.
81
+ * [Note] We recently received an email from one of our users suggesting that we replace the line charts currently used to display reports over a timeline with **bar charts**, because 'the number of pageviews and IPs are discrete numbers, hence they should also be presented as discrete numbers', according to him. What do you think? Please let us know by [sending us a message](https://support.wp-slimstat.com/) on our support platform. Thank you.
82
+ * [Update] Renamed a few files in the admin. If you're including Slimstat libraries in your custom code, please make sure to check that your references are up-to-date. Also, make sure to clear your cache if you page layout doesn't look right.
83
+ * [Update] [AmCharts](https://www.amcharts.com/javascript-charts/), the library used to render all of our charts, has been updated to version 4.5.3.
84
+ * [Update] When functioning in Client mode, the tracker will now not ignore bots, spiders and the like automatically. Please use the appropriate option under Settings > Exclusions if you would like to ignore bots. This solves an incompatibility issue with some caching plugins which "prefetch" the website, presenting themselves as bots.
85
+ * [Update] Removed tracker notice field under Settings > Maintenance as it was confusing many people and generating extra work for our customer service team.
86
+ * [Update] Removed option to not track "client properties" like screen resolution, etc. Also, removed option to not honor DNT headers, as we received complaints from privacy activists on this matter.
87
+ * [Update] Removed option to change date/time formats and numeric separators: Slimstat will now use the WordPress settings to adjust its behavior.
88
+ * [Update] Removed 'About Slimstat' report, given that some of the information in it has been moved to the Settings.
89
+ * [Update] Removed unused strings, improved contextual descriptions and applied consistent naming conventions across our codebase (first pass).
90
+ * [Update] The Slimstat admin menu is now added to the Admin Bar by default. Please go to Settings > Basic > WordPress Integration and change the corresponding option, if you prefer to use the side menu instead.
91
+ * [Update] Enabled code editor in Settings.
92
+ * [Update] Implemented a new optimized function to retrieve the post count on the Edit Posts/Pages/CPTs screens. Thank you, Lance.
93
+ * [Update] Improved browser detection feature, which will now fallback to the heuristic function if the Browscap data file doesn't contain an exact match for a given browser. This usually happens whenever a new browser version is released, which is not yet included in the data file.
94
+ * [Update] Option to track same-domain referrers is now deactivated by default on new installations.
95
+ * [Update] Enabled wildcards on the exclusion rule by capability.
96
+ * [Update] Improved the overall source code readability score. Now you don't have any other excuses to not contribute to this project!
97
+ * [Update] Table indexes are now enabled by default in the database.
98
+ * [Update] Added new WordPress filter to the Browscap Library, so that third-party tools can manipulate the data before it's returned to the tracker.
99
+ * [Update] Added [nonce](https://wordpress.org/support/article/glossary/#nonce) to Settings page for improved security.
100
+
101
+ ### 4.8.3 ###
102
+ * [Note] Thank you for all the great feedback you provided to our unofficial survey about retiring the 'browser plugins' feature. The vast majority of those who replied confirmed what we already thought. Please consider backing up your database if you would like to preserve this information for future analysis. With this update, we removed the portion of code that tracks that information, but kept the existing data untouched. In a couple of releases, code will be added to actually drop this column from the database.
103
+ * [New] If English is not your primary languge, Slimstat will now display a notice asking for your help to [translate our plugin](https://translate.wordpress.org/projects/wp-plugins/wp-slimstat/) in your language. Please consider volunteering for this great opportunity to help our community!
104
+ * [Update] We are working with the GlotPress community to improve the way Slimstat speaks your language. We had to change the way certain strings are defined in our source code. Please let us know if you notice any unexpected behavior when analyzing languages, countries and operating systems.
105
+ * [Update] Removed Facebook rankings metrics, as the API has been deprecated and the new one is not accessible without a private token.
106
+ * [Update] MozRank has been deprecated, we have replaced it with the Domain Authority metric.
107
+ * [Update] Spring cleaning in the 'admin notices' department: removed some obsolete CSS code, replaced by built-in WP classes and definitions.
108
+ * [Fix] Changed the default minimum capability to access the reports from 'activate_plugins' to 'manage_options', so that regular administrators (a.k.a. non-super admins) in a multisite environment can still see their own reports (thank you, [homepageware](https://wordpress.org/support/topic/slimstat-and-multisite/)). This update does not affect existing installations: if you want regular admins to see their own stats, please go to Slimstat > Settings > Access Control and change the values in the corresponding fields.
109
+ * [Fix] The autorefresh feature for the Access Log was not working as expected. Thank you to all the users who patiently worked with us to identify the issue.
110
+ * [Fix] A conflict between the Async loader and AmCharts 4 was causing the Screen Options tab to not work as expected (thank you, [softfully](https://wordpress.org/support/topic/screen-options-doesnt-open/)).
111
+ * [Fix] Removed unused setting 'Expand Reports'
112
+
113
+ ### 4.8.2 ###
114
+ * [Note] Our team has been contemplating the idea of deprecating the information collected about your visitors' *browser plugins* (Java, PDF reader, RealView player, Silverlight, etc). In this day and age, where browsers use either built-in functionality to provide those features, or extensions that cannot be tracked for privacy purposes, it feels anachronistic to continue collecting this outdated information. By getting rid of this specific feature, we can streamline our code, improve performance, and reduce the database size. However, we wanted to hear from our users before anything is actually implemented. Please do not hesitate [to let us know](https://support.wp-slimstat.com) if you are using the 'browser plugins' field for your reporting needs.
115
+ * [New] Many CRM integration plugins rely mostly on the user emails, not usernames. For this reason, a new email field has been added to the database (thank you, [sandrodz](https://github.com/sandrodz)).
116
+ * [Update] Changed the preset intervals in the date filter dropdown so that you can get a day over day comparison (Monday over Monday, etc) for improved accuracy.
117
+ * [Update] [AmCharts](https://www.amcharts.com/javascript-charts/), the library used to render all of our charts, has been updated to version 4.4.9.
118
+ * [Fix] The countdown timer on the Access Log was not working as expected (thank you, [anniest](https://wordpress.org/support/topic/no-refresh-2/)).
119
+ * [Fix] The countdown timer was causing an warning message to appear on other screens.
120
+ * [Fix] Minor aesthetic improvements.
121
+
122
+ ### 4.8.1 ###
123
+ * [Update] Async mode will now serialize concurrent requests to the backend to optimize performance and reduce server load.
124
+ * [Fix] Addressed a remote XSS vulnerability disclosed by Sucuri/GoDaddy.
125
+ * [Fix] Charts were displaying the wrong label for certain values (thank you, Alex).
126
+
127
+ ### 4.8 ###
128
+ * [Note] Now that we have a cleaner foundation to build on, it's time to start introducing new reports and new ways to segment your audience and the traffic they generate. While our users test the latest changes and updates (to confirm that the foundation is indeed solid and bug-free), we are hard at work implementing the first batch of new reports. Some of them will be made available in the free version, while others will be added to our premium add-on, [User Overview](https://www.wp-slimstat.com/downloads/user-overview/). And we need your help! If you think that a specific report should be added to Slimstat, please do not hesitate to let us know!
129
+ * [Note] Worried about the recent [news regarding jQuery vulnerabilities](https://www.zdnet.com/article/popular-jquery-javascript-library-impacted-by-prototype-pollution-flaw/)? Slimstat doesn't use jQuery as a dependency, so you can sleep tight knowing that your website will not be affected.
130
+ * [Update] [AmCharts](https://www.amcharts.com/javascript-charts/), the library used to render all of our charts, has been updated to version 4. This new release is not backward compatible, so the code to integrate it with Slimstat had to be completely rewritten. Please let us know if you notice any issues.
131
+ * [Update] [Plugin Update Checker](https://github.com/YahnisElsts/plugin-update-checker), the library we use to check if a new version of our premium add-ons is available for download, has been update to version 4.6.
132
+ * [Update] If you're using our partner's CDN functionality (JsDelivr) to load the tracker, their link is now always loaded over HTTPS for added security.
133
+ * [Update] Switched the Add-on Update checker URL to HTTPS, for added security (thank you, Peter).
134
+ * [Update] Changed the protocol of all the URLs used within Slimstat, including references to our documentation, to HTTPS.
135
+ * [Update] Added icon to geolocate Originating IP addresses, when detected.
136
+ * [Fix] The optout cookie path was not being set correctly (thank you, [ralfkerkhoff](https://wordpress.org/support/topic/opt-out-cookie-per-page/)).
137
+ * [Fix] Google seems to be using a new User Agent string for its "mobile" crawler, which was causing Slimstat from incorrectly identifying visits as coming from mobile devices, instead of bots (thank you, Ron).
138
+ * [Fix] An error was being returned if SVG elements were using the A tag on a page (thank you, [snaphappyme](https://wordpress.org/support/topic/uncaught-typeerror-all_linksn-href-indexof/)).
139
+ * [Fix] A bug was causing Slimstat to incorrectly geolocate visits to websites behind a Cloudflare load balancer. Please update the IP Address Fix add-on as well.
140
+ * [Fix] Tweaked the formula to determine your website bounce rate, and updated the associated description to better reflect the underlying calculations.
admin/config/index.php CHANGED
@@ -544,10 +544,16 @@ var SlimStatParams = { ajaxurl: "' . admin_url( 'admin-ajax.php' ) . '" };
544
  'type'=> 'section_header'
545
  ),
546
  'delete_all_records' => array(
547
- 'title' => __( 'Data Reset', 'wp-slimstat' ),
548
  'type'=> 'plain-text',
549
- 'after_input_field' => '<a class="button-primary" href="' . wp_slimstat_admin::$config_url . $current_tab . '&amp;action=truncate-table&amp;slimstat_update_settings=' . wp_create_nonce( 'slimstat_update_settings' ) . '" onclick="return( confirm( \'' . __( 'Please confirm that you want to PERMANENTLY DELETE ALL the records from your database.' ,'wp-slimstat' ) . '\' ) )">' . __( 'Delete All Records', 'wp-slimstat' ) . '</a>',
550
  'description'=> __( 'Delete all the information collected by Slimstat so far, but not the archived records (stored in <code>wp_slim_stats_archive</code>). This operation <strong>does not</strong> reset your settings and it can be undone by manually copying your records from the archive table, if you have the corresponding option enabled.' ,'wp-slimstat' )
 
 
 
 
 
 
551
  )
552
  )
553
  ),
@@ -574,6 +580,31 @@ $settings = apply_filters( 'slimstat_options_on_page', $settings );
574
  // Save options
575
  $save_messages = array();
576
  if ( !empty( $settings ) && !empty( $_REQUEST[ 'slimstat_update_settings' ] ) && wp_verify_nonce( $_REQUEST[ 'slimstat_update_settings' ], 'slimstat_update_settings' ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
577
  // Some of them require extra processing
578
  if ( !empty( $_POST[ 'options' ] ) ) {
579
  // DB Indexes
@@ -684,12 +715,8 @@ if ( !empty( $settings ) && !empty( $_REQUEST[ 'slimstat_update_settings' ] ) &&
684
  // Allow third-party functions to manipulate the options right before they are saved
685
  wp_slimstat::$settings = apply_filters( 'slimstat_save_options', wp_slimstat::$settings );
686
 
687
- if ( !is_network_admin() ) {
688
- update_option( 'slimstat_options', wp_slimstat::$settings );
689
- }
690
- else {
691
- update_site_option( 'slimstat_options', wp_slimstat::$settings );
692
- }
693
 
694
  if ( !empty( $save_messages ) ) {
695
  wp_slimstat_admin::show_message( implode( ' ', $save_messages ), 'warning' );
@@ -698,31 +725,6 @@ if ( !empty( $settings ) && !empty( $_REQUEST[ 'slimstat_update_settings' ] ) &&
698
  wp_slimstat_admin::show_message( __( 'Your new settings have been saved.', 'wp-slimstat' ), 'info' );
699
  }
700
  }
701
-
702
- if ( !empty( $_GET[ 'action' ] ) ) {
703
- switch ( $_GET[ 'action' ] ) {
704
- case 'reset-tracker-error':
705
- $settings[ 6 ][ 'rows' ][ 'last_tracker_error' ][ 'after_input_field' ] = __( 'So far so good.', 'wp-slimstat' );
706
- if ( !is_network_admin() ) {
707
- update_option( 'slimstat_tracker_error', array() );
708
- }
709
- else {
710
- update_site_option( 'slimstat_tracker_error', array() );
711
- }
712
- break;
713
-
714
- case 'truncate-table':
715
- wp_slimstat::$wpdb->query( "DELETE te FROM {$GLOBALS[ 'wpdb' ]->prefix}slim_events te" );
716
- wp_slimstat::$wpdb->query( "OPTIMIZE TABLE {$GLOBALS[ 'wpdb' ]->prefix}slim_events" );
717
- wp_slimstat::$wpdb->query( "DELETE t1 FROM {$GLOBALS[ 'wpdb' ]->prefix}slim_stats t1" );
718
- wp_slimstat::$wpdb->query( "OPTIMIZE TABLE {$GLOBALS[ 'wpdb' ]->prefix}slim_stats" );
719
- wp_slimstat_admin::show_message( __( 'All the records were successfully deleted.', 'wp-slimstat' ) );
720
- break;
721
-
722
- default:
723
- break;
724
- }
725
- }
726
  }
727
 
728
  $maxmind_last_modified = '';
544
  'type'=> 'section_header'
545
  ),
546
  'delete_all_records' => array(
547
+ 'title' => __( 'Data', 'wp-slimstat' ),
548
  'type'=> 'plain-text',
549
+ 'after_input_field' => '<a class="button-primary" href="' . wp_slimstat_admin::$config_url . $current_tab . '&amp;action=truncate-table&amp;slimstat_update_settings=' . wp_create_nonce( 'slimstat_update_settings' ) . '" onclick="return( confirm( \'' . __( 'Please confirm that you want to PERMANENTLY DELETE ALL the records from your database.' ,'wp-slimstat' ) . '\' ) )">' . __( 'Delete Records', 'wp-slimstat' ) . '</a>',
550
  'description'=> __( 'Delete all the information collected by Slimstat so far, but not the archived records (stored in <code>wp_slim_stats_archive</code>). This operation <strong>does not</strong> reset your settings and it can be undone by manually copying your records from the archive table, if you have the corresponding option enabled.' ,'wp-slimstat' )
551
+ ),
552
+ 'reset_all_settings' => array(
553
+ 'title' => __( 'Settings', 'wp-slimstat' ),
554
+ 'type'=> 'plain-text',
555
+ 'after_input_field' => '<a class="button-primary" href="' . wp_slimstat_admin::$config_url . $current_tab . '&amp;action=reset-settings&amp;slimstat_update_settings=' . wp_create_nonce( 'slimstat_update_settings' ) . '" onclick="return( confirm( \'' . __( 'Please confirm that you want to RESET your settings.' ,'wp-slimstat' ) . '\' ) )">' . __( 'Factory Reset', 'wp-slimstat' ) . '</a>',
556
+ 'description'=> __( 'Restore all the settings to their default value. This action DOES NOT delete any records collected by the plugin.' ,'wp-slimstat' )
557
  )
558
  )
559
  ),
580
  // Save options
581
  $save_messages = array();
582
  if ( !empty( $settings ) && !empty( $_REQUEST[ 'slimstat_update_settings' ] ) && wp_verify_nonce( $_REQUEST[ 'slimstat_update_settings' ], 'slimstat_update_settings' ) ) {
583
+ if ( !empty( $_GET[ 'action' ] ) ) {
584
+ switch ( $_GET[ 'action' ] ) {
585
+ case 'reset-tracker-error':
586
+ $settings[ 6 ][ 'rows' ][ 'last_tracker_error' ][ 'after_input_field' ] = __( 'So far so good.', 'wp-slimstat' );
587
+ wp_slimstat::update_option( 'slimstat_tracker_error', array() );
588
+ break;
589
+
590
+ case 'reset-settings':
591
+ wp_slimstat::update_option( 'slimstat_options', wp_slimstat::$settings );
592
+ wp_slimstat_admin::show_message( __( 'All settings were successfully reset to their default values.', 'wp-slimstat' ) );
593
+ break;
594
+
595
+ case 'truncate-table':
596
+ wp_slimstat::$wpdb->query( "DELETE te FROM {$GLOBALS[ 'wpdb' ]->prefix}slim_events te" );
597
+ wp_slimstat::$wpdb->query( "OPTIMIZE TABLE {$GLOBALS[ 'wpdb' ]->prefix}slim_events" );
598
+ wp_slimstat::$wpdb->query( "DELETE t1 FROM {$GLOBALS[ 'wpdb' ]->prefix}slim_stats t1" );
599
+ wp_slimstat::$wpdb->query( "OPTIMIZE TABLE {$GLOBALS[ 'wpdb' ]->prefix}slim_stats" );
600
+ wp_slimstat_admin::show_message( __( 'All your records were successfully deleted.', 'wp-slimstat' ) );
601
+ break;
602
+
603
+ default:
604
+ break;
605
+ }
606
+ }
607
+
608
  // Some of them require extra processing
609
  if ( !empty( $_POST[ 'options' ] ) ) {
610
  // DB Indexes
715
  // Allow third-party functions to manipulate the options right before they are saved
716
  wp_slimstat::$settings = apply_filters( 'slimstat_save_options', wp_slimstat::$settings );
717
 
718
+ // Save the new values in the database
719
+ wp_slimstat::update_option( 'slimstat_options', wp_slimstat::$settings );
 
 
 
 
720
 
721
  if ( !empty( $save_messages ) ) {
722
  wp_slimstat_admin::show_message( implode( ' ', $save_messages ), 'warning' );
725
  wp_slimstat_admin::show_message( __( 'Your new settings have been saved.', 'wp-slimstat' ), 'info' );
726
  }
727
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
728
  }
729
 
730
  $maxmind_last_modified = '';
admin/index.php CHANGED
@@ -18,7 +18,8 @@ class wp_slimstat_admin {
18
  * Init -- Sets things up.
19
  */
20
  public static function init() {
21
- self::$admin_notice = "We are deprecating the two columns <em>type</em> and <em>event_description</em> in the events table, and consolidating that information in the <em>notes</em> field. Code will be added to Slimstat in a few released to actually drop these columns from the database. If you are using those two columns in your custom code, please feel free to contact our support team to discuss your options and how to update your code using the information collected by the new tracker.";
 
22
  // self::$admin_notice = "In this day and age where every single social media platform knows our individual whereabouts on the Interwebs, we have been doing some research on what <em>the techies</em> out there call <a href='https://amiunique.org/fp' target='_blank'>browser fingerprinting</a>. With this technique, it is not necessary to install any cookies to identify a specific user. This means that the act of fingerprinting a specific browser is stateless and transparent, and thus much more accurate. We are already wearing our lab coats and are hard at work to leverage <a href='https://github.com/Valve/fingerprintjs2' target='_blank'>tools like Fingerprint2</a> in Slimstat. This library, among other things, will allow our tracker to record your users' timezone: wouldn't it be nice to know what time it was for the user who was visiting your website? Of course, if you have Privacy Mode enabled, this feature will not be used, in compliance with GDPR and other international privacy laws. Stay tuned!";
23
 
24
  // Load language files
@@ -874,6 +875,9 @@ class wp_slimstat_admin {
874
  if ( !empty( $tag ) ) {
875
  $tag = str_replace( 'wp_ajax_slimstat_', '', $tag );
876
  wp_slimstat::$settings[ $tag ] = 'no';
 
 
 
877
  }
878
 
879
  exit();
@@ -957,14 +961,6 @@ class wp_slimstat_admin {
957
  }
958
  // END: manage_filters
959
 
960
- /*
961
- * Updates the options
962
- */
963
- public static function update_settings( $_settings = array() ) {
964
-
965
- }
966
- // END: update_settings
967
-
968
  /**
969
  * Contextual help
970
  */
18
  * Init -- Sets things up.
19
  */
20
  public static function init() {
21
+ self::$admin_notice = "We recently introduced a new simplified tracker that gets rid of a few layers of convoluted functions and algorithms accumulated over the years. Even though we have tested our new code using a variety of scenarios, you can understand how it would be impossible to cover all the environments available out there. <strong>Make sure to clear your caches</strong> (local, Cloudflare, WP plugins, etc), to allow Slimstat to append the new tracking script to your pages. Also, if you are using Slimstat to track <strong>external</strong> pages (outside of your WP install), please make sure to update the code you're using on those pages with the new one you can find in Slimstat > Settings > Tracker > External Pages. As always, do not hesitate to contact <a href='https://support.wp-slimstat.com/' target='_blank'>our support team</a> if you notice any issues.";
22
+ // self::$admin_notice = "Just a quick reminder that, in our quest for improved performance, we are deprecating the two columns <em>type</em> and <em>event_description</em> in the events table, and consolidating that information in the <em>notes</em> field. Code will be added to Slimstat in a few released to actually drop these columns from the database. If you are using those two columns in your custom code, please feel free to contact our support team to discuss your options and how to update your code using the information collected by the new tracker.";
23
  // self::$admin_notice = "In this day and age where every single social media platform knows our individual whereabouts on the Interwebs, we have been doing some research on what <em>the techies</em> out there call <a href='https://amiunique.org/fp' target='_blank'>browser fingerprinting</a>. With this technique, it is not necessary to install any cookies to identify a specific user. This means that the act of fingerprinting a specific browser is stateless and transparent, and thus much more accurate. We are already wearing our lab coats and are hard at work to leverage <a href='https://github.com/Valve/fingerprintjs2' target='_blank'>tools like Fingerprint2</a> in Slimstat. This library, among other things, will allow our tracker to record your users' timezone: wouldn't it be nice to know what time it was for the user who was visiting your website? Of course, if you have Privacy Mode enabled, this feature will not be used, in compliance with GDPR and other international privacy laws. Stay tuned!";
24
 
25
  // Load language files
875
  if ( !empty( $tag ) ) {
876
  $tag = str_replace( 'wp_ajax_slimstat_', '', $tag );
877
  wp_slimstat::$settings[ $tag ] = 'no';
878
+
879
+ // Save the default values in the database
880
+ wp_slimstat::update_option( 'slimstat_options', wp_slimstat::$settings );
881
  }
882
 
883
  exit();
961
  }
962
  // END: manage_filters
963
 
 
 
 
 
 
 
 
 
964
  /**
965
  * Contextual help
966
  */
admin/view/addons.php CHANGED
@@ -10,12 +10,7 @@ if ( !empty( $_POST[ 'licenses' ] ) && is_array( $_POST[ 'licenses' ] ) && !empt
10
  wp_slimstat::$settings[ 'addon_licenses' ][ $a_license_slug ] = sanitize_title( $a_license_key );
11
  }
12
 
13
- if ( !is_network_admin() ) {
14
- update_option( 'slimstat_options', wp_slimstat::$settings );
15
- }
16
- else {
17
- update_site_option( 'slimstat_options', wp_slimstat::$settings );
18
- }
19
  }
20
 
21
  $response = get_transient( 'wp_slimstat_addon_list' );
10
  wp_slimstat::$settings[ 'addon_licenses' ][ $a_license_slug ] = sanitize_title( $a_license_key );
11
  }
12
 
13
+ wp_slimstat::update_option( 'slimstat_options', wp_slimstat::$settings );
 
 
 
 
 
14
  }
15
 
16
  $response = get_transient( 'wp_slimstat_addon_list' );
admin/view/layout.php CHANGED
@@ -1,17 +1,26 @@
1
  <?php
2
- $is_report_reset = false;
3
  if ( !empty( $_GET[ 'action' ] ) && $_GET[ 'action' ] == 'restore-views' ) {
4
  $GLOBALS[ 'wpdb' ]->query( "DELETE FROM {$GLOBALS['wpdb']->prefix}usermeta WHERE meta_key LIKE '%meta-box-order_admin_page_slimlayout%'" );
5
  $GLOBALS[ 'wpdb' ]->query( "DELETE FROM {$GLOBALS['wpdb']->prefix}usermeta WHERE meta_key LIKE '%mmetaboxhidden_admin_page_slimview%'" );
6
  $GLOBALS[ 'wpdb' ]->query( "DELETE FROM {$GLOBALS['wpdb']->prefix}usermeta WHERE meta_key LIKE '%meta-box-order_slimstat%'" );
7
  $GLOBALS[ 'wpdb' ]->query( "DELETE FROM {$GLOBALS['wpdb']->prefix}usermeta WHERE meta_key LIKE '%metaboxhidden_slimstat%'" );
8
  $GLOBALS[ 'wpdb' ]->query( "DELETE FROM {$GLOBALS['wpdb']->prefix}usermeta WHERE meta_key LIKE '%closedpostboxes_slimstat%'" );
9
- $is_report_reset = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  }
11
 
12
- include_once( dirname(__FILE__) . '/wp-slimstat-reports.php' );
13
- wp_slimstat_reports::init();
14
-
15
  // Keep track of multiple occurrences of the same report, to allow users to delete duplicates
16
  $already_seen = array();
17
  ?>
1
  <?php
 
2
  if ( !empty( $_GET[ 'action' ] ) && $_GET[ 'action' ] == 'restore-views' ) {
3
  $GLOBALS[ 'wpdb' ]->query( "DELETE FROM {$GLOBALS['wpdb']->prefix}usermeta WHERE meta_key LIKE '%meta-box-order_admin_page_slimlayout%'" );
4
  $GLOBALS[ 'wpdb' ]->query( "DELETE FROM {$GLOBALS['wpdb']->prefix}usermeta WHERE meta_key LIKE '%mmetaboxhidden_admin_page_slimview%'" );
5
  $GLOBALS[ 'wpdb' ]->query( "DELETE FROM {$GLOBALS['wpdb']->prefix}usermeta WHERE meta_key LIKE '%meta-box-order_slimstat%'" );
6
  $GLOBALS[ 'wpdb' ]->query( "DELETE FROM {$GLOBALS['wpdb']->prefix}usermeta WHERE meta_key LIKE '%metaboxhidden_slimstat%'" );
7
  $GLOBALS[ 'wpdb' ]->query( "DELETE FROM {$GLOBALS['wpdb']->prefix}usermeta WHERE meta_key LIKE '%closedpostboxes_slimstat%'" );
8
+
9
+ // Reset the reports for the rest of this request
10
+ wp_slimstat_reports::$reports = array();
11
+ wp_slimstat_reports::$user_reports = array(
12
+ 'slimview1' => array(),
13
+ 'slimview2' => array(),
14
+ 'slimview3' => array(),
15
+ 'slimview4' => array(),
16
+ 'slimview5' => array(),
17
+ 'dashboard' => array(),
18
+ 'inactive' => array()
19
+ );
20
+ wp_slimstat_admin::$meta_user_reports = array();
21
+ wp_slimstat_reports::init();
22
  }
23
 
 
 
 
24
  // Keep track of multiple occurrences of the same report, to allow users to delete duplicates
25
  $already_seen = array();
26
  ?>
admin/view/right-now.php CHANGED
@@ -202,14 +202,16 @@ for ( $i=0; $i < $count_page_results; $i++ ) {
202
  }
203
 
204
  // Permalink: find post title, if available
205
-
206
-
207
  if ( !empty( $results[ $i ][ 'resource' ] ) ) {
208
  if ( isset( $results[ $i ][ 'blog_id' ] ) ) {
209
  $results[ $i ][ 'resource' ] = get_site_url( $results[ $i ][ 'blog_id' ] ) . $results[ $i ][ 'resource' ];
 
 
 
 
210
  }
211
 
212
- $results[ $i ][ 'resource' ] = "<a class='slimstat-font-logout slimstat-tooltip-trigger' target='_blank' title='" . htmlentities( __( 'Open this URL in a new window', 'wp-slimstat' ), ENT_QUOTES, 'UTF-8' ) . "' href='" . htmlentities( $results[$i][ 'resource' ], ENT_QUOTES, 'UTF-8' ) . "'></a> <a class='slimstat-filter-link' href='" . wp_slimstat_reports::fs_url( 'resource equals ' . htmlentities( $results[ $i ][ 'resource' ], ENT_QUOTES, 'UTF-8' ) ) . "'>" . wp_slimstat_reports::get_resource_title( $results[$i][ 'resource' ], $results[$i][ 'category' ] ) . '</a>';
213
  }
214
  else {
215
  if ( !empty( $results[$i][ 'notes' ] ) ) {
202
  }
203
 
204
  // Permalink: find post title, if available
 
 
205
  if ( !empty( $results[ $i ][ 'resource' ] ) ) {
206
  if ( isset( $results[ $i ][ 'blog_id' ] ) ) {
207
  $results[ $i ][ 'resource' ] = get_site_url( $results[ $i ][ 'blog_id' ] ) . $results[ $i ][ 'resource' ];
208
+ $resource_title = $results[ $i ][ 'resource' ];
209
+ }
210
+ else {
211
+ $resource_title = wp_slimstat_reports::get_resource_title( $results[$i][ 'resource' ] );
212
  }
213
 
214
+ $results[ $i ][ 'resource' ] = "<a class='slimstat-font-logout slimstat-tooltip-trigger' target='_blank' title='" . htmlentities( __( 'Open this URL in a new window', 'wp-slimstat' ), ENT_QUOTES, 'UTF-8' ) . "' href='" . htmlentities( $results[$i][ 'resource' ], ENT_QUOTES, 'UTF-8' ) . "'></a> <a class='slimstat-filter-link' href='" . wp_slimstat_reports::fs_url( 'resource equals ' . htmlentities( $results[ $i ][ 'resource' ], ENT_QUOTES, 'UTF-8' ) ) . "'>" . $resource_title . '</a>';
215
  }
216
  else {
217
  if ( !empty( $results[$i][ 'notes' ] ) ) {
admin/view/wp-slimstat-db.php CHANGED
@@ -97,10 +97,6 @@ class wp_slimstat_db {
97
  'dt_out' => array( __( 'Exit Timestamp', 'wp-slimstat' ), 'int' ),
98
 
99
  // Other columns
100
- 'language_calculated' => array( __( 'Language', 'wp-slimstat' ), 'varchar' ),
101
- 'platform_calculated' => array( __( 'Operating System', 'wp-slimstat' ), 'varchar' ),
102
- 'resource_calculated' => array( __( 'Permalink', 'wp-slimstat' ), 'varchar' ),
103
- 'referer_calculated' => array( __( 'Referer', 'wp-slimstat' ), 'varchar' ),
104
  'metric' => array( __( 'Metric', 'wp-slimstat' ), 'varchar' ),
105
  'value' => array( __( 'Value', 'wp-slimstat' ), 'varchar' ),
106
  'counthits' => array( __( 'Hits', 'wp-slimstat' ), 'int' ),
@@ -252,7 +248,6 @@ class wp_slimstat_db {
252
  }
253
 
254
  if ( !empty( $_column ) && !empty( self::$columns_names[ $_column ] ) ) {
255
- $_column = str_replace( '_calculated', '', $_column );
256
  $column_with_alias = $_column;
257
  if ( !empty( $_slim_stats_table_alias ) ) {
258
  $column_with_alias = $_slim_stats_table_alias . '.' . $column_with_alias;
@@ -276,8 +271,6 @@ class wp_slimstat_db {
276
  $filter_empty = ( !empty( self::$columns_names[ $_dimension ] ) && self::$columns_names[ $_dimension ] [ 1 ] == 'varchar' ) ? 'IS NULL' : '= 0';
277
  $filter_not_empty = ( !empty( self::$columns_names[ $_dimension ] ) && self::$columns_names[ $_dimension ] [ 1 ] == 'varchar' ) ? 'IS NOT NULL' : '<> 0';
278
 
279
- $_dimension = str_replace( '_calculated', '', $_dimension );
280
-
281
  $column_with_alias = $_dimension;
282
  if ( !empty( $_slim_stats_table_alias ) ) {
283
  $column_with_alias = $_slim_stats_table_alias . '.' . $_dimension;
@@ -372,7 +365,12 @@ class wp_slimstat_db {
372
  self::$debug_message .= "<p class='debug'>$_sql</p>";
373
  }
374
 
375
- return wp_slimstat::$wpdb->get_results( $_sql, ARRAY_A );
 
 
 
 
 
376
  }
377
 
378
  public static function get_var( $_sql = '', $_aggregate_value = '' ) {
@@ -382,7 +380,12 @@ class wp_slimstat_db {
382
  self::$debug_message .= "<p class='debug'>$_sql</p>";
383
  }
384
 
385
- return wp_slimstat::$wpdb->get_var( $_sql );
 
 
 
 
 
386
  }
387
 
388
  public static function parse_filters( $_filters_raw ) {
@@ -878,8 +881,13 @@ class wp_slimstat_db {
878
  $columns = "$_column AS $_as_column";
879
  }
880
 
 
 
 
 
 
881
  if ( $_column != '*' ) {
882
- $columns .= ', ip, dt';
883
  $group_by = 'GROUP BY ' . $_column;
884
  }
885
  else {
@@ -940,6 +948,8 @@ class wp_slimstat_db {
940
  $_column = $_column[ 'columns' ];
941
  }
942
 
 
 
943
  if ( !empty( $_as_column ) ) {
944
  $_column = "$_column AS $_as_column";
945
  }
@@ -953,7 +963,7 @@ class wp_slimstat_db {
953
  SELECT $_column, COUNT(*) counthits
954
  FROM {$GLOBALS['wpdb']->prefix}slim_stats
955
  WHERE $_where
956
- GROUP BY $_as_column $_having
957
  ORDER BY counthits DESC
958
  LIMIT 0, " . self::$filters_normalized[ 'misc' ][ 'limit_results' ],
959
  ( ( !empty( $_as_column ) && $_as_column != $_column ) ? $_as_column : $_column ),
@@ -1238,22 +1248,6 @@ class wp_slimstat_db {
1238
  return $results;
1239
  }
1240
 
1241
- // protected static function array_column( $input = array(), $columns = array() ) {
1242
- // $output = array();
1243
-
1244
- // foreach ( $input as $a_key => $a_row ) {
1245
- // foreach ( $columns as $a_column ) {
1246
- // var_dump($a_column);
1247
- // $a_column = trim( $a_column );
1248
- // if ( $a_row[ $a_column ] != NULL ) {
1249
- // $output[ $a_key ][ $a_column ] = $a_row[ $a_column ];
1250
- // }
1251
- // }
1252
- // }
1253
-
1254
- // return $output;
1255
- // }
1256
-
1257
  protected static function count_months_between( $min_timestamp = 0, $max_timestamp = 0 ) {
1258
  $i = 0;
1259
  $min_month = date( 'Ym', $min_timestamp );
97
  'dt_out' => array( __( 'Exit Timestamp', 'wp-slimstat' ), 'int' ),
98
 
99
  // Other columns
 
 
 
 
100
  'metric' => array( __( 'Metric', 'wp-slimstat' ), 'varchar' ),
101
  'value' => array( __( 'Value', 'wp-slimstat' ), 'varchar' ),
102
  'counthits' => array( __( 'Hits', 'wp-slimstat' ), 'int' ),
248
  }
249
 
250
  if ( !empty( $_column ) && !empty( self::$columns_names[ $_column ] ) ) {
 
251
  $column_with_alias = $_column;
252
  if ( !empty( $_slim_stats_table_alias ) ) {
253
  $column_with_alias = $_slim_stats_table_alias . '.' . $column_with_alias;
271
  $filter_empty = ( !empty( self::$columns_names[ $_dimension ] ) && self::$columns_names[ $_dimension ] [ 1 ] == 'varchar' ) ? 'IS NULL' : '= 0';
272
  $filter_not_empty = ( !empty( self::$columns_names[ $_dimension ] ) && self::$columns_names[ $_dimension ] [ 1 ] == 'varchar' ) ? 'IS NOT NULL' : '<> 0';
273
 
 
 
274
  $column_with_alias = $_dimension;
275
  if ( !empty( $_slim_stats_table_alias ) ) {
276
  $column_with_alias = $_slim_stats_table_alias . '.' . $_dimension;
365
  self::$debug_message .= "<p class='debug'>$_sql</p>";
366
  }
367
 
368
+ // Save the results of this query in our object cache
369
+ if ( empty( wp_cache_get( md5( $_sql ), 'wp-slimstat' ) ) ) {
370
+ wp_cache_add( md5( $_sql ), wp_slimstat::$wpdb->get_results( $_sql, ARRAY_A ), 'wp-slimstat' );
371
+ }
372
+
373
+ return wp_cache_get( md5( $_sql ), 'wp-slimstat' );
374
  }
375
 
376
  public static function get_var( $_sql = '', $_aggregate_value = '' ) {
380
  self::$debug_message .= "<p class='debug'>$_sql</p>";
381
  }
382
 
383
+ // Save the results of this query in our object cache
384
+ if ( empty( wp_cache_get( md5( $_sql ), 'wp-slimstat' ) ) ) {
385
+ wp_cache_add( md5( $_sql ), wp_slimstat::$wpdb->get_var( $_sql ), 'wp-slimstat' );
386
+ }
387
+
388
+ return wp_cache_get( md5( $_sql ), 'wp-slimstat' );
389
  }
390
 
391
  public static function parse_filters( $_filters_raw ) {
881
  $columns = "$_column AS $_as_column";
882
  }
883
 
884
+ // Add the IP column, used to display details about that visit
885
+ if ( $_column != 'ip' ) {
886
+ $columns .= ', ip';
887
+ }
888
+
889
  if ( $_column != '*' ) {
890
+ $columns .= ', dt';
891
  $group_by = 'GROUP BY ' . $_column;
892
  }
893
  else {
948
  $_column = $_column[ 'columns' ];
949
  }
950
 
951
+ $group_by_column = $_column;
952
+
953
  if ( !empty( $_as_column ) ) {
954
  $_column = "$_column AS $_as_column";
955
  }
963
  SELECT $_column, COUNT(*) counthits
964
  FROM {$GLOBALS['wpdb']->prefix}slim_stats
965
  WHERE $_where
966
+ GROUP BY $group_by_column $_having
967
  ORDER BY counthits DESC
968
  LIMIT 0, " . self::$filters_normalized[ 'misc' ][ 'limit_results' ],
969
  ( ( !empty( $_as_column ) && $_as_column != $_column ) ? $_as_column : $_column ),
1248
  return $results;
1249
  }
1250
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1251
  protected static function count_months_between( $min_timestamp = 0, $max_timestamp = 0 ) {
1252
  $i = 0;
1253
  $min_month = date( 'Ym', $min_timestamp );
admin/view/wp-slimstat-reports.php CHANGED
@@ -17,6 +17,11 @@ class wp_slimstat_reports {
17
  * Initalize class properties
18
  */
19
  public static function init() {
 
 
 
 
 
20
  // Include and initialize the API to interact with the database
21
  include_once( 'wp-slimstat-db.php' );
22
  wp_slimstat_db::init();
@@ -107,7 +112,7 @@ class wp_slimstat_reports {
107
  'callback_args' => array(
108
  'type' => 'top',
109
  'columns' => 'TRIM( TRAILING "/" FROM SUBSTRING_INDEX( resource, "' . ( !get_option( 'permalink_structure' ) ? '&' : '?' ) . '", 1 ) )',
110
- 'as_column' => 'resource_calculated',
111
  'filter_op' => 'contains',
112
  'raw' => array( 'wp_slimstat_db', 'get_top' )
113
  ),
@@ -121,7 +126,7 @@ class wp_slimstat_reports {
121
  'callback_args' => array(
122
  'type' => 'top',
123
  'columns' => 'REPLACE( SUBSTRING_INDEX( ( SUBSTRING_INDEX( ( SUBSTRING_INDEX( referer, "://", -1 ) ), "/", 1 ) ), ".", -5 ), "www.", "" )',
124
- 'as_column' => 'referer_calculated',
125
  'filter_op' => 'contains',
126
  'where' => 'referer NOT LIKE "%' . str_replace( 'www.', '', parse_url( home_url(), PHP_URL_HOST ) ) . '%"',
127
  'raw' => array( 'wp_slimstat_db', 'get_top' )
@@ -179,8 +184,8 @@ class wp_slimstat_reports {
179
  'callback' => array( __CLASS__, 'raw_results_to_html' ),
180
  'callback_args' => array(
181
  'type' => 'top',
182
- 'columns' => 'SUBSTRING(language, 1, 2)',
183
- 'as_column' => 'language_calculated',
184
  'filter_op' => 'contains',
185
  'raw' => array( 'wp_slimstat_db', 'get_top' )
186
  ),
@@ -423,8 +428,8 @@ class wp_slimstat_reports {
423
  'callback' => array( __CLASS__, 'raw_results_to_html' ),
424
  'callback_args' => array(
425
  'type' => 'top',
426
- 'columns' => 'CONCAT("p-", SUBSTRING(platform, 1, 3))',
427
- 'as_column' => 'platform_calculated',
428
  'filter_op' => 'contains',
429
  'raw' => array( 'wp_slimstat_db', 'get_top' )
430
  ),
@@ -533,7 +538,7 @@ class wp_slimstat_reports {
533
  'callback_args' => array(
534
  'type' => 'top',
535
  'columns' => 'REPLACE( SUBSTRING_INDEX( SUBSTRING_INDEX( SUBSTRING_INDEX( referer, "://", -1 ), "/", 1 ), ".", -5 ), "www.", "" )',
536
- 'as_column' => 'referer_calculated',
537
  'filter_op' => 'contains',
538
  'where' => 'searchterms IS NOT NULL AND searchterms <> "" AND searchterms <> "_" AND referer NOT LIKE "%' . str_replace( 'www.', '', parse_url( home_url(), PHP_URL_HOST ) ) . '%"',
539
  'raw' => array( 'wp_slimstat_db', 'get_top' )
@@ -560,7 +565,7 @@ class wp_slimstat_reports {
560
  'callback_args' => array(
561
  'type' => 'recent',
562
  'columns' => 'TRIM( TRAILING "/" FROM resource )',
563
- 'as_column' => 'resource_calculated',
564
  'where' => 'content_type = "post"',
565
  'raw' => array( 'wp_slimstat_db', 'get_recent' )
566
  ),
@@ -684,7 +689,7 @@ class wp_slimstat_reports {
684
  'callback_args' => array(
685
  'type' => 'recent',
686
  'columns' => 'TRIM( TRAILING "/" FROM resource )',
687
- 'as_column' => 'resource_calculated',
688
  'where' => '(content_type = "category" OR content_type = "tag")',
689
  'raw' => array( 'wp_slimstat_db', 'get_recent' )
690
  ),
@@ -766,7 +771,7 @@ class wp_slimstat_reports {
766
  'callback_args' => array(
767
  'type' => 'top',
768
  'columns' => 'TRIM( TRAILING "/" FROM resource )',
769
- 'as_column' => 'resource_calculated',
770
  'where' => 'content_type <> "404"',
771
  'having' => 'HAVING COUNT(visit_id) = 1',
772
  'raw' => array( 'wp_slimstat_db', 'get_top' )
@@ -861,22 +866,22 @@ class wp_slimstat_reports {
861
  $merge_reports = array_keys( self::$reports );
862
 
863
  // Do we have any new reports not listed in this user's settings?
864
- if ( class_exists( 'wp_slimstat_admin' ) ) {
865
- if ( !empty( wp_slimstat_admin::$meta_user_reports ) && is_array( wp_slimstat_admin::$meta_user_reports ) ) {
866
- $flat_user_reports = array_filter( explode( ',', implode( ',', wp_slimstat_admin::$meta_user_reports ) ) );
867
- $merge_reports = array_diff( array_filter( array_keys( self::$reports ) ), $flat_user_reports );
868
-
869
- // Now let's explode all the lists
870
- foreach ( wp_slimstat_admin::$meta_user_reports as $a_location => $a_report_list ) {
871
- self::$user_reports[ $a_location ] = explode( ',', $a_report_list );
872
- }
873
  }
874
  }
875
 
876
  foreach ( $merge_reports as $a_report_id ) {
877
  if ( !empty( self::$reports[ $a_report_id ][ 'locations' ] ) && is_array( self::$reports[ $a_report_id ][ 'locations' ] ) ) {
878
  foreach ( self::$reports[ $a_report_id ][ 'locations' ] as $a_report_location ) {
879
- self::$user_reports[ $a_report_location ][] = $a_report_id;
 
 
880
  }
881
  }
882
  }
@@ -1035,7 +1040,6 @@ class wp_slimstat_reports {
1035
  echo self::report_pagination( $count_page_results, count( $all_results ) );
1036
 
1037
  $permalinks_enabled = get_option( 'permalink_structure' );
1038
- $column_not_calculated = str_replace( '_calculated', '', $_args[ 'columns' ] );
1039
 
1040
  for ( $i=0; $i<$count_page_results; $i++ ) {
1041
  $row_details = $percentage = '';
@@ -1043,7 +1047,7 @@ class wp_slimstat_reports {
1043
  $element_value = $results[ $i ][ $_args[ 'columns' ] ];
1044
 
1045
  // Some columns require a special pre-treatment
1046
- switch ( $column_not_calculated ){
1047
  case 'browser':
1048
  if ( !empty( $results[ $i ][ 'user_agent' ] ) && wp_slimstat::$settings[ 'show_complete_user_agent_tooltip' ] == 'on' ) {
1049
  $element_pre_value = self::inline_help( $results[ $i ][ 'user_agent' ], false );
@@ -1061,12 +1065,13 @@ class wp_slimstat_reports {
1061
  $element_value = slim_i18n::get_string( 'c-' . $results[ $i ][ 'country' ] );
1062
  break;
1063
 
 
1064
  case 'ip':
1065
  if ( wp_slimstat::$settings[ 'convert_ip_addresses' ] == 'on' ) {
1066
- $element_value = gethostbyaddr( $results[ $i ][ $_args[ 'columns' ] ] );
1067
  }
1068
  else{
1069
- $element_value = $results[ $i ][ $_args[ 'columns' ] ];
1070
  }
1071
  break;
1072
 
@@ -1136,7 +1141,7 @@ class wp_slimstat_reports {
1136
  }
1137
 
1138
  if ( is_admin() ) {
1139
- $element_value = "<a class='slimstat-filter-link' href='" . self::fs_url( $column_not_calculated. ' ' . $_args[ 'filter_op' ] . ' ' . $results[ $i ][ $_args[ 'columns' ] ] ) . "'>$element_value</a>";
1140
  }
1141
 
1142
  if ( !empty( $_args['type'] ) && $_args['type'] == 'recent' ) {
@@ -1149,7 +1154,7 @@ class wp_slimstat_reports {
1149
 
1150
  if ( ( !empty( $_args[ 'criteria' ] ) && $_args[ 'criteria' ] == 'swap' ) || wp_slimstat::$settings[ 'show_hits' ] == 'on' ) {
1151
  $percentage = ' <span>' . $counthits . '</span>';
1152
- $row_details = __('Hits','wp-slimstat') . ': ' . ( ( $column_not_calculated != 'outbound_resource' ) ? $percentage_value . '%' . ( !empty( $row_details ) ? '<br>' : '' ) . $row_details : '' );
1153
  }
1154
  else {
1155
  $percentage = ' <span>' . $percentage_value . '%</span>';
@@ -1167,11 +1172,6 @@ class wp_slimstat_reports {
1167
  $element_value = '<a target="_blank" class="slimstat-font-logout" title="'.__('Open this URL in a new window','wp-slimstat').'" href="'.$base_url.htmlentities($results[$i]['resource'], ENT_QUOTES, 'UTF-8').'"></a> '.$base_url.$element_value;
1168
  }
1169
 
1170
- if ( $_args[ 'columns' ] == 'referer_calculated' && !empty( $_args[ 'type' ] ) && $_args[ 'type' ] == 'top' ) {
1171
- $element_url = 'http://' . htmlentities( $results[ $i ][ 'referer_calculated' ], ENT_QUOTES, 'UTF-8' );
1172
- $element_value = '<a target="_blank" class="slimstat-font-logout" title="'.__('Open this URL in a new window','wp-slimstat').'" href="'.$element_url.'"></a> '.$element_value;
1173
- }
1174
-
1175
  if ( $_args[ 'columns' ] == 'referer' && !empty( $_args[ 'type' ] ) && $_args[ 'type' ] == 'top' ) {
1176
  $element_url = htmlentities( $results[ $i ][ 'referer' ], ENT_QUOTES, 'UTF-8' );
1177
  $element_value = '<a target="_blank" class="slimstat-font-logout" title="'.__('Open this URL in a new window','wp-slimstat').'" href="'.$element_url.'"></a> '.$element_value;
@@ -1737,7 +1737,6 @@ class wp_slimstat_reports {
1737
  // Columns
1738
  if ( !empty( $fn[ 'columns' ] ) ) {
1739
  foreach ( $fn[ 'columns' ] as $a_key => $a_filter ) {
1740
- $a_key = str_replace( '_calculated', '', $a_key );
1741
  $request_uri .= "&amp;fs%5B$a_key%5D=" . urlencode( $a_filter[ 0 ] . ' ' . str_replace( '=', '%3D', $a_filter[ 1 ] ) );
1742
  }
1743
  }
17
  * Initalize class properties
18
  */
19
  public static function init() {
20
+ // Has the class already been initialized?
21
+ if ( !empty( self::$reports ) ) {
22
+ return true;
23
+ }
24
+
25
  // Include and initialize the API to interact with the database
26
  include_once( 'wp-slimstat-db.php' );
27
  wp_slimstat_db::init();
112
  'callback_args' => array(
113
  'type' => 'top',
114
  'columns' => 'TRIM( TRAILING "/" FROM SUBSTRING_INDEX( resource, "' . ( !get_option( 'permalink_structure' ) ? '&' : '?' ) . '", 1 ) )',
115
+ 'as_column' => 'resource',
116
  'filter_op' => 'contains',
117
  'raw' => array( 'wp_slimstat_db', 'get_top' )
118
  ),
126
  'callback_args' => array(
127
  'type' => 'top',
128
  'columns' => 'REPLACE( SUBSTRING_INDEX( ( SUBSTRING_INDEX( ( SUBSTRING_INDEX( referer, "://", -1 ) ), "/", 1 ) ), ".", -5 ), "www.", "" )',
129
+ 'as_column' => 'referer',
130
  'filter_op' => 'contains',
131
  'where' => 'referer NOT LIKE "%' . str_replace( 'www.', '', parse_url( home_url(), PHP_URL_HOST ) ) . '%"',
132
  'raw' => array( 'wp_slimstat_db', 'get_top' )
184
  'callback' => array( __CLASS__, 'raw_results_to_html' ),
185
  'callback_args' => array(
186
  'type' => 'top',
187
+ 'columns' => 'SUBSTRING( language, 1, 2 )',
188
+ 'as_column' => 'language',
189
  'filter_op' => 'contains',
190
  'raw' => array( 'wp_slimstat_db', 'get_top' )
191
  ),
428
  'callback' => array( __CLASS__, 'raw_results_to_html' ),
429
  'callback_args' => array(
430
  'type' => 'top',
431
+ 'columns' => 'CONCAT( "p-", SUBSTRING( platform, 1, 3 ) )',
432
+ 'as_column' => 'platform',
433
  'filter_op' => 'contains',
434
  'raw' => array( 'wp_slimstat_db', 'get_top' )
435
  ),
538
  'callback_args' => array(
539
  'type' => 'top',
540
  'columns' => 'REPLACE( SUBSTRING_INDEX( SUBSTRING_INDEX( SUBSTRING_INDEX( referer, "://", -1 ), "/", 1 ), ".", -5 ), "www.", "" )',
541
+ 'as_column' => 'referer',
542
  'filter_op' => 'contains',
543
  'where' => 'searchterms IS NOT NULL AND searchterms <> "" AND searchterms <> "_" AND referer NOT LIKE "%' . str_replace( 'www.', '', parse_url( home_url(), PHP_URL_HOST ) ) . '%"',
544
  'raw' => array( 'wp_slimstat_db', 'get_top' )
565
  'callback_args' => array(
566
  'type' => 'recent',
567
  'columns' => 'TRIM( TRAILING "/" FROM resource )',
568
+ 'as_column' => 'resource',
569
  'where' => 'content_type = "post"',
570
  'raw' => array( 'wp_slimstat_db', 'get_recent' )
571
  ),
689
  'callback_args' => array(
690
  'type' => 'recent',
691
  'columns' => 'TRIM( TRAILING "/" FROM resource )',
692
+ 'as_column' => 'resource',
693
  'where' => '(content_type = "category" OR content_type = "tag")',
694
  'raw' => array( 'wp_slimstat_db', 'get_recent' )
695
  ),
771
  'callback_args' => array(
772
  'type' => 'top',
773
  'columns' => 'TRIM( TRAILING "/" FROM resource )',
774
+ 'as_column' => 'resource',
775
  'where' => 'content_type <> "404"',
776
  'having' => 'HAVING COUNT(visit_id) = 1',
777
  'raw' => array( 'wp_slimstat_db', 'get_top' )
866
  $merge_reports = array_keys( self::$reports );
867
 
868
  // Do we have any new reports not listed in this user's settings?
869
+ if ( class_exists( 'wp_slimstat_admin' ) && !empty( wp_slimstat_admin::$meta_user_reports ) && is_array( wp_slimstat_admin::$meta_user_reports ) ) {
870
+ $flat_user_reports = array_filter( explode( ',', implode( ',', wp_slimstat_admin::$meta_user_reports ) ) );
871
+ $merge_reports = array_diff( array_filter( array_keys( self::$reports ) ), $flat_user_reports );
872
+
873
+ // Now let's explode all the lists
874
+ foreach ( wp_slimstat_admin::$meta_user_reports as $a_location => $a_report_list ) {
875
+ self::$user_reports[ $a_location ] = explode( ',', $a_report_list );
 
 
876
  }
877
  }
878
 
879
  foreach ( $merge_reports as $a_report_id ) {
880
  if ( !empty( self::$reports[ $a_report_id ][ 'locations' ] ) && is_array( self::$reports[ $a_report_id ][ 'locations' ] ) ) {
881
  foreach ( self::$reports[ $a_report_id ][ 'locations' ] as $a_report_location ) {
882
+ if ( !in_array( $a_report_id, self::$user_reports[ $a_report_location ] ) ) {
883
+ self::$user_reports[ $a_report_location ][] = $a_report_id;
884
+ }
885
  }
886
  }
887
  }
1040
  echo self::report_pagination( $count_page_results, count( $all_results ) );
1041
 
1042
  $permalinks_enabled = get_option( 'permalink_structure' );
 
1043
 
1044
  for ( $i=0; $i<$count_page_results; $i++ ) {
1045
  $row_details = $percentage = '';
1047
  $element_value = $results[ $i ][ $_args[ 'columns' ] ];
1048
 
1049
  // Some columns require a special pre-treatment
1050
+ switch ( $_args[ 'columns' ] ){
1051
  case 'browser':
1052
  if ( !empty( $results[ $i ][ 'user_agent' ] ) && wp_slimstat::$settings[ 'show_complete_user_agent_tooltip' ] == 'on' ) {
1053
  $element_pre_value = self::inline_help( $results[ $i ][ 'user_agent' ], false );
1065
  $element_value = slim_i18n::get_string( 'c-' . $results[ $i ][ 'country' ] );
1066
  break;
1067
 
1068
+ case 'id':
1069
  case 'ip':
1070
  if ( wp_slimstat::$settings[ 'convert_ip_addresses' ] == 'on' ) {
1071
+ $element_value = gethostbyaddr( $results[ $i ][ 'ip' ] );
1072
  }
1073
  else{
1074
+ $element_value = $results[ $i ][ 'ip' ];
1075
  }
1076
  break;
1077
 
1141
  }
1142
 
1143
  if ( is_admin() ) {
1144
+ $element_value = "<a class='slimstat-filter-link' href='" . self::fs_url( $_args[ 'columns' ] . ' ' . $_args[ 'filter_op' ] . ' ' . $results[ $i ][ $_args[ 'columns' ] ] ) . "'>$element_value</a>";
1145
  }
1146
 
1147
  if ( !empty( $_args['type'] ) && $_args['type'] == 'recent' ) {
1154
 
1155
  if ( ( !empty( $_args[ 'criteria' ] ) && $_args[ 'criteria' ] == 'swap' ) || wp_slimstat::$settings[ 'show_hits' ] == 'on' ) {
1156
  $percentage = ' <span>' . $counthits . '</span>';
1157
+ $row_details = __('Hits','wp-slimstat') . ': ' . ( ( $_args[ 'columns' ] != 'outbound_resource' ) ? $percentage_value . '%' . ( !empty( $row_details ) ? '<br>' : '' ) . $row_details : '' );
1158
  }
1159
  else {
1160
  $percentage = ' <span>' . $percentage_value . '%</span>';
1172
  $element_value = '<a target="_blank" class="slimstat-font-logout" title="'.__('Open this URL in a new window','wp-slimstat').'" href="'.$base_url.htmlentities($results[$i]['resource'], ENT_QUOTES, 'UTF-8').'"></a> '.$base_url.$element_value;
1173
  }
1174
 
 
 
 
 
 
1175
  if ( $_args[ 'columns' ] == 'referer' && !empty( $_args[ 'type' ] ) && $_args[ 'type' ] == 'top' ) {
1176
  $element_url = htmlentities( $results[ $i ][ 'referer' ], ENT_QUOTES, 'UTF-8' );
1177
  $element_value = '<a target="_blank" class="slimstat-font-logout" title="'.__('Open this URL in a new window','wp-slimstat').'" href="'.$element_url.'"></a> '.$element_value;
1737
  // Columns
1738
  if ( !empty( $fn[ 'columns' ] ) ) {
1739
  foreach ( $fn[ 'columns' ] as $a_key => $a_filter ) {
 
1740
  $request_uri .= "&amp;fs%5B$a_key%5D=" . urlencode( $a_filter[ 0 ] . ' ' . str_replace( '=', '%3D', $a_filter[ 1 ] ) );
1741
  }
1742
  }
readme.txt CHANGED
@@ -6,7 +6,7 @@ Text Domain: wp-slimstat
6
  Requires at least: 4.9
7
  Requires PHP: 5.2
8
  Tested up to: 5.2
9
- Stable tag: 4.8.7.2
10
 
11
  == Description ==
12
  The leading web analytics plugin for WordPress. Track returning customers and registered users, monitor Javascript events, detect intrusions, analyze email campaigns. Thousands of WordPress sites are already using it.
@@ -60,6 +60,17 @@ Our knowledge base is available on our [support center](https://docs.wp-slimstat
60
  5. **Responsive layout** - Keep an eye on your reports on the go
61
 
62
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
 
63
  = 4.8.7.2 =
64
  * [Fix] The new tracker was having problems recording clicks on SVG elements within a link (thank you, [pollensteyn](https://wordpress.org/support/topic/javascript-error-typeerror/#post-11926542)).
65
  * [Fix] The event handler is now capable of tracking events on BUTTONs within FORM elements.
@@ -83,7 +94,6 @@ Our knowledge base is available on our [support center](https://docs.wp-slimstat
83
  * [Fix] A bug was affecting certain shortcodes when PHP 7.2 was enabled (thank you, Peter).
84
  * [Fix] Emptying one of the settings and saving did not produce the desired effect.
85
 
86
- =======
87
  = 4.8.6.2 =
88
  * [Update] We tweaked the SQL query to retrieve 'recent' results, and added a GROUP BY clause to remove duplicates. This might affect some custom reports you might have created, so please don't hesitate to contact us if you have any question or experience any issues.
89
  * [Fix] The button to delete all the records from the database was not working as expected (thank you, [Softfully](https://wordpress.org/support/topic/delete-all-records-doesnt-work/)).
6
  Requires at least: 4.9
7
  Requires PHP: 5.2
8
  Tested up to: 5.2
9
+ Stable tag: 4.8.7.3
10
 
11
  == Description ==
12
  The leading web analytics plugin for WordPress. Track returning customers and registered users, monitor Javascript events, detect intrusions, analyze email campaigns. Thousands of WordPress sites are already using it.
60
  5. **Responsive layout** - Keep an eye on your reports on the go
61
 
62
  == Changelog ==
63
+ = 4.8.7.3 =
64
+ * [New] Implemented a simple query cache to minimize the number of requests needed to crunch and display the data in the reports.
65
+ * [Update] Extended tracker to also record the 'fragment' portion of the URL, if available (this feature is only available in Client Mode).
66
+ * [Update] Do not show the resource title in Network View mode.
67
+ * [Fix] Some reports were not optimized for our Network Analytics add-on (thank you, Peter).
68
+ * [Fix] The notice displayed to share the latest news with our users would not disappear even after clicking the X button to close it (thank you, Anton).
69
+ * [Fix] The 'Top Web Pages' reports was listing duplicate entries.
70
+ * [Fix] A regression bug was affecting the Currently Online report, by showing incorrect information for the IP addresses.
71
+ * [Fix] After resetting the Customizer view, all reports were being listed twice (thank you, Anton).
72
+ * [Fix] A new feature introduced by our Javascript tracker was not working as expected in IE11 (thank you, [51nullacht](https://wordpress.org/support/topic/js-error-in-wp-slimstat-js321/)).
73
+
74
  = 4.8.7.2 =
75
  * [Fix] The new tracker was having problems recording clicks on SVG elements within a link (thank you, [pollensteyn](https://wordpress.org/support/topic/javascript-error-typeerror/#post-11926542)).
76
  * [Fix] The event handler is now capable of tracking events on BUTTONs within FORM elements.
94
  * [Fix] A bug was affecting certain shortcodes when PHP 7.2 was enabled (thank you, Peter).
95
  * [Fix] Emptying one of the settings and saving did not produce the desired effect.
96
 
 
97
  = 4.8.6.2 =
98
  * [Update] We tweaked the SQL query to retrieve 'recent' results, and added a GROUP BY clause to remove duplicates. This might affect some custom reports you might have created, so please don't hesitate to contact us if you have any question or experience any issues.
99
  * [Fix] The button to delete all the records from the database was not working as expected (thank you, [Softfully](https://wordpress.org/support/topic/delete-all-records-doesnt-work/)).
wp-slimstat.js CHANGED
@@ -318,7 +318,7 @@ var SlimStat = {
318
  if ( !SlimStat.empty( do_not_track.length ) && !SlimStat.empty( target_node ) ) {
319
  target_classes = !SlimStat.empty( target_node.className ) ? target_node.className.split( " " ) : [];
320
 
321
- if ( target_classes.filter( value => -1 !== do_not_track.indexOf( value ) ).length != 0 || ( !SlimStat.empty( target_node.attributes ) && !SlimStat.empty( target_node.attributes.rel ) && !SlimStat.empty( target_node.attributes.rel.value ) && SlimStat.in_array( target_node.attributes.rel.value, do_not_track ) ) ) {
322
  return false;
323
  }
324
  }
318
  if ( !SlimStat.empty( do_not_track.length ) && !SlimStat.empty( target_node ) ) {
319
  target_classes = !SlimStat.empty( target_node.className ) ? target_node.className.split( " " ) : [];
320
 
321
+ if ( target_classes.filter( function( value ) { return do_not_track.indexOf( value ) !== -1; } ).length != 0 || ( !SlimStat.empty( target_node.attributes ) && !SlimStat.empty( target_node.attributes.rel ) && !SlimStat.empty( target_node.attributes.rel.value ) && SlimStat.in_array( target_node.attributes.rel.value, do_not_track ) ) ) {
322
  return false;
323
  }
324
  }
wp-slimstat.min.js CHANGED
@@ -1 +1 @@
1
- var SlimStat={_base64_key_str:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-",_utf8_encode:function(a){var b,d,e="";for(a=a.replace(/\r\n/g,"\n"),b=0;b<a.length;b++)d=a.charCodeAt(b),128>d?e+=String.fromCharCode(d):127<d&&2048>d?(e+=String.fromCharCode(192|d>>6),e+=String.fromCharCode(128|63&d)):(e+=String.fromCharCode(224|d>>12),e+=String.fromCharCode(128|63&d>>6),e+=String.fromCharCode(128|63&d));return e},_base64_encode:function(a){var b,c,d,e,f,g,h,j="",k=0;for(a=SlimStat._utf8_encode(a);k<a.length;)b=a.charCodeAt(k++),c=a.charCodeAt(k++),d=a.charCodeAt(k++),e=b>>2,f=(3&b)<<4|c>>4,g=(15&c)<<2|d>>6,h=63&d,isNaN(c)?g=h=64:isNaN(d)&&(h=64),j=j+SlimStat._base64_key_str.charAt(e)+SlimStat._base64_key_str.charAt(f)+SlimStat._base64_key_str.charAt(g)+SlimStat._base64_key_str.charAt(h);return j},get_page_performance:function(){return slim_performance=window.performance||window.mozPerformance||window.msPerformance||window.webkitPerformance||{},"undefined"==typeof slim_performance.timing?0:slim_performance.timing.loadEventEnd-slim_performance.timing.responseEnd},get_server_latency:function(){return slim_performance=window.performance||window.mozPerformance||window.msPerformance||window.webkitPerformance||{},"undefined"==typeof slim_performance.timing?0:slim_performance.timing.responseEnd-slim_performance.timing.connectEnd},optout:function(a,b){a.preventDefault(),("string"!=typeof SlimStatParams.baseurl||0==SlimStatParams.baseurl.length)&&(SlimStatParams.baseurl="/"),expiration=new Date,expiration.setTime(expiration.getTime()+31536e6),document.cookie="slimstat_optout_tracking="+b+";path="+SlimStatParams.baseurl+";expires="+expiration.toGMTString(),a.target.parentNode.parentNode.removeChild(a.target.parentNode)},show_optout_message:function(){opt_out_cookies=SlimStat.empty(SlimStatParams.oc)?[]:SlimStatParams.oc.split(","),Array.isArray(opt_out_cookies)||(opt_out_cookies=[]),show_optout=0<opt_out_cookies.length;for(var a=0;a<opt_out_cookies.length;a++)""!=SlimStat.get_cookie(opt_out_cookies[a])&&(show_optout=!1);if(show_optout){try{xhr=new XMLHttpRequest}catch(a){return!1}if("object"==typeof xhr)return xhr.open("POST",SlimStatParams.ajaxurl,!0),xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xhr.setRequestHeader("X-Requested-With","XMLHttpRequest"),xhr.withCredentials=!0,xhr.send("action=slimstat_optout_html"),xhr.onreadystatechange=function(){4==xhr.readyState&&document.body.insertAdjacentHTML("beforeend",xhr.responseText)},!0}},add_event:function(a,b,c){a&&a.addEventListener?a.addEventListener(b,c,!1):a&&a.attachEvent?(a["e"+b+c]=c,a[b+c]=function(){a["e"+b+c](window.event)},a.attachEvent("on"+b,a[b+c])):a["on"+b]=a["e"+b+c]},in_array:function(a,b){for(var c=0;c<b.length;c++)if(-1!=a.indexOf(b[c].trim()))return!0;return!1},empty:function(a){return!("undefined"!=typeof a&&null!=a)||("number"==typeof a?0==a:"boolean"==typeof a?!a:"string"!=typeof a&&"object"!=typeof a||0==a.length)},get_cookie:function(a){var b="; "+document.cookie,c=b.split("; "+a+"=");return 2==c.length?c.pop().split(";").shift():""},send_to_server:function(a,b){if(SlimStat.empty(SlimStatParams.ajaxurl)||SlimStat.empty(a))return!1;if("undefined"==typeof b&&(b=!0),slimstat_data_with_client_info=a+"&sw="+screen.width+"&sh="+screen.height+"&bw="+window.innerWidth+"&bh="+window.innerHeight+"&sl="+SlimStat.get_server_latency()+"&pp="+SlimStat.get_page_performance(),b&&navigator.sendBeacon)navigator.sendBeacon(SlimStatParams.ajaxurl,slimstat_data_with_client_info);else{try{xhr=new XMLHttpRequest}catch(a){return!1}if("object"==typeof xhr)return xhr.open("POST",SlimStatParams.ajaxurl,!0),xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xhr.setRequestHeader("X-Requested-With","XMLHttpRequest"),xhr.withCredentials=!0,xhr.send(slimstat_data_with_client_info),xhr.onreadystatechange=function(){4==xhr.readyState&&(parsed_id=parseInt(xhr.responseText),!isNaN(parsed_id)&&0<parsed_id&&(SlimStatParams.id=xhr.responseText))},!0}return!1},ss_track:function(a,b){if(SlimStat.empty(SlimStatParams.id)||isNaN(parseInt(SlimStatParams.id))||0>=parseInt(SlimStatParams.id))return!1;if(note_array=[],SlimStat.empty(a)||note_array.push(a),"undefined"==typeof b&&(b=!0),SlimStat.empty(window.event))return!1;if(!SlimStat.empty(window.event.target))target_node=window.event.target;else if(!SlimStat.empty(window.event.srcElement))target_node=window.event.srcElement;else return!1;if(resource_url="",do_not_track=SlimStat.empty(SlimStatParams.dnt)?[]:SlimStatParams.dnt.split(","),!SlimStat.empty(target_node.nodeName)){switch(target_node.nodeName){case"INPUT":case"BUTTON":for(;!SlimStat.empty(target_node)&&!SlimStat.empty(target_node.nodeName)&&"form"!=target_node.nodeName.toLowerCase();)target_node=target_node.parentNode;SlimStat.empty(target_node)||SlimStat.empty(target_node.nodeName)||SlimStat.empty(target_node.action)||(resource_url=target_node.action);break;default:for(;!SlimStat.empty(target_node)&&!SlimStat.empty(target_node.nodeName)&&"a"!=target_node.nodeName.toLowerCase();)target_node=target_node.parentNode;if(!SlimStat.empty(target_node)){if(!SlimStat.empty(target_node.hash)&&target_node.hostname==location.hostname)resource_url=target_node.hash;else if(!SlimStat.empty(target_node.href)&&-1==target_node.href.indexOf("javascript:")){if(SlimStat.in_array(target_node.href,do_not_track))return!1;resource_url=target_node.href}"function"==typeof target_node.getAttribute&&(!SlimStat.empty(target_node.getAttribute("title"))&&note_array.push("Title:"+target_node.getAttribute("title")),!SlimStat.empty(target_node.getAttribute("id"))&&note_array.push("ID:"+target_node.getAttribute("id")))}}if(!SlimStat.empty(do_not_track.length)&&!SlimStat.empty(target_node)&&(target_classes=SlimStat.empty(target_node.className)?[]:target_node.className.split(" "),0!=target_classes.filter(a=>-1!==do_not_track.indexOf(a)).length||!SlimStat.empty(target_node.attributes)&&!SlimStat.empty(target_node.attributes.rel)&&!SlimStat.empty(target_node.attributes.rel.value)&&SlimStat.in_array(target_node.attributes.rel.value,do_not_track)))return!1}return position="0,0",SlimStat.empty(window.event.pageX)||SlimStat.empty(window.event.pageY)?!SlimStat.empty(window.event.clientX)&&!SlimStat.empty(document.body.scrollLeft)&&!SlimStat.empty(document.documentElement.scrollLeft)&&(position=window.event.clientX+document.body.scrollLeft+document.documentElement.scrollLeft+","+window.event.clientY+document.body.scrollTop+document.documentElement.scrollTop):position=window.event.pageX+","+window.event.pageY,SlimStat.empty(window.event.type)||(note_array.push("type:"+window.event.type),"keypress"==window.event.type?note_array.push("keypress:"+String.fromCharCode(parseInt(window.event.which))):"click"==window.event.type&&note_array.push("which:"+window.event.which)),SlimStat.send_to_server("action=slimtrack&id="+SlimStatParams.id+"&ref="+SlimStat._base64_encode(document.referrer)+"&res="+SlimStat._base64_encode(resource_url)+"&pos="+position+"&no="+SlimStat._base64_encode(note_array.join(", ")),b),!0}};"function"!=typeof String.prototype.trim&&(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),SlimStat.add_event(window,"load",function(){slimstat_data="",use_beacon=!0,SlimStat.empty(SlimStatParams.id)?(slimstat_data="action=slimtrack&ref="+SlimStat._base64_encode(document.referrer)+"&res="+SlimStat._base64_encode(window.location.href),!SlimStat.empty(SlimStatParams.ci)&&(slimstat_data+="&ci="+SlimStatParams.ci),use_beacon=!1):0<parseInt(SlimStatParams.id)&&(slimstat_data="action=slimtrack&id="+SlimStatParams.id),0<slimstat_data.length&&setTimeout(function(){SlimStat.send_to_server(slimstat_data,use_beacon)},50),all_links=document.getElementsByTagName("a");for(var a=0;a<all_links.length;a++)SlimStat.add_event(all_links[a],"click",function(){SlimStat.ss_track()});SlimStat.show_optout_message()});
1
+ var SlimStat={_base64_key_str:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-",_utf8_encode:function(t){var e,a,r="";for(t=t.replace(/\r\n/g,"\n"),e=0;e<t.length;e++)(a=t.charCodeAt(e))<128?r+=String.fromCharCode(a):(127<a&&a<2048?r+=String.fromCharCode(a>>6|192):(r+=String.fromCharCode(a>>12|224),r+=String.fromCharCode(a>>6&63|128)),r+=String.fromCharCode(63&a|128));return r},_base64_encode:function(t){var e,a,r,n,o,i,m,s="",d=0;for(t=SlimStat._utf8_encode(t);d<t.length;)n=(e=t.charCodeAt(d++))>>2,o=(3&e)<<4|(a=t.charCodeAt(d++))>>4,i=(15&a)<<2|(r=t.charCodeAt(d++))>>6,m=63&r,isNaN(a)?i=m=64:isNaN(r)&&(m=64),s=s+SlimStat._base64_key_str.charAt(n)+SlimStat._base64_key_str.charAt(o)+SlimStat._base64_key_str.charAt(i)+SlimStat._base64_key_str.charAt(m);return s},get_page_performance:function(){return slim_performance=window.performance||window.mozPerformance||window.msPerformance||window.webkitPerformance||{},void 0===slim_performance.timing?0:slim_performance.timing.loadEventEnd-slim_performance.timing.responseEnd},get_server_latency:function(){return slim_performance=window.performance||window.mozPerformance||window.msPerformance||window.webkitPerformance||{},void 0===slim_performance.timing?0:slim_performance.timing.responseEnd-slim_performance.timing.connectEnd},optout:function(t,e){t.preventDefault(),"string"==typeof SlimStatParams.baseurl&&0!=SlimStatParams.baseurl.length||(SlimStatParams.baseurl="/"),expiration=new Date,expiration.setTime(expiration.getTime()+31536e6),document.cookie="slimstat_optout_tracking="+e+";path="+SlimStatParams.baseurl+";expires="+expiration.toGMTString(),t.target.parentNode.parentNode.removeChild(t.target.parentNode)},show_optout_message:function(){opt_out_cookies=SlimStat.empty(SlimStatParams.oc)?[]:SlimStatParams.oc.split(","),Array.isArray(opt_out_cookies)||(opt_out_cookies=[]),show_optout=0<opt_out_cookies.length;for(var t=0;t<opt_out_cookies.length;t++)""!=SlimStat.get_cookie(opt_out_cookies[t])&&(show_optout=!1);if(show_optout){try{xhr=new XMLHttpRequest}catch(t){return!1}if("object"==typeof xhr)return xhr.open("POST",SlimStatParams.ajaxurl,!0),xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xhr.setRequestHeader("X-Requested-With","XMLHttpRequest"),xhr.withCredentials=!0,xhr.send("action=slimstat_optout_html"),xhr.onreadystatechange=function(){4==xhr.readyState&&document.body.insertAdjacentHTML("beforeend",xhr.responseText)},!0}},add_event:function(t,e,a){t&&t.addEventListener?t.addEventListener(e,a,!1):t&&t.attachEvent?(t["e"+e+a]=a,t[e+a]=function(){t["e"+e+a](window.event)},t.attachEvent("on"+e,t[e+a])):t["on"+e]=t["e"+e+a]},in_array:function(t,e){for(var a=0;a<e.length;a++)if(-1!=t.indexOf(e[a].trim()))return!0;return!1},empty:function(t){return void 0===t||null==t||("number"==typeof t?0==t:"boolean"==typeof t?!t:"string"!=typeof t&&"object"!=typeof t||0==t.length)},get_cookie:function(t){var e=("; "+document.cookie).split("; "+t+"=");return 2==e.length?e.pop().split(";").shift():""},send_to_server:function(t,e){if(SlimStat.empty(SlimStatParams.ajaxurl)||SlimStat.empty(t))return!1;if(void 0===e&&(e=!0),slimstat_data_with_client_info=t+"&sw="+screen.width+"&sh="+screen.height+"&bw="+window.innerWidth+"&bh="+window.innerHeight+"&sl="+SlimStat.get_server_latency()+"&pp="+SlimStat.get_page_performance(),e&&navigator.sendBeacon)navigator.sendBeacon(SlimStatParams.ajaxurl,slimstat_data_with_client_info);else{try{xhr=new XMLHttpRequest}catch(t){return!1}if("object"==typeof xhr)return xhr.open("POST",SlimStatParams.ajaxurl,!0),xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xhr.setRequestHeader("X-Requested-With","XMLHttpRequest"),xhr.withCredentials=!0,xhr.send(slimstat_data_with_client_info),xhr.onreadystatechange=function(){4==xhr.readyState&&(parsed_id=parseInt(xhr.responseText),!isNaN(parsed_id)&&0<parsed_id&&(SlimStatParams.id=xhr.responseText))},!0}return!1},ss_track:function(t,e){if(SlimStat.empty(SlimStatParams.id)||isNaN(parseInt(SlimStatParams.id))||parseInt(SlimStatParams.id)<=0)return!1;if(note_array=[],SlimStat.empty(t)||note_array.push(t),void 0===e&&(e=!0),SlimStat.empty(window.event))return!1;if(SlimStat.empty(window.event.target)){if(SlimStat.empty(window.event.srcElement))return!1;target_node=window.event.srcElement}else target_node=window.event.target;if(resource_url="",do_not_track=SlimStat.empty(SlimStatParams.dnt)?[]:SlimStatParams.dnt.split(","),!SlimStat.empty(target_node.nodeName)){switch(target_node.nodeName){case"INPUT":case"BUTTON":for(;!SlimStat.empty(target_node)&&!SlimStat.empty(target_node.nodeName)&&"form"!=target_node.nodeName.toLowerCase();)target_node=target_node.parentNode;SlimStat.empty(target_node)||SlimStat.empty(target_node.nodeName)||SlimStat.empty(target_node.action)||(resource_url=target_node.action);break;default:for(;!SlimStat.empty(target_node)&&!SlimStat.empty(target_node.nodeName)&&"a"!=target_node.nodeName.toLowerCase();)target_node=target_node.parentNode;if(!SlimStat.empty(target_node)){if(SlimStat.empty(target_node.hash)||target_node.hostname!=location.hostname){if(!SlimStat.empty(target_node.href)&&-1==target_node.href.indexOf("javascript:")){if(SlimStat.in_array(target_node.href,do_not_track))return!1;resource_url=target_node.href}}else resource_url=target_node.hash;"function"==typeof target_node.getAttribute&&(SlimStat.empty(target_node.getAttribute("title"))||note_array.push("Title:"+target_node.getAttribute("title")),SlimStat.empty(target_node.getAttribute("id"))||note_array.push("ID:"+target_node.getAttribute("id")))}}if(!SlimStat.empty(do_not_track.length)&&!SlimStat.empty(target_node)&&(target_classes=SlimStat.empty(target_node.className)?[]:target_node.className.split(" "),0!=target_classes.filter(function(t){return-1!==do_not_track.indexOf(t)}).length||!SlimStat.empty(target_node.attributes)&&!SlimStat.empty(target_node.attributes.rel)&&!SlimStat.empty(target_node.attributes.rel.value)&&SlimStat.in_array(target_node.attributes.rel.value,do_not_track)))return!1}return position="0,0",SlimStat.empty(window.event.pageX)||SlimStat.empty(window.event.pageY)?SlimStat.empty(window.event.clientX)||SlimStat.empty(document.body.scrollLeft)||SlimStat.empty(document.documentElement.scrollLeft)||(position=window.event.clientX+document.body.scrollLeft+document.documentElement.scrollLeft+","+window.event.clientY+document.body.scrollTop+document.documentElement.scrollTop):position=window.event.pageX+","+window.event.pageY,SlimStat.empty(window.event.type)||(note_array.push("type:"+window.event.type),"keypress"==window.event.type?note_array.push("keypress:"+String.fromCharCode(parseInt(window.event.which))):"click"==window.event.type&&note_array.push("which:"+window.event.which)),SlimStat.send_to_server("action=slimtrack&id="+SlimStatParams.id+"&ref="+SlimStat._base64_encode(document.referrer)+"&res="+SlimStat._base64_encode(resource_url)+"&pos="+position+"&no="+SlimStat._base64_encode(note_array.join(", ")),e),!0}};"function"!=typeof String.prototype.trim&&(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),SlimStat.add_event(window,"load",function(){slimstat_data="",use_beacon=!0,SlimStat.empty(SlimStatParams.id)?(slimstat_data="action=slimtrack&ref="+SlimStat._base64_encode(document.referrer)+"&res="+SlimStat._base64_encode(window.location.href),SlimStat.empty(SlimStatParams.ci)||(slimstat_data+="&ci="+SlimStatParams.ci),use_beacon=!1):0<parseInt(SlimStatParams.id)&&(slimstat_data="action=slimtrack&id="+SlimStatParams.id),0<slimstat_data.length&&setTimeout(function(){SlimStat.send_to_server(slimstat_data,use_beacon)},50),all_links=document.getElementsByTagName("a");for(var t=0;t<all_links.length;t++)SlimStat.add_event(all_links[t],"click",function(t){SlimStat.ss_track()});SlimStat.show_optout_message()});
wp-slimstat.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Slimstat Analytics
4
  Plugin URI: https://wordpress.org/plugins/wp-slimstat/
5
  Description: The leading web analytics plugin for WordPress
6
- Version: 4.8.7.2
7
  Author: Jason Crouse
8
  Author URI: https://www.wp-slimstat.com/
9
  Text Domain: wp-slimstat
@@ -15,7 +15,7 @@ if ( !empty( wp_slimstat::$settings ) ) {
15
  }
16
 
17
  class wp_slimstat {
18
- public static $version = '4.8.7.2';
19
  public static $settings = array();
20
 
21
  public static $wpdb = '';
@@ -42,7 +42,13 @@ class wp_slimstat {
42
  self::$settings = get_option( 'slimstat_options', array() );
43
  }
44
 
45
- self::$settings = array_merge( self::init_options(), self::$settings );
 
 
 
 
 
 
46
 
47
  // Allow third party tools to edit the options
48
  self::$settings = apply_filters( 'slimstat_init_options', self::$settings );
@@ -399,7 +405,7 @@ class wp_slimstat {
399
  }
400
 
401
  // Don't store the domain name in the database
402
- self::$stat[ 'resource' ] = $parsed_url[ 'path' ] . ( !empty( $parsed_url[ 'query' ] ) ? '?' . $parsed_url[ 'query' ] : '' );
403
 
404
  // Is this resource blacklisted?
405
  if ( !empty( self::$settings[ 'ignore_resources' ] ) && self::_is_blacklisted( self::$stat[ 'resource' ], self::$settings[ 'ignore_resources' ] ) ) {
@@ -675,15 +681,23 @@ class wp_slimstat {
675
  * Decodes the permalink
676
  */
677
  public static function get_request_uri() {
 
 
678
  if ( isset( $_SERVER[ 'REQUEST_URI' ] ) ) {
679
  return urldecode( $_SERVER[ 'REQUEST_URI' ] );
680
  }
681
- elseif ( isset( $_SERVER[ 'SCRIPT_NAME' ] ) ) {
682
- return isset( $_SERVER[ 'QUERY_STRING' ] ) ? $_SERVER[ 'SCRIPT_NAME' ] . '?' . $_SERVER[ 'QUERY_STRING' ] : $_SERVER[ 'SCRIPT_NAME' ];
683
  }
684
- else{
685
- return isset( $_SERVER[ 'QUERY_STRING' ] ) ? $_SERVER[ 'PHP_SELF' ] . '?' . $_SERVER[ 'QUERY_STRING' ] : $_SERVER[ 'PHP_SELF' ];
686
  }
 
 
 
 
 
 
687
  }
688
  // end get_request_uri
689
 
@@ -940,7 +954,7 @@ class wp_slimstat {
940
  // The special value 'post_list_no_qs' requires a substring to be calculated
941
  if ( in_array( 'post_link_no_qs', $w ) ) {
942
  $w_clean = array( 'SUBSTRING_INDEX( resource, "' . ( !get_option( 'permalink_structure' ) ? '&' : '?' ) . '", 1 )' );
943
- $as_column = 'resource_calculated';
944
  }
945
 
946
  // Retrieve the data
@@ -999,13 +1013,12 @@ class wp_slimstat {
999
 
1000
  case 'post_link':
1001
  case 'post_link_no_qs':
1002
- $resource_key = ( $a_column == 'post_link' ) ? 'resource' : 'resource_calculated';
1003
- $post_id = url_to_postid( $a_result[ $resource_key ] );
1004
  if ( $post_id > 0 ) {
1005
- $output[ $result_idx ][ $a_column ] .= "<a href='{$a_result[ $resource_key ]}'>" . get_the_title( $post_id ) . '</a>';
1006
  }
1007
  else {
1008
- $output[ $result_idx ][ $a_column ] .= "<a href='{$a_result[ $resource_key ]}'>{$a_result[ $resource_key ]}</a>";
1009
  }
1010
  break;
1011
 
@@ -1160,7 +1173,7 @@ class wp_slimstat {
1160
  }
1161
 
1162
  /**
1163
- * Imports all the 'old' options into the new array, and saves them
1164
  */
1165
  public static function init_options(){
1166
  return array(
@@ -1304,6 +1317,19 @@ class wp_slimstat {
1304
  }
1305
  // end init_options
1306
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1307
  /**
1308
  * Attach a script to every page to track visitors' screen resolution and other browser-based information
1309
  */
@@ -1812,13 +1838,10 @@ class wp_slimstat {
1812
  // end _get_client_info
1813
 
1814
  protected static function _log_error( $_error_code = 0 ) {
1815
- if ( !is_network_admin() ) {
1816
- update_option( 'slimstat_tracker_error', array( $_error_code, self::date_i18n( 'U' ) ) );
1817
- }
1818
- else {
1819
- update_site_option( 'slimstat_tracker_error', array( $_error_code, self::date_i18n( 'U' ) ) );
1820
- }
1821
 
 
1822
  do_action( 'slimstat_track_exit_' . abs( $_error_code ), self::$stat );
1823
 
1824
  return -$_error_code;
3
  Plugin Name: Slimstat Analytics
4
  Plugin URI: https://wordpress.org/plugins/wp-slimstat/
5
  Description: The leading web analytics plugin for WordPress
6
+ Version: 4.8.7.3
7
  Author: Jason Crouse
8
  Author URI: https://www.wp-slimstat.com/
9
  Text Domain: wp-slimstat
15
  }
16
 
17
  class wp_slimstat {
18
+ public static $version = '4.8.7.3';
19
  public static $settings = array();
20
 
21
  public static $wpdb = '';
42
  self::$settings = get_option( 'slimstat_options', array() );
43
  }
44
 
45
+ if ( empty( self::$settings ) ) {
46
+ // Save the default values in the database
47
+ self::update_option( 'slimstat_options', self::init_options() );
48
+ }
49
+ else {
50
+ self::$settings = array_merge( self::init_options(), self::$settings );
51
+ }
52
 
53
  // Allow third party tools to edit the options
54
  self::$settings = apply_filters( 'slimstat_init_options', self::$settings );
405
  }
406
 
407
  // Don't store the domain name in the database
408
+ self::$stat[ 'resource' ] = $parsed_url[ 'path' ] . ( !empty( $parsed_url[ 'query' ] ) ? '?' . $parsed_url[ 'query' ] : '' ) . ( !empty( $parsed_url[ 'fragment' ] ) ? '#' . $parsed_url[ 'fragment' ] : '' );
409
 
410
  // Is this resource blacklisted?
411
  if ( !empty( self::$settings[ 'ignore_resources' ] ) && self::_is_blacklisted( self::$stat[ 'resource' ], self::$settings[ 'ignore_resources' ] ) ) {
681
  * Decodes the permalink
682
  */
683
  public static function get_request_uri() {
684
+ $request_url = '';
685
+
686
  if ( isset( $_SERVER[ 'REQUEST_URI' ] ) ) {
687
  return urldecode( $_SERVER[ 'REQUEST_URI' ] );
688
  }
689
+ else if ( isset( $_SERVER[ 'SCRIPT_NAME' ] ) ) {
690
+ $request_url = $_SERVER[ 'SCRIPT_NAME' ];
691
  }
692
+ else if ( isset( $_SERVER[ 'PHP_SELF' ] ) ) {
693
+ $request_url = $_SERVER[ 'PHP_SELF' ];
694
  }
695
+
696
+ if ( isset( $_SERVER[ 'QUERY_STRING' ] ) ) {
697
+ $request_url .= '?' . $_SERVER[ 'QUERY_STRING' ];
698
+ }
699
+
700
+ return $request_url;
701
  }
702
  // end get_request_uri
703
 
954
  // The special value 'post_list_no_qs' requires a substring to be calculated
955
  if ( in_array( 'post_link_no_qs', $w ) ) {
956
  $w_clean = array( 'SUBSTRING_INDEX( resource, "' . ( !get_option( 'permalink_structure' ) ? '&' : '?' ) . '", 1 )' );
957
+ $as_column = 'resource';
958
  }
959
 
960
  // Retrieve the data
1013
 
1014
  case 'post_link':
1015
  case 'post_link_no_qs':
1016
+ $post_id = url_to_postid( $a_result[ 'resource' ] );
 
1017
  if ( $post_id > 0 ) {
1018
+ $output[ $result_idx ][ $a_column ] .= "<a href='{$a_result[ 'resource' ]}'>" . get_the_title( $post_id ) . '</a>';
1019
  }
1020
  else {
1021
+ $output[ $result_idx ][ $a_column ] .= "<a href='{$a_result[ 'resource' ]}'>{$a_result[ 'resource' ]}</a>";
1022
  }
1023
  break;
1024
 
1173
  }
1174
 
1175
  /**
1176
+ * Sets the default values for all the options
1177
  */
1178
  public static function init_options(){
1179
  return array(
1317
  }
1318
  // end init_options
1319
 
1320
+ /**
1321
+ * Saves a given option in the database
1322
+ */
1323
+ public static function update_option( $_key = '', $_value = '' ) {
1324
+ if ( !is_network_admin() ) {
1325
+ update_option( $_key, $_value );
1326
+ }
1327
+ else {
1328
+ update_site_option( $_key, $_value );
1329
+ }
1330
+ }
1331
+ // end update_option
1332
+
1333
  /**
1334
  * Attach a script to every page to track visitors' screen resolution and other browser-based information
1335
  */
1838
  // end _get_client_info
1839
 
1840
  protected static function _log_error( $_error_code = 0 ) {
1841
+ // Save this error in the database
1842
+ self::update_option( 'slimstat_tracker_error', array( $_error_code, self::date_i18n( 'U' ) ) );
 
 
 
 
1843
 
1844
+ // Allow third-party code to trigger actions based on this error
1845
  do_action( 'slimstat_track_exit_' . abs( $_error_code ), self::$stat );
1846
 
1847
  return -$_error_code;