Version Description
- [New] We've completely rewritten the portion of code that handles the date ranges in the Filter Bar. In order to simplify things, we have deprecated the
interval_direction
filter, which is now expressed by the sign in front of the interval value (positive for going forward from a given start date, and negative for going back in time). Please note that this change affect your existing shortcodes, if they use the aforementioned filter. We will update our documentation in the next few days to remove any reference to this filter, and to avoid any confusion. Please feel free to contact us if you have any questions or to report any issues. - [New] The comparison chart is now always displayed, using new criteria to determine the range to use. You may want to update your settings (Settings > Reports > Default Time Span > Days, and Reports > Comparison Chart) to mimic the old behavior or hide the comparison chart altogether, if you like.
- [Update] We've reintroduced the various levels of granularity for our charts: hourly (when a single day is selected), daily (for ranges up to 120 days) and monthly. Also, the comparison chart is now always available, regardless of the selected time range. Thank you, WebsiteOpzetten.
- [Update] Tooltips across the interface have a more uniform behavior.
Download this release
Release Info
Developer | coolmann |
Plugin | Slimstat Analytics |
Version | 4.7.7 |
Comparing to | |
See all releases |
Code changes from version 4.7.6.1 to 4.7.7
- README.md +0 -192
- admin/config/index.php +245 -244
- admin/css/slimstat.css +764 -763
- admin/js/slimstat.admin.js +520 -517
- admin/view/index.php +163 -168
- admin/view/right-now.php +297 -297
- admin/view/wp-slimstat-db.php +1007 -1099
- admin/view/wp-slimstat-reports.php +2192 -2197
- admin/wp-slimstat-admin.php +3 -3
- readme.txt +162 -155
- wp-slimstat.php +1967 -1966
README.md
DELETED
@@ -1,192 +0,0 @@
|
|
1 |
-
# Slimstat Analytics
|
2 |
-
**Contributors:** coolmann
|
3 |
-
**Donate link:** https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=BNJR5EZNY3W38
|
4 |
-
**Tags:** analytics, statistics, counter, tracking, reports, wassup, geolocation, online users, spider, tracker, pageviews, stats, maxmind, statistics, statpress, power stats, hit
|
5 |
-
Text Domain: wp-slimstat
|
6 |
-
**Requires at least:** 3.8
|
7 |
-
**Tested up to:** 4.9
|
8 |
-
**Stable tag:** 4.7.6.1
|
9 |
-
|
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.
|
13 |
-
|
14 |
-
|
15 |
-
### Feature Spotlight
|
16 |
-
[youtube https://www.youtube.com/watch?v=zEKP9yC8x6g]
|
17 |
-
|
18 |
-
|
19 |
-
### Main features
|
20 |
-
* Get access to real-time access log, measure server latency, track page events, keep an eye on your bounce rate and much more.
|
21 |
-
* Add shortcodes to your website to display reports in widgets or directly in posts and pages.
|
22 |
-
* Exclude users from statistics collection based on various criteria, including; user roles, common robots, IP subnets, admin pages, country, etc.
|
23 |
-
* Export your reports to CSV, generate user heatmaps or get daily emails right in your mailbox (via premium add-ons).
|
24 |
-
* Compatible with W3 Total Cache, WP SuperCache, CloudFlare and most caching plugins.
|
25 |
-
* Support for hashing IP addresses in the database to protect your users privacy.
|
26 |
-
* Accurate IP geolocation, browser and platform detection (courtesy of [MaxMind](http://www.maxmind.com/) and [Browscap](http://browscap.org)).
|
27 |
-
* World Map that works on your mobile device, too (courtesy of [amMap](http://www.ammap.com/)).
|
28 |
-
|
29 |
-
|
30 |
-
### Premium Add-ons
|
31 |
-
Visit [our website](http://www.wp-slimstat.com/addons/) for a list of available extensions.
|
32 |
-
|
33 |
-
|
34 |
-
### Social Media
|
35 |
-
[Like Us](https://www.facebook.com/slimstatistics/) on Facebook and [follow us](https://twitter.com/wp_stats) on Twitter to get the latest news and updates about our plugin.
|
36 |
-
|
37 |
-
|
38 |
-
### Translations
|
39 |
-
Slimstat is available in multiple languages: English, Belarusian (UStarCash), Chinese (沐熙工作室), Farsi, French (Michael Bastin, Jean-Michel Venet, Yves Pouplard, Henrick Kac), German (TechnoViel), Indonesian ([ChameleonJohn](https://www.chameleonjohn.com/)), Italian ([Slimstat Dev Team](https://www.wp-slimstat.com)), Japanese (h_a_l_f), Portuguese, Russian (Vitaly), Spanish ([WebHostingHub](http://www.webhostinghub.com/)), Swedish (Per Soderman) and Turkish (Seyit Mehmet Çoban). Is your language missing or incomplete? [Contact us](http://support.wp-slimstat.com/) today.
|
40 |
-
|
41 |
-
|
42 |
-
### Reviews and Feedback
|
43 |
-
* This is by far the most accurate and in-depth tracking plugin I've encountered for WordPress [MiMango](https://wordpress.org/support/topic/excellent-plugin-and-service-9)
|
44 |
-
* I have been relying on SlimStat to not only track all traffic to my sites accurately but also to present the stats in very useful graphic format [JJD3](https://wordpress.org/support/topic/an-essential-plugin-14)
|
45 |
-
* Thanks you for such an excellent plugin. I am using it to kick Jetpack out of all the wordpress installations that I manage for myself and others - [robertwagnervt](http://wordpress.org/support/topic/plugin-wp-slimstat-excellent-but-some-errors-on-activating)
|
46 |
-
* I like Slimstat very much and so I decided to use it instead of Piwik - [Joannes](http://wordpress.org/support/topic/plugin-wp-slimstat-slimstat-and-privacy)
|
47 |
-
* Read all the [reviews](http://wordpress.org/support/view/plugin-reviews/wp-slimstat) and feel free to post your own!
|
48 |
-
|
49 |
-
|
50 |
-
### Requirements
|
51 |
-
* WordPress 3.8+
|
52 |
-
* PHP 5.2+ (or 5.5+ if you use the Browscap data file)
|
53 |
-
* MySQL 5.0.3+
|
54 |
-
* At least 20 MB of free web space
|
55 |
-
* At least 5 MB of free DB space
|
56 |
-
* At least 32 Mb of free PHP memory for the tracker (peak memory usage)
|
57 |
-
* IE9+ or any browser supporting HTML5, to access the reports
|
58 |
-
|
59 |
-
|
60 |
-
## Installation
|
61 |
-
1. In your WordPress admin, go to Plugins > Add New
|
62 |
-
2. Search for WP Slimstat Analytics
|
63 |
-
3. Click on **Install Now** under WP Slimstat Analytics and then activate the plugin
|
64 |
-
4. Make sure your template calls `wp_footer()` or the equivalent hook somewhere (possibly just before the `</body>` tag)
|
65 |
-
5. Go to Slimstat > Settings > Maintenance tab > MaxMind IP to Country section and click on "Install GeoLite DB" to detect your visitors' countries based on their IP addresses
|
66 |
-
6. If your `wp-admin` folder is not publicly accessible, make sure to check the [FAQs](http://wordpress.org/extend/plugins/wp-slimstat/faq/) to see if there's anything else you need to do
|
67 |
-
|
68 |
-
|
69 |
-
## Please note
|
70 |
-
* If you decide to uninstall Slimstat Analytics, all the stats will be **PERMANENTLY** deleted from your database. Make sure to setup a database backup (wp_slim_*) to avoid losing your data.
|
71 |
-
* If you are upgrading from a version prior to 4.0, please install version 4.0 first to upgrade the database structure and download the new Geolocation data.
|
72 |
-
|
73 |
-
|
74 |
-
## Frequently Asked Questions
|
75 |
-
Our knowledge base is available on our [support center](http://docs.wp-slimstat.com/) website.
|
76 |
-
|
77 |
-
|
78 |
-
## Screenshots
|
79 |
-
### 1. **Overview** - Your website traffic at a glance
|
80 |
-
[missing image]
|
81 |
-
|
82 |
-
### 2. **Activity Log** - A real-time view of your visitors' whereabouts
|
83 |
-
[missing image]
|
84 |
-
|
85 |
-
### 3. **Settings** - Plenty of options to customize the plugin's behavior
|
86 |
-
[missing image]
|
87 |
-
|
88 |
-
### 4. **Interactive World Map** - See where your visitors are coming from
|
89 |
-
[missing image]
|
90 |
-
|
91 |
-
### 5. **Responsive layout** - Keep an eye on your reports on the go
|
92 |
-
[missing image]
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
## Changelog
|
97 |
-
|
98 |
-
### 4.7.6.1
|
99 |
-
* [Fix] The new Javascript library was interfering with the dropdown menus on the WordPress Dashboard. Thanks to all of those who helped us troubleshoot the issue.
|
100 |
-
|
101 |
-
|
102 |
-
### 4.7.6
|
103 |
-
* [Note] As we mentioned earlier, we've been working on streamlining and cleaning up our source code. It's incredible how layers of code can deposit on top of each other, until they form a thick layer that prevents developers from seeing clearly what's happening. It was time to apply some virtual citric acid to descale our code. If you're using any kind of server caching functionality, please make sure to clear your cache before opening a support request. Also, do not hesitate to reach out to us if you notice any strange or unusual behaviors.
|
104 |
-
* [New] You can now download the geolocation map as a PDF file or PNG image. Thank you, Steve, for suggesting this feature!
|
105 |
-
* [New] You can now exclude pageviews by content type, like 404, taxonomy, search, etc. Thank you, [victor50g](https://wordpress.org/support/topic/suggestion-enable-filtering-on-content-404/).
|
106 |
-
* [Update] Deprecated the 'direction' filter, which was a leftover from over 5 years ago, when we used our old interface.
|
107 |
-
* [Fix] The cron job to archive old records was not firing as expected under certain circumstances.
|
108 |
-
* [Fix] Charts did not render correctly, if no data was available for that specific view.
|
109 |
-
|
110 |
-
|
111 |
-
### 4.7.5.3
|
112 |
-
* [New] For those who can't manage to automatically update their local copy of our premium add-ons, we've added a link to manually download the zip file. You'll find it under the Plugins screen, once you've entered and saved the corresponding license key under Slimstat > Add-ons.
|
113 |
-
* [Update] The [Update Checker](https://github.com/YahnisElsts/plugin-update-checker) library has been updated to version 4.4.
|
114 |
-
* [Fix] The world map was not being displayed correctly if no data points were available for the selected time range (thank you, Michel).
|
115 |
-
|
116 |
-
|
117 |
-
### 4.7.5.2
|
118 |
-
* [Update] You can now customize the amount of dots displayed on the World Map, under Slimstat > Settings > Reports > Access Log and World Map. Thank you, [service4](https://wordpress.org/support/topic/new-geolocation-map-with-cities/).
|
119 |
-
* [Fix] A dependency error was being highlighted for one of our premium add-ons under certain circumstances. Thank you, Peter.
|
120 |
-
* [Fix] The option to not set the session cookie was not working as expected. Thank you, [Bjarne](https://wordpress.org/support/topic/disable-cookies-2/#post-9887099).
|
121 |
-
|
122 |
-
|
123 |
-
### 4.7.5.1
|
124 |
-
* [Update] Implemented a workaround to try and fix the "Forbidden" error that a few users are experiencing when trying to download the MaxMind Geolite2 data file.
|
125 |
-
* [Fix] Updated the link to manually download the MaxMind data file from their servers, and added a new page to our knowledge base to explain how to manually install it.
|
126 |
-
|
127 |
-
|
128 |
-
### 4.7.5
|
129 |
-
* [New] Now that Slimstat is capable of geolocating visitors at the city level, wouldn't it make sense to display those visitors on the map? Well, of course! Go check out this new feature by accessing the Geolocation tab in Slimstat.
|
130 |
-
* [New] Updated the tracking script to handle events triggered by external libraries, like the [Vimeo API](https://github.com/vimeo/player.js/#events). Thank you, Max.
|
131 |
-
* [New] Added new operator "included_in_set", which allows you to list multiple values to match against, when composing a shortcode.
|
132 |
-
* [New] Added new option to avoid that Slimstat assigns a COOKIE to your visitors. Thank you, [dragon013](https://wordpress.org/support/topic/disable-cookies-2/).
|
133 |
-
* [Fix] A bug was preventing the feature to "restrict users" to only see their reports from working as expected.
|
134 |
-
|
135 |
-
|
136 |
-
### 4.7.4.1
|
137 |
-
* [Update] The Browscap data file is now loaded only when needed, thus removing its inherent overhead when unnecessary.
|
138 |
-
* [Update] The Browscap data file has been updated to the latest version available on their repository (ver 6026).
|
139 |
-
* [Fix] Addressed a remote XSS Vulnerability responsibly disclosed by one of our customers. Thank you, [riscybusiness](https://wordpress.org/support/topic/security-vulnerability-affecting-slimstat/).
|
140 |
-
* [Fix] Reintroduced the WHOIS pin, which has been removed by mistake because of a regression bug. Thank you, [brachialis](https://wordpress.org/support/topic/whois-location-icon-disappear/).
|
141 |
-
|
142 |
-
|
143 |
-
### 4.7.4
|
144 |
-
* [Update] New fields added to the Email Report and Export to Excel add-ons, by extending how certain reports are defined in core.
|
145 |
-
* [Fix] The [false positive](https://www.virustotal.com/#/file/43f69d9c4028f857b5b5544ea4559c03b4d58e02d75617482db517c626164363/detection) alert related to a virus in our code was fixed by updating [AmChart](https://www.amcharts.com/) to the latest version available (thank you, Sasa).
|
146 |
-
* [Fix] Removed a PHP warning of undefined index (thank you, [slewis1000 and Sasa](https://wordpress.org/support/topic/php-notice-undefined-index-country/))
|
147 |
-
* [Fix] The MozScape report was causing connectivity issues for some users, and it is now set as "hidden" by default.
|
148 |
-
* [Fix] Regression bug related to our Export to Excel add-on.
|
149 |
-
|
150 |
-
|
151 |
-
### 4.7.3.1
|
152 |
-
* [Fix] Apparently more people than we initially thought have issues with the MaxMind data file not being saved as expected. We are introducing a temporary fix while we try to investigate this issue further.
|
153 |
-
|
154 |
-
|
155 |
-
### 4.7.3
|
156 |
-
* [Fix] A [few users](https://wordpress.org/support/topic/cannot-install-maxmind-geolite-db/) pointed out a weird behavior when installing the MaxMind Geolocation data file, where an empty folder would be created instead of the actual file. If you still experience issues related to this problem, please make sure to delete the empty folder "maxmind.mmdb" under `wp-content/uploads/wp-slimstat/`.
|
157 |
-
* [Fix] Apparently Microsoft Security Essentials [was not pleased with our code](https://wordpress.org/support/topic/trojandownloader097m-donoff-detected-in-archive/), and was returning a false positive alert that a virus was included with the source code (thank you, Sasa).
|
158 |
-
* [Fix] The "content_id" filter could not be used in a shortcode to reference other pages (i.e. `[slimstat f='count-all' w='id']content_id equals 2012[/slimstat]`). Thank you, Felipe.
|
159 |
-
* [Fix] Country flags were not being displayed properly under certain circumstances (thank you, [Catmaniax](https://wordpress.org/support/topic/minor-issue-missing-png-file/)).
|
160 |
-
* [Fix] Bug preventing the new Heatmap Add-on from working as expected.
|
161 |
-
|
162 |
-
|
163 |
-
### 4.7.2.2
|
164 |
-
* [New] Added support for SCRIPT_DEBUG: by defining this constant in your `wp-config.php` will make Slimstat load the unminified version of the javascript tracker (thank you, Sasa)
|
165 |
-
* [Update] Added new parameter to make the `admin-ajax.php` URL relative, to solve issues like [this one](https://wordpress.org/support/topic/xmlhttprequest-cannot-load-wp-adminadmin-ajax-php-3/).
|
166 |
-
* [Fix] The Network Settings premium add-on was not working because of a bug in the main plugin. Thank you, Steve, for pointing us into the right direction.
|
167 |
-
* [Fix] Updated the schema (columns) for the archive table.
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
### 4.7.2.1
|
172 |
-
* [Fix] The new table columns "location" and "city" were not being created on a fresh install (thank you, [nielsgoossens](https://wordpress.org/support/topic/no-data-anymore-2/#post-9491034))
|
173 |
-
* [Fix] Async mode was not working as expected (thank you, [keithgbcc](https://wordpress.org/support/topic/doesnt-work-1694/#post-9487448))
|
174 |
-
|
175 |
-
|
176 |
-
### 4.7.2
|
177 |
-
* [New] As those who have been using Slimstat for a while know, we never stop doing our good share of research and development to improve our plugin. One feature on our wishlist was to make the geolocation functionality more accurate. Specifically, users have been asking us to track not just the Country of origin, but possibly the state and city. In order to geolocate visitors, our code has been leveraging a third-party data file provided by [MaxMind.com](https://www.maxmind.com/en/home). A while ago, they launched a new data format, which improves performance and offers a way to quickly determine the city of origin. However, the new library required a higher version of PHP, and up until now we had been hesitant to adopt it, to allow more people to use our plugin, over the chance of offering this feature. Now, after spending some time combing through their code, we found a way to get the best of both worlds: by customizing their PHP library, we were able to make it work with PHP 5.3! Which means that now Slimstat is able to tell you your visitors' city of origin (and State, when applicable) right out of the box. This information is available in the Access Log report and in a new 'Top Cities' report under the Audience tab. Please note: the MaxMind data file to enable this feature is approximately 60 Mb, and for this reason <strong>this new functionality is not enabled by default</strong>. You must go to Slimstat > Settings > Tracker and turn on the corresponding option. Then go to Slimstat > Settings > Maintenance and uninstall/install the GeoLite file to download the one that contains the city data. Please feel free to contact us if you have any questions.
|
178 |
-
* [Update] Removed backward compatibility code for those updating from a version prior to 4.2. Hopefully most of our users are using a newer version that that. If you're not, please contact our support service for instructions on how to upgrade.
|
179 |
-
* [Update] The format used to save your settings in the database has been changed. You MUST update your premium add-ons as soon as possible, and get the version compatible with this new format, or you might notice unexpected behaviors. Please contact us if you experience difficulties updating your add-ons.
|
180 |
-
* [Update] Cleaned up some old CSS code affecting the reports.
|
181 |
-
|
182 |
-
|
183 |
-
### 4.7.1
|
184 |
-
* [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.
|
185 |
-
* [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.
|
186 |
-
* [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).
|
187 |
-
|
188 |
-
|
189 |
-
## Support Our Work
|
190 |
-
Slimstat Analytics is an open source project, dependent in large parts on donations. [This page](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=BNJR5EZNY3W38)
|
191 |
-
is for those who want to donate money - be it once, be it regularly, be it a small or a big amount. Everything is set up for an easy donation process.
|
192 |
-
Try it out, you'll be amazed how good it feels! If you're on a tight budget, please consider writing [a review](https://wordpress.org/support/plugin/wp-slimstat/reviews/#new-post) for Slimstat as a token of appreciation for our hard work!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin/config/index.php
CHANGED
@@ -1,245 +1,246 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
// Avoid direct access to this piece of code
|
4 |
-
if ( !function_exists( 'add_action' ) ) {
|
5 |
-
exit(0);
|
6 |
-
}
|
7 |
-
|
8 |
-
if ( isset( $_POST[ 'options' ][ 'ignore_capabilities' ] ) ) {
|
9 |
-
// Make sure all the capabilities exist in the system
|
10 |
-
$capability_not_found = false;
|
11 |
-
foreach( wp_slimstat::string_to_array( $_POST[ 'options' ][ 'ignore_capabilities' ] ) as $a_capability ) {
|
12 |
-
if ( isset( $GLOBALS[ 'wp_roles' ]->role_objects[ 'administrator' ]->capabilities ) && !array_key_exists( $a_capability, $GLOBALS[ 'wp_roles' ]->role_objects[ 'administrator' ]->capabilities ) ) {
|
13 |
-
$capability_not_found = true;
|
14 |
-
break;
|
15 |
-
}
|
16 |
-
}
|
17 |
-
|
18 |
-
if ( !$capability_not_found ) {
|
19 |
-
wp_slimstat::$settings[ 'ignore_capabilities' ] = $_POST[ 'options' ][ 'ignore_capabilities' ];
|
20 |
-
}
|
21 |
-
else{
|
22 |
-
wp_slimstat_admin::$faulty_fields[] = __( 'Invalid capability. Please check <a href="http://codex.wordpress.org/Roles_and_Capabilities" target="_new">this page</a> for more information', 'wp-slimstat' );
|
23 |
-
}
|
24 |
-
}
|
25 |
-
|
26 |
-
if ( isset( $_POST[ 'options' ][ 'can_view' ] ) ) {
|
27 |
-
// Make sure all the users exist in the system
|
28 |
-
$post_data = trim( $_POST[ 'options' ][ 'can_view' ] );
|
29 |
-
$user_array = wp_slimstat::string_to_array( $_POST[ 'options' ][ 'can_view' ] );
|
30 |
-
|
31 |
-
if ( !empty( $post_data ) ) {
|
32 |
-
$sql_user_placeholders = implode( ', ', array_fill( 0, count( $user_array ), '%s' ) );
|
33 |
-
if ( $GLOBALS[ 'wpdb' ]->get_var( $GLOBALS[ 'wpdb' ]->prepare( "SELECT COUNT( * ) FROM {$GLOBALS[ 'wpdb' ]->users} WHERE user_login IN ( $sql_user_placeholders )", $user_array ) ) == count( $user_array ) ) {
|
34 |
-
wp_slimstat::$settings[ 'can_view' ] = $_POST[ 'options' ][ 'can_view' ];
|
35 |
-
}
|
36 |
-
else{
|
37 |
-
wp_slimstat_admin::$faulty_fields[] = __( 'Read access: username not found', 'wp-slimstat' );
|
38 |
-
}
|
39 |
-
}
|
40 |
-
else {
|
41 |
-
wp_slimstat::$settings[ 'can_view' ] = '';
|
42 |
-
}
|
43 |
-
}
|
44 |
-
|
45 |
-
if ( isset( $_POST[ 'options' ][ 'capability_can_view' ] ) ) {
|
46 |
-
if ( isset( $GLOBALS[ 'wp_roles' ]->role_objects[ 'administrator' ]->capabilities ) && array_key_exists( $_POST[ 'options' ][ 'capability_can_view' ], $GLOBALS[ 'wp_roles' ]->role_objects[ 'administrator' ]->capabilities ) ) {
|
47 |
-
wp_slimstat::$settings[ 'capability_can_view' ] = $_POST[ 'options' ][ 'capability_can_view' ];
|
48 |
-
}
|
49 |
-
else{
|
50 |
-
wp_slimstat_admin::$faulty_fields[] = __( 'Invalid capability. Please check <a href="http://codex.wordpress.org/Roles_and_Capabilities" target="_new">this page</a> for more information', 'wp-slimstat' );
|
51 |
-
}
|
52 |
-
}
|
53 |
-
|
54 |
-
if ( isset( $_POST[ 'options' ][ 'can_admin' ] ) ) {
|
55 |
-
// Make sure all the users exist in the system
|
56 |
-
$post_data = trim( $_POST[ 'options' ][ 'can_admin' ] );
|
57 |
-
$user_array = wp_slimstat::string_to_array( $_POST[ 'options' ][ 'can_admin' ] );
|
58 |
-
|
59 |
-
if ( is_array( $user_array ) && !empty( $post_data ) ) {
|
60 |
-
$sql_user_placeholders = implode( ', ', array_fill( 0, count( $user_array ), '%s' ) );
|
61 |
-
if ( $GLOBALS[ 'wpdb' ]->get_var( $GLOBALS[ 'wpdb' ]->prepare( "SELECT COUNT( * ) FROM {$GLOBALS[ 'wpdb' ]->users} WHERE user_login IN ( $sql_user_placeholders )", $user_array ) ) == count( $user_array ) ) {
|
62 |
-
wp_slimstat::$settings[ 'can_admin' ] = $_POST[ 'options' ][ 'can_admin' ];
|
63 |
-
}
|
64 |
-
else{
|
65 |
-
wp_slimstat_admin::$faulty_fields[] = __( 'Config access: username not found', 'wp-slimstat' );
|
66 |
-
}
|
67 |
-
}
|
68 |
-
}
|
69 |
-
|
70 |
-
if ( isset( $_POST[ 'options' ][ 'capability_can_admin' ] ) ) {
|
71 |
-
if ( isset( $GLOBALS[ 'wp_roles' ]->role_objects[ 'administrator' ]->capabilities ) && array_key_exists( $_POST[ 'options' ][ 'capability_can_admin' ], $GLOBALS[ 'wp_roles' ]->role_objects[ 'administrator' ]->capabilities ) ) {
|
72 |
-
wp_slimstat::$settings[ 'capability_can_admin' ] = $_POST[ 'options' ][ 'capability_can_admin' ];
|
73 |
-
}
|
74 |
-
else{
|
75 |
-
wp_slimstat_admin::$faulty_fields[] = __( 'Invalid capability. Please check <a href="http://codex.wordpress.org/Roles_and_Capabilities" target="_new">this page</a> for more information', 'wp-slimstat' );
|
76 |
-
}
|
77 |
-
}
|
78 |
-
|
79 |
-
$current_tab = empty( $_GET[ 'tab' ] ) ? 1 : intval( $_GET[ 'tab' ] );
|
80 |
-
|
81 |
-
// Define all the options
|
82 |
-
$settings = array(
|
83 |
-
1 => array(
|
84 |
-
'title' => __( 'Basic', 'wp-slimstat' ),
|
85 |
-
'rows' => array(
|
86 |
-
'general_tracking_header' => array( 'description' => __( 'Tracker', 'wp-slimstat' ), 'type' => 'section_header' ),
|
87 |
-
'is_tracking' => array( 'description' => __( 'Enable Tracking', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Turn the tracker on or off, while keeping the reports accessible.', 'wp-slimstat' ) ),
|
88 |
-
'javascript_mode' => array( 'description' => __( 'Tracking Mode', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __('Select <strong>Client</strong> if you are using a caching plugin (W3 Total Cache, WP SuperCache, HyperCache, etc). Slimstat will behave pretty much like Google Analytics, and visitors whose browser does not support Javascript will be ignored. A nice side effect is that <strong>most spammers, search engines and other crawlers</strong> will not be tracked.','wp-slimstat'), 'custom_label_on' => __('Client','wp-slimstat'), 'custom_label_off' => __('Server','wp-slimstat') ),
|
89 |
-
'enable_javascript' => array( 'description' => __( 'Track Client Info', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "If this option is turned off, the tracker will not be collecting information such as screen resolution, outbound links, downloads, etc. This option is ignored if Tracking Mode is set to Client.", 'wp-slimstat' ) ),
|
90 |
-
'track_admin_pages' => array( 'description' => __( 'Track Admin Pages', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "Enable this option to track your users' activity within the admin.", 'wp-slimstat') ),
|
91 |
-
|
92 |
-
'general_integration_header' => array( 'description' => __( 'WordPress Integration', 'wp-slimstat' ), 'type' => 'section_header' ),
|
93 |
-
'add_dashboard_widgets' => array( 'description' => __( 'Dashboard Widgets', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Enable this option if you want to add reports to your WordPress Dashboard. Use the Customizer to choose which ones to display.', 'wp-slimstat' ) ),
|
94 |
-
'use_separate_menu' => array( 'description' => __( 'Menu Position', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Choose between a standalone admin menu for Slimstat or a drop down in the admin bar (if visible).', 'wp-slimstat' ), 'custom_label_on' => __( 'Side', 'wp-slimstat' ), 'custom_label_off' => __( 'Bar', 'wp-slimstat' ) ),
|
95 |
-
'posts_column_day_interval' => array( 'description' => __('Report Interval','wp-slimstat'), 'type' => 'integer', 'long_description' => __('Enter the time range, in days, that should be used to count the number of pageviews on Posts/Pages (see option here below) and for the Default Time Span option under the Reports tab.','wp-slimstat') ),
|
96 |
-
'add_posts_column' => array( 'description' => __('Posts and Pages','wp-slimstat'), 'type' => 'toggle', 'long_description' => __('Add a new column to the Edit Posts/Pages screens, with the number of hits per post within the timeframe specified here below.','wp-slimstat') ),
|
97 |
-
|
98 |
-
'posts_column_pageviews' => array( 'description' => __( 'Report Type','wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Select what kind of information you would like to see displayed on your Posts admin screen. Hits counts all the pageviews regardless of the user, (unique) IPs counts only one hit per IP in the given time range.', 'wp-slimstat' ), 'custom_label_on' => __( 'Hits', 'wp-slimstat' ), 'custom_label_off' => __( 'IPs', 'wp-slimstat' ) ),
|
99 |
-
'hide_addons' => array( 'description' => __( 'Hide Add-ons', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Enable this option to hide all your <strong>active</strong> premium add-ons from the list of plugins in WordPress. Please note that you will still receive updates for hidden add-ons.', 'wp-slimstat' ) ),
|
100 |
-
|
101 |
-
'general_database_header' => array('description' => __('Database','wp-slimstat'), 'type' => 'section_header'),
|
102 |
-
'auto_purge' => array( 'description' => __( 'Retain data for', 'wp-slimstat' ), 'type' => 'integer', 'long_description' => __( "Clean-up log entries older than the number of days specified here above. Enter <strong>0</strong> (number zero) if you want to preserve your data in the main table (neither archive it nor delete it) regardless of its age.", 'wp-slimstat' ).( (wp_slimstat::$settings[ 'auto_purge' ] > 0)?' '.__('Next clean-up on','wp-slimstat').' <strong>'.date_i18n(get_option('date_format').', '.get_option('time_format'), wp_next_scheduled( 'wp_update_plugins' ) ) . '</strong>. '.sprintf(__('Entries logged on or before %s will be archived or deleted according to the option here below.','wp-slimstat'), date_i18n(get_option('date_format'), strtotime('-'.wp_slimstat::$settings['auto_purge'].' days'))):''), 'after_input_field' => __('days','wp-slimstat') ),
|
103 |
-
'auto_purge_delete' => array( 'description' => __( 'Archive records', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'If DB space is not an issue, you can decide to archive older records in another table, instead of deleting them. This way performance is preserved, but you will still be able to access your data at a later time, if needed. Please note that the archive table (<code>wp_slim_stats_archive</code>) will be <strong>deleted</strong> along with all the other tables, when Slimstat is uninstalled. Make sure to backup your data before you proceed.', 'wp-slimstat' ) )
|
104 |
-
)
|
105 |
-
),
|
106 |
-
|
107 |
-
2 => array(
|
108 |
-
'title' => __( 'Tracker', 'wp-slimstat' ),
|
109 |
-
'rows' => array(
|
110 |
-
'filters_outbound_header' => array( 'description' => __( 'Link Tracking', 'wp-slimstat' ), 'type' => 'section_header' ),
|
111 |
-
'do_not_track_outbound_classes_rel_href' => array( 'description' => __( 'Do Not Track', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "Slimstat will ignore links marked with one of these class names, <em>rel</em> attributes or whose <em>href</em> attribute contains one of these strings. Please keep in mind that the class <code>noslimstat</code> is also used to avoid tracking interactive links throughout the reports. If you remove it from this list, some features might not work as expected.", 'wp-slimstat' ) ),
|
112 |
-
'extensions_to_track' => array( 'description' => __( 'Downloads', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( 'List all the file extensions that you want to be treated as Downloads. Please note that links pointing to external resources (i.e. PDFs on an external website) are considered Downloads and not Outbound Links (and tracked as such), if their extension matches one of the ones listed here below.', 'wp-slimstat' ) ),
|
113 |
-
'track_same_domain_referers' => array( 'description' => __( 'Same-Domain Referrers', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'By default, when the domain of the referrer for a given page view is the same as the current site, that information is not tracked to save space in the database. However, if you are running a multisite network with subfolders, you might need to track same-domain referrers from one site to another, as they are technically "separate" websites.', 'wp-slimstat' ) ),
|
114 |
-
|
115 |
-
'advanced_tracker_header' => array( 'description' => __( 'Advanced Options', 'wp-slimstat' ), 'type' => 'section_header' ),
|
116 |
-
'geolocation_country' => array( 'description' => __( 'Geolocation Precision', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "When Slimstat determines your visitors' Country of origin, it uses a third-party data file <a href='https://dev.maxmind.com/geoip/geoip2/geolite2/' target='_blank'>provided by MaxMind</a>. They offer two precision levels: country and city. By default, Slimstat will install the smaller one (country), and you can decide to use the other one, if you don't mind its 60 Mb average size. After you change this option, please <strong>go to the Maintenance tab</strong> and reload (uninstall/install) the MaxMind GeoLite DB by clicking on the corresponding button.", 'wp-slimstat' ), 'custom_label_on' => __( 'Country', 'wp-slimstat' ), 'custom_label_off' => __( 'City', 'wp-slimstat' ) ),
|
117 |
-
'session_duration' => array('description' => __( 'Session Duration', 'wp-slimstat' ), 'type' => 'integer', 'long_description' => __( 'How many seconds should a human session last? Google Analytics sets it to 1800 seconds.', 'wp-slimstat' ), 'after_input_field' => __( 'seconds', 'wp-slimstat' ) ),
|
118 |
-
'extend_session' => array( 'description' => __( 'Extend Session', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Extend the duration of a session each time the user visits a new page.', 'wp-slimstat' ) ),
|
119 |
-
'set_tracker_cookie' => array( 'description' => __( 'Set Cookie', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Disable this option if, for legal or security reasons, you do not want Slimstat to assign a <a href="https://en.wikipedia.org/wiki/HTTP_cookie" target="_blank">cookie</a> to your visitors. Please note that, by deactivating this feature, Slimstat will not keep track of returning visitors and sessions.', 'wp-slimstat' ) ),
|
120 |
-
'enable_cdn' => array( 'description' => __( 'Enable CDN', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "Use <a href='http://www.jsdelivr.com/' target='_blank'>JSDelivr</a>'s CDN, by serving our tracking code from their fast and reliable network (free service).", 'wp-slimstat' ) ),
|
121 |
-
'ajax_relative_path' => array( 'description' => __( 'Relative Ajax', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'If you are experiencing issues related to the header field X-Requested-With not being allowed by Access-Control-Allow-Headers in preflight response (or similar), try enabling this option to make that <code>admin-ajax.php</code> URL relative.', 'wp-slimstat' ) ),
|
122 |
-
|
123 |
-
'advanced_external_pages_header' => array('description' => __('External Pages','wp-slimstat'), 'type' => 'section_header'),
|
124 |
-
'external_pages_script' => array('type' => 'static', 'skip_update' => 'yes', 'description' => __('Add the following code to all the non-WP pages you want to track, right before the closing BODY tag. Please make sure to change the protocol of all the URLs to HTTPS, if you external site is served over a secure channel.','wp-slimstat'), 'long_description' => '<script type="text/javascript">
|
125 |
-
/* <![CDATA[ */
|
126 |
-
var SlimStatParams = {
|
127 |
-
ajaxurl: "'.admin_url('admin-ajax.php').'",
|
128 |
-
ci: "YTo0OntzOjEyOiJjb250ZW50X3R5cGUiO3M6ODoiZXh0ZXJuYWwiO3M6ODoiY2F0ZWdvcnkiO3M6MDoiIjtzOjEwOiJjb250ZW50X2lkIjtpOjA7czo2OiJhdXRob3IiO3M6MTM6ImV4dGVybmFsLXBhZ2UiO30=.' . md5('YTo0OntzOjEyOiJjb250ZW50X3R5cGUiO3M6ODoiZXh0ZXJuYWwiO3M6ODoiY2F0ZWdvcnkiO3M6MDoiIjtzOjEwOiJjb250ZW50X2lkIjtpOjA7czo2OiJhdXRob3IiO3M6MTM6ImV4dGVybmFsLXBhZ2UiO30=' . wp_slimstat::$settings[ 'secret' ] ).'",
|
129 |
-
extensions_to_track: "'.wp_slimstat::$settings['extensions_to_track'].'"
|
130 |
-
};
|
131 |
-
/* ]]> */
|
132 |
-
</script>
|
133 |
-
<script type="text/javascript" src="http://cdn.jsdelivr.net/wp/wp-slimstat/trunk/wp-slimstat.min.js"></script>', 'use_tag_list' => false ),
|
134 |
-
'external_domains' => array('description' => __('Allow Domains','wp-slimstat'), 'type' => 'textarea', 'long_description' => __("If you are getting an error saying that no 'Access-Control-Allow-Origin' header is present on the requested resource, when using the external tracking code here above, list the domains (complete with scheme) you would like to allow. For example: <code>http://my.domain.ext</code> (no trailing slash). Please see <a href='http://www.w3.org/TR/cors/#security' target='_blank'>this W3 resource</a> for more information on the security implications of allowing CORS requests.",'wp-slimstat'))
|
135 |
-
)
|
136 |
-
),
|
137 |
-
|
138 |
-
3 => array(
|
139 |
-
'title' => __( 'Filters', 'wp-slimstat' ),
|
140 |
-
'rows' => array(
|
141 |
-
'filters_categories_header' => array( 'description' => __( 'Profiling', 'wp-slimstat' ), 'type' => 'section_header' ),
|
142 |
-
'track_users' => array( 'description' => __( 'Track WP Users', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Enable this option to track logged in users.', 'wp-slimstat' ) ),
|
143 |
-
'ignore_spammers' => array( 'description' => __( 'Ignore Spammers', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "Enable this option if you don't want to track visits from users identified as spammers by third-party tools like Akismet. Pageviews generated by users whose comments are later marked as spam, will also be removed from the database.", 'wp-slimstat' ) ),
|
144 |
-
'ignore_bots' => array( 'description' => __( 'Ignore Bots', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "Turn on this feature if you want to have the accuracy level of server-side tracking, but not the inconvenience of getting your database clogged with pageviews generated by crawlers, spiders, search engine bots, etc. Please note that in Client mode, bots are ignored regardless of this setting.", 'wp-slimstat' ) ),
|
145 |
-
'ignore_prefetch' => array( 'description' => __( 'Ignore Prefetch Requests', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "Prevent Slimstat from tracking pageviews generated by Firefox's <a href='https://developer.mozilla.org/en/Link_prefetching_FAQ' target='_blank'>Link Prefetching functionality</a>.", 'wp-slimstat' ) ),
|
146 |
-
'anonymize_ip' => array( 'description' => __( 'Enable Privacy Mode', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "Mask your visitors' IP addresses to comply with European Privacy Laws.", 'wp-slimstat' ) ),
|
147 |
-
|
148 |
-
'filters_users_header' => array( 'description' => __( 'User Properties', 'wp-slimstat' ), 'type' => 'section_header' ),
|
149 |
-
'ignore_users' => array( 'description' => __( 'Usernames', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "List all the usernames you don't want to track. Please be aware that spaces are <em>not</em> ignored and that usernames are case sensitive. Wildcards: <code>*</code> matches 'any string, including the empty string', <code>!</code> matches 'any character'. For example, <code>user*</code> will match user12 and userfoo, <code>u*100</code> will match user100 and uber100, <code>user!0</code> will match user10 and user90.", 'wp-slimstat' ) ),
|
150 |
-
'ignore_ip' => array( 'description' => __( 'IP Addresses', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "List all the IP addresses you don't want to track. Each subnet <strong>must</strong> be defined using the <a href='https://www.iplocation.net/subnet-mask' target='_blank'>CIDR notation</a> (i.e. <em>192.168.0.0/24</em>). This filter applies both to the public IP and the originating IP, if available. Using the CIDR notation, you will use octets to determine the subnet, so for example 54.0.0.0/8 means that the first number is represented by 8 bits, hence 8 after the slash. Then the second number would be another 8 bits, so you would write 54.12.0.0/16 (16 = 8 + 8), and you could do the same for the third number, for example 54.12.34.0/24 (24 = 8 + 8 + 8).", 'wp-slimstat' ) ),
|
151 |
-
'ignore_countries' => array( 'description' => __( 'Countries', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "Country codes (i.e.: <code>en-us, it, es</code>) that you don't want to track.", 'wp-slimstat' ) ),
|
152 |
-
'ignore_browsers' => array('description' => __( 'User Agents', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "Browsers (user agents) you don't want to track. You can specify the browser's version adding a slash after the name (i.e. <em>Firefox/3.6</em>). Wildcards: <code>*</code> matches 'any string, including the empty string', <code>!</code> matches 'any character'. For example, <code>Chr*</code> will match Chrome and Chromium, <code>IE/!.0</code> will match IE/7.0 and IE/8.0. Strings are case-insensitive.", 'wp-slimstat' ) ),
|
153 |
-
'ignore_platforms' => array( 'description' => __( 'Operating Systems', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "Operating system codes you don't want to track. Please refer to <a href='https://slimstat.freshdesk.com/solution/articles/12000031504-what-are-the-operating-system-codes-used-by-slimstat-' target='_blank'>this page</a> in our knowledge base to learn more about what codes you can use. Usual rules for using wildcards apply (see fields here above).", 'wp-slimstat' ) ),
|
154 |
-
'ignore_capabilities' => array( 'description' => __( 'Capabilities', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "Users having at least one of the <a href='http://codex.wordpress.org/Roles_and_Capabilities' target='_new'>capabilities</a> listed here below will not be tracked. Capabilities are case-insensitive.", 'wp-slimstat' ), 'skip_update' => true ),
|
155 |
-
|
156 |
-
'filters_pageview_header' => array( 'description' => __( 'Page Properties', 'wp-slimstat' ), 'type' => 'section_header' ),
|
157 |
-
'ignore_resources' => array( 'description' => __( 'Permalinks', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "List all the URLs on your website that you don't want to track. Don't include the domain name: <em>/about, ?p=1</em>, etc. Wildcards: <code>*</code> matches 'any string, including the empty string', <code>!</code> matches 'any character'. For example, <code>/abou*</code> will match /about and /abound, <code>/abo*t</code> will match /aboundant and /about, <code>/abo!t</code> will match /about and /abort. Strings are case-insensitive.", 'wp-slimstat' ) ),
|
158 |
-
'ignore_referers' => array( 'description' => __( 'Referring Sites', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "Referring URLs that you don't want to track: <code>http://mysite.com*</code>, <code>*/ignore-me-please</code>, etc. Wildcards: <code>*</code> matches 'any string, including the empty string', <code>!</code> matches 'any character'. Strings are case-insensitive. Please include either a wildcard or the protocol you want to filter (http://, https://).", 'wp-slimstat' ) ),
|
159 |
-
'ignore_content_types' => array( 'description' => __( 'Content Types', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "Slimstat categorizes pageviews by the associated WordPress content type: post, page, attachment, tag, 404, taxonomy, author, archive, search, feed, login and others. You can use this field to avoid tracking pages whose content type matches the ones you set here below.", 'wp-slimstat' ) )
|
160 |
-
)
|
161 |
-
),
|
162 |
-
|
163 |
-
4 => array(
|
164 |
-
'title' => __( 'Reports', 'wp-slimstat' ),
|
165 |
-
'rows' => array(
|
166 |
-
'reports_basic_header' => array( 'description' => __( 'Data Formats and Conversion', 'wp-slimstat' ), 'type' => 'section_header' ),
|
167 |
-
'use_european_separators' => array( 'description' => __( 'Number Format', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Choose the number format you want to use for your reports.','wp-slimstat' ), 'custom_label_on' => '1.234,5', 'custom_label_off' => '1,234.5' ),
|
168 |
-
'date_format' => array('description' => __('Date Format','wp-slimstat'), 'type' => 'text', 'long_description' => __("<a href='http://php.net/manual/en/function.date.php' target='_blank'>PHP Format</a> to use when displaying a pageview's date.", 'wp-slimstat')),
|
169 |
-
'time_format' => array('description' => __('Time Format','wp-slimstat'), 'type' => 'text', 'long_description' => __("<a href='http://php.net/manual/en/function.date.php' target='_blank'>PHP Format</a> to use when displaying a pageview's time.", 'wp-slimstat')),
|
170 |
-
'show_display_name' => array('description' => __('Use Display Name','wp-slimstat'), 'type' => 'toggle', 'long_description' => __('By default, users are listed by their usernames. Use this option to visualize their display names instead.','wp-slimstat')),
|
171 |
-
'convert_resource_urls_to_titles' => array('description' => __('Use Titles','wp-slimstat'), 'type' => 'toggle', 'long_description' => __('Slimstat converts your permalinks into post, page and category titles. Disable this feature if you need to see the URL in your reports.', 'wp-slimstat')),
|
172 |
-
'convert_ip_addresses' => array('description' => __('Convert IP Addresses','wp-slimstat'), 'type' => 'toggle', 'long_description' => __('Display provider names instead of IP addresses.','wp-slimstat')),
|
173 |
-
|
174 |
-
'reports_functionality_header' => array( 'description' => __( 'Functionality', 'wp-slimstat' ), 'type' => 'section_header' ),
|
175 |
-
'async_load' => array( 'description' => __( 'Async Mode', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Activate this feature if your reports take a while to load. It breaks down the load on your server into multiple requests, thus avoiding memory issues and performance problems.', 'wp-slimstat' ) ),
|
176 |
-
'use_current_month_timespan' => array( 'description' => __( 'Default Time Span', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Determine what is the default time period for calculating all the data in each report: current month or past given number of days. The number of days is defined under Basic > Report Interval. You can always use the time filter dropdown to customize this value even further.', 'wp-slimstat' ), 'custom_label_on' => 'Month', 'custom_label_off' => 'Days' ),
|
177 |
-
'expand_details' => array('description' => __('Expand Details','wp-slimstat'), 'type' => 'toggle', 'long_description' => __("Expand each row's details by default, insted of on mousehover.",'wp-slimstat')),
|
178 |
-
'rows_to_show' => array('description' => __('Rows to Display','wp-slimstat'), 'type' => 'integer', 'long_description' => __('Specify the number of items in each report.','wp-slimstat')),
|
179 |
-
'limit_results' => array( 'description' => __( 'Max Results','wp-slimstat' ), 'type' => 'integer', 'long_description' => __( 'Decide how many records should be retrieved from the database in total. Depending on your server configuration, you may want to fine tune this value to avoid exceeding your PHP memory limit.', 'wp-slimstat' ) ),
|
180 |
-
'ip_lookup_service' => array('description' => __( 'IP Lookup', 'wp-slimstat' ), 'type' => 'text', 'long_description' => __( 'Customize the Geolocation service to be used in the reports. Default: <code>http://www.infosniper.net/?ip_address=</code>', 'wp-slimstat' ) ),
|
181 |
-
'mozcom_access_id' => array('description' => __( 'Mozscape Access ID', 'wp-slimstat' ), 'type' => 'text', 'long_description' => __( 'Get accurate rankings for your website through the free <a href="https://moz.com/community/join?redirect=/products/api/keys" target="_blank">Mozscape API</a> service. Sign up for a free community account to get started. Then enter your personal identification code here.', 'wp-slimstat' ) ),
|
182 |
-
'mozcom_secret_key' => array('description' => __( 'Mozscape Secret Key', 'wp-slimstat' ), 'type' => 'text', 'long_description' => __( 'Do not share your secret key with anyone or they will be able to make API requests on your account!', 'wp-slimstat' ) ),
|
183 |
-
|
184 |
-
'reports_right_now_header' => array( 'description' => __( 'Access Log and World Map', 'wp-slimstat' ), 'type' => 'section_header' ),
|
185 |
-
'refresh_interval' => array( 'description' => __( 'Auto Refresh', 'wp-slimstat' ), 'type' => 'integer', 'long_description' => __( 'Enable the Live View, which refreshes the Access Log every X seconds. Enter <strong>0</strong> (number zero) to deactivate this feature.', 'wp-slimstat' ), 'after_input_field' => __( 'seconds', 'wp-slimstat' ) ),
|
186 |
-
'number_results_raw_data' => array('description' => __( 'Rows to Display', 'wp-slimstat'), 'type' => 'integer', 'long_description' => __( 'Specify the number of items in the Access Log.', 'wp-slimstat' ) ),
|
187 |
-
'max_dots_on_map' => array('description' => __( 'Map Data Points', 'wp-slimstat'), 'type' => 'integer', 'long_description' => __( 'Customize the maximum number of dots displayed on the world map. Please note that large numbers might increase the amount of time needed to render the map.', 'wp-slimstat' ) ),
|
188 |
-
|
189 |
-
'reports_miscellaneous_header' => array('description' => __('Miscellaneous','wp-slimstat'), 'type' => 'section_header'),
|
190 |
-
'custom_css' => array( 'description' => __( 'Custom CSS', 'wp-slimstat' ), 'type' => 'textarea', 'rows' => 8, 'long_description' => __( "Paste here your custom stylesheet to personalize the way your reports look. <a href='https://slimstat.freshdesk.com/support/solutions/articles/5000528528-how-can-i-change-the-colors-associated-to-color-coded-pageviews-known-user-known-visitors-search-e' target='_blank'>Check the FAQ</a> for more information on how to use this setting.", 'wp-slimstat' ), 'use_tag_list' => false ),
|
191 |
-
'chart_colors' => array('description' => __('Chart Colors','wp-slimstat'), 'type' => 'textarea', 'long_description' => __("Customize the look and feel of your charts by assigning personalized colors to each metric. List 4 hex colors, strictly in the following order: metric 1 previous, metric 2 previous, metric 1 current, metric 2 current. For example: <code>#ccc, #999, #bbcc44, #21759b</code>.",'wp-slimstat')),
|
192 |
-
'
|
193 |
-
'
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
'
|
200 |
-
|
201 |
-
'
|
202 |
-
'
|
203 |
-
'
|
204 |
-
|
205 |
-
|
206 |
-
'
|
207 |
-
'
|
208 |
-
|
209 |
-
|
210 |
-
'
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
'
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
)
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
}
|
232 |
-
|
233 |
-
|
234 |
-
echo '<div class="
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
wp_slimstat_admin::
|
243 |
-
|
244 |
-
|
|
|
245 |
echo '</div>';
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Avoid direct access to this piece of code
|
4 |
+
if ( !function_exists( 'add_action' ) ) {
|
5 |
+
exit(0);
|
6 |
+
}
|
7 |
+
|
8 |
+
if ( isset( $_POST[ 'options' ][ 'ignore_capabilities' ] ) ) {
|
9 |
+
// Make sure all the capabilities exist in the system
|
10 |
+
$capability_not_found = false;
|
11 |
+
foreach( wp_slimstat::string_to_array( $_POST[ 'options' ][ 'ignore_capabilities' ] ) as $a_capability ) {
|
12 |
+
if ( isset( $GLOBALS[ 'wp_roles' ]->role_objects[ 'administrator' ]->capabilities ) && !array_key_exists( $a_capability, $GLOBALS[ 'wp_roles' ]->role_objects[ 'administrator' ]->capabilities ) ) {
|
13 |
+
$capability_not_found = true;
|
14 |
+
break;
|
15 |
+
}
|
16 |
+
}
|
17 |
+
|
18 |
+
if ( !$capability_not_found ) {
|
19 |
+
wp_slimstat::$settings[ 'ignore_capabilities' ] = $_POST[ 'options' ][ 'ignore_capabilities' ];
|
20 |
+
}
|
21 |
+
else{
|
22 |
+
wp_slimstat_admin::$faulty_fields[] = __( 'Invalid capability. Please check <a href="http://codex.wordpress.org/Roles_and_Capabilities" target="_new">this page</a> for more information', 'wp-slimstat' );
|
23 |
+
}
|
24 |
+
}
|
25 |
+
|
26 |
+
if ( isset( $_POST[ 'options' ][ 'can_view' ] ) ) {
|
27 |
+
// Make sure all the users exist in the system
|
28 |
+
$post_data = trim( $_POST[ 'options' ][ 'can_view' ] );
|
29 |
+
$user_array = wp_slimstat::string_to_array( $_POST[ 'options' ][ 'can_view' ] );
|
30 |
+
|
31 |
+
if ( !empty( $post_data ) ) {
|
32 |
+
$sql_user_placeholders = implode( ', ', array_fill( 0, count( $user_array ), '%s' ) );
|
33 |
+
if ( $GLOBALS[ 'wpdb' ]->get_var( $GLOBALS[ 'wpdb' ]->prepare( "SELECT COUNT( * ) FROM {$GLOBALS[ 'wpdb' ]->users} WHERE user_login IN ( $sql_user_placeholders )", $user_array ) ) == count( $user_array ) ) {
|
34 |
+
wp_slimstat::$settings[ 'can_view' ] = $_POST[ 'options' ][ 'can_view' ];
|
35 |
+
}
|
36 |
+
else{
|
37 |
+
wp_slimstat_admin::$faulty_fields[] = __( 'Read access: username not found', 'wp-slimstat' );
|
38 |
+
}
|
39 |
+
}
|
40 |
+
else {
|
41 |
+
wp_slimstat::$settings[ 'can_view' ] = '';
|
42 |
+
}
|
43 |
+
}
|
44 |
+
|
45 |
+
if ( isset( $_POST[ 'options' ][ 'capability_can_view' ] ) ) {
|
46 |
+
if ( isset( $GLOBALS[ 'wp_roles' ]->role_objects[ 'administrator' ]->capabilities ) && array_key_exists( $_POST[ 'options' ][ 'capability_can_view' ], $GLOBALS[ 'wp_roles' ]->role_objects[ 'administrator' ]->capabilities ) ) {
|
47 |
+
wp_slimstat::$settings[ 'capability_can_view' ] = $_POST[ 'options' ][ 'capability_can_view' ];
|
48 |
+
}
|
49 |
+
else{
|
50 |
+
wp_slimstat_admin::$faulty_fields[] = __( 'Invalid capability. Please check <a href="http://codex.wordpress.org/Roles_and_Capabilities" target="_new">this page</a> for more information', 'wp-slimstat' );
|
51 |
+
}
|
52 |
+
}
|
53 |
+
|
54 |
+
if ( isset( $_POST[ 'options' ][ 'can_admin' ] ) ) {
|
55 |
+
// Make sure all the users exist in the system
|
56 |
+
$post_data = trim( $_POST[ 'options' ][ 'can_admin' ] );
|
57 |
+
$user_array = wp_slimstat::string_to_array( $_POST[ 'options' ][ 'can_admin' ] );
|
58 |
+
|
59 |
+
if ( is_array( $user_array ) && !empty( $post_data ) ) {
|
60 |
+
$sql_user_placeholders = implode( ', ', array_fill( 0, count( $user_array ), '%s' ) );
|
61 |
+
if ( $GLOBALS[ 'wpdb' ]->get_var( $GLOBALS[ 'wpdb' ]->prepare( "SELECT COUNT( * ) FROM {$GLOBALS[ 'wpdb' ]->users} WHERE user_login IN ( $sql_user_placeholders )", $user_array ) ) == count( $user_array ) ) {
|
62 |
+
wp_slimstat::$settings[ 'can_admin' ] = $_POST[ 'options' ][ 'can_admin' ];
|
63 |
+
}
|
64 |
+
else{
|
65 |
+
wp_slimstat_admin::$faulty_fields[] = __( 'Config access: username not found', 'wp-slimstat' );
|
66 |
+
}
|
67 |
+
}
|
68 |
+
}
|
69 |
+
|
70 |
+
if ( isset( $_POST[ 'options' ][ 'capability_can_admin' ] ) ) {
|
71 |
+
if ( isset( $GLOBALS[ 'wp_roles' ]->role_objects[ 'administrator' ]->capabilities ) && array_key_exists( $_POST[ 'options' ][ 'capability_can_admin' ], $GLOBALS[ 'wp_roles' ]->role_objects[ 'administrator' ]->capabilities ) ) {
|
72 |
+
wp_slimstat::$settings[ 'capability_can_admin' ] = $_POST[ 'options' ][ 'capability_can_admin' ];
|
73 |
+
}
|
74 |
+
else{
|
75 |
+
wp_slimstat_admin::$faulty_fields[] = __( 'Invalid capability. Please check <a href="http://codex.wordpress.org/Roles_and_Capabilities" target="_new">this page</a> for more information', 'wp-slimstat' );
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
$current_tab = empty( $_GET[ 'tab' ] ) ? 1 : intval( $_GET[ 'tab' ] );
|
80 |
+
|
81 |
+
// Define all the options
|
82 |
+
$settings = array(
|
83 |
+
1 => array(
|
84 |
+
'title' => __( 'Basic', 'wp-slimstat' ),
|
85 |
+
'rows' => array(
|
86 |
+
'general_tracking_header' => array( 'description' => __( 'Tracker', 'wp-slimstat' ), 'type' => 'section_header' ),
|
87 |
+
'is_tracking' => array( 'description' => __( 'Enable Tracking', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Turn the tracker on or off, while keeping the reports accessible.', 'wp-slimstat' ) ),
|
88 |
+
'javascript_mode' => array( 'description' => __( 'Tracking Mode', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __('Select <strong>Client</strong> if you are using a caching plugin (W3 Total Cache, WP SuperCache, HyperCache, etc). Slimstat will behave pretty much like Google Analytics, and visitors whose browser does not support Javascript will be ignored. A nice side effect is that <strong>most spammers, search engines and other crawlers</strong> will not be tracked.','wp-slimstat'), 'custom_label_on' => __('Client','wp-slimstat'), 'custom_label_off' => __('Server','wp-slimstat') ),
|
89 |
+
'enable_javascript' => array( 'description' => __( 'Track Client Info', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "If this option is turned off, the tracker will not be collecting information such as screen resolution, outbound links, downloads, etc. This option is ignored if Tracking Mode is set to Client.", 'wp-slimstat' ) ),
|
90 |
+
'track_admin_pages' => array( 'description' => __( 'Track Admin Pages', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "Enable this option to track your users' activity within the admin.", 'wp-slimstat') ),
|
91 |
+
|
92 |
+
'general_integration_header' => array( 'description' => __( 'WordPress Integration', 'wp-slimstat' ), 'type' => 'section_header' ),
|
93 |
+
'add_dashboard_widgets' => array( 'description' => __( 'Dashboard Widgets', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Enable this option if you want to add reports to your WordPress Dashboard. Use the Customizer to choose which ones to display.', 'wp-slimstat' ) ),
|
94 |
+
'use_separate_menu' => array( 'description' => __( 'Menu Position', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Choose between a standalone admin menu for Slimstat or a drop down in the admin bar (if visible).', 'wp-slimstat' ), 'custom_label_on' => __( 'Side', 'wp-slimstat' ), 'custom_label_off' => __( 'Bar', 'wp-slimstat' ) ),
|
95 |
+
'posts_column_day_interval' => array( 'description' => __('Report Interval','wp-slimstat'), 'type' => 'integer', 'long_description' => __('Enter the time range, in days, that should be used to count the number of pageviews on Posts/Pages (see option here below) and for the Default Time Span option under the Reports tab.','wp-slimstat') ),
|
96 |
+
'add_posts_column' => array( 'description' => __('Posts and Pages','wp-slimstat'), 'type' => 'toggle', 'long_description' => __('Add a new column to the Edit Posts/Pages screens, with the number of hits per post within the timeframe specified here below.','wp-slimstat') ),
|
97 |
+
|
98 |
+
'posts_column_pageviews' => array( 'description' => __( 'Report Type','wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Select what kind of information you would like to see displayed on your Posts admin screen. Hits counts all the pageviews regardless of the user, (unique) IPs counts only one hit per IP in the given time range.', 'wp-slimstat' ), 'custom_label_on' => __( 'Hits', 'wp-slimstat' ), 'custom_label_off' => __( 'IPs', 'wp-slimstat' ) ),
|
99 |
+
'hide_addons' => array( 'description' => __( 'Hide Add-ons', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Enable this option to hide all your <strong>active</strong> premium add-ons from the list of plugins in WordPress. Please note that you will still receive updates for hidden add-ons.', 'wp-slimstat' ) ),
|
100 |
+
|
101 |
+
'general_database_header' => array('description' => __('Database','wp-slimstat'), 'type' => 'section_header'),
|
102 |
+
'auto_purge' => array( 'description' => __( 'Retain data for', 'wp-slimstat' ), 'type' => 'integer', 'long_description' => __( "Clean-up log entries older than the number of days specified here above. Enter <strong>0</strong> (number zero) if you want to preserve your data in the main table (neither archive it nor delete it) regardless of its age.", 'wp-slimstat' ).( (wp_slimstat::$settings[ 'auto_purge' ] > 0)?' '.__('Next clean-up on','wp-slimstat').' <strong>'.date_i18n(get_option('date_format').', '.get_option('time_format'), wp_next_scheduled( 'wp_update_plugins' ) ) . '</strong>. '.sprintf(__('Entries logged on or before %s will be archived or deleted according to the option here below.','wp-slimstat'), date_i18n(get_option('date_format'), strtotime('-'.wp_slimstat::$settings['auto_purge'].' days'))):''), 'after_input_field' => __('days','wp-slimstat') ),
|
103 |
+
'auto_purge_delete' => array( 'description' => __( 'Archive records', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'If DB space is not an issue, you can decide to archive older records in another table, instead of deleting them. This way performance is preserved, but you will still be able to access your data at a later time, if needed. Please note that the archive table (<code>wp_slim_stats_archive</code>) will be <strong>deleted</strong> along with all the other tables, when Slimstat is uninstalled. Make sure to backup your data before you proceed.', 'wp-slimstat' ) )
|
104 |
+
)
|
105 |
+
),
|
106 |
+
|
107 |
+
2 => array(
|
108 |
+
'title' => __( 'Tracker', 'wp-slimstat' ),
|
109 |
+
'rows' => array(
|
110 |
+
'filters_outbound_header' => array( 'description' => __( 'Link Tracking', 'wp-slimstat' ), 'type' => 'section_header' ),
|
111 |
+
'do_not_track_outbound_classes_rel_href' => array( 'description' => __( 'Do Not Track', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "Slimstat will ignore links marked with one of these class names, <em>rel</em> attributes or whose <em>href</em> attribute contains one of these strings. Please keep in mind that the class <code>noslimstat</code> is also used to avoid tracking interactive links throughout the reports. If you remove it from this list, some features might not work as expected.", 'wp-slimstat' ) ),
|
112 |
+
'extensions_to_track' => array( 'description' => __( 'Downloads', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( 'List all the file extensions that you want to be treated as Downloads. Please note that links pointing to external resources (i.e. PDFs on an external website) are considered Downloads and not Outbound Links (and tracked as such), if their extension matches one of the ones listed here below.', 'wp-slimstat' ) ),
|
113 |
+
'track_same_domain_referers' => array( 'description' => __( 'Same-Domain Referrers', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'By default, when the domain of the referrer for a given page view is the same as the current site, that information is not tracked to save space in the database. However, if you are running a multisite network with subfolders, you might need to track same-domain referrers from one site to another, as they are technically "separate" websites.', 'wp-slimstat' ) ),
|
114 |
+
|
115 |
+
'advanced_tracker_header' => array( 'description' => __( 'Advanced Options', 'wp-slimstat' ), 'type' => 'section_header' ),
|
116 |
+
'geolocation_country' => array( 'description' => __( 'Geolocation Precision', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "When Slimstat determines your visitors' Country of origin, it uses a third-party data file <a href='https://dev.maxmind.com/geoip/geoip2/geolite2/' target='_blank'>provided by MaxMind</a>. They offer two precision levels: country and city. By default, Slimstat will install the smaller one (country), and you can decide to use the other one, if you don't mind its 60 Mb average size. After you change this option, please <strong>go to the Maintenance tab</strong> and reload (uninstall/install) the MaxMind GeoLite DB by clicking on the corresponding button.", 'wp-slimstat' ), 'custom_label_on' => __( 'Country', 'wp-slimstat' ), 'custom_label_off' => __( 'City', 'wp-slimstat' ) ),
|
117 |
+
'session_duration' => array('description' => __( 'Session Duration', 'wp-slimstat' ), 'type' => 'integer', 'long_description' => __( 'How many seconds should a human session last? Google Analytics sets it to 1800 seconds.', 'wp-slimstat' ), 'after_input_field' => __( 'seconds', 'wp-slimstat' ) ),
|
118 |
+
'extend_session' => array( 'description' => __( 'Extend Session', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Extend the duration of a session each time the user visits a new page.', 'wp-slimstat' ) ),
|
119 |
+
'set_tracker_cookie' => array( 'description' => __( 'Set Cookie', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Disable this option if, for legal or security reasons, you do not want Slimstat to assign a <a href="https://en.wikipedia.org/wiki/HTTP_cookie" target="_blank">cookie</a> to your visitors. Please note that, by deactivating this feature, Slimstat will not keep track of returning visitors and sessions.', 'wp-slimstat' ) ),
|
120 |
+
'enable_cdn' => array( 'description' => __( 'Enable CDN', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "Use <a href='http://www.jsdelivr.com/' target='_blank'>JSDelivr</a>'s CDN, by serving our tracking code from their fast and reliable network (free service).", 'wp-slimstat' ) ),
|
121 |
+
'ajax_relative_path' => array( 'description' => __( 'Relative Ajax', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'If you are experiencing issues related to the header field X-Requested-With not being allowed by Access-Control-Allow-Headers in preflight response (or similar), try enabling this option to make that <code>admin-ajax.php</code> URL relative.', 'wp-slimstat' ) ),
|
122 |
+
|
123 |
+
'advanced_external_pages_header' => array('description' => __('External Pages','wp-slimstat'), 'type' => 'section_header'),
|
124 |
+
'external_pages_script' => array('type' => 'static', 'skip_update' => 'yes', 'description' => __('Add the following code to all the non-WP pages you want to track, right before the closing BODY tag. Please make sure to change the protocol of all the URLs to HTTPS, if you external site is served over a secure channel.','wp-slimstat'), 'long_description' => '<script type="text/javascript">
|
125 |
+
/* <![CDATA[ */
|
126 |
+
var SlimStatParams = {
|
127 |
+
ajaxurl: "'.admin_url('admin-ajax.php').'",
|
128 |
+
ci: "YTo0OntzOjEyOiJjb250ZW50X3R5cGUiO3M6ODoiZXh0ZXJuYWwiO3M6ODoiY2F0ZWdvcnkiO3M6MDoiIjtzOjEwOiJjb250ZW50X2lkIjtpOjA7czo2OiJhdXRob3IiO3M6MTM6ImV4dGVybmFsLXBhZ2UiO30=.' . md5('YTo0OntzOjEyOiJjb250ZW50X3R5cGUiO3M6ODoiZXh0ZXJuYWwiO3M6ODoiY2F0ZWdvcnkiO3M6MDoiIjtzOjEwOiJjb250ZW50X2lkIjtpOjA7czo2OiJhdXRob3IiO3M6MTM6ImV4dGVybmFsLXBhZ2UiO30=' . wp_slimstat::$settings[ 'secret' ] ).'",
|
129 |
+
extensions_to_track: "'.wp_slimstat::$settings['extensions_to_track'].'"
|
130 |
+
};
|
131 |
+
/* ]]> */
|
132 |
+
</script>
|
133 |
+
<script type="text/javascript" src="http://cdn.jsdelivr.net/wp/wp-slimstat/trunk/wp-slimstat.min.js"></script>', 'use_tag_list' => false ),
|
134 |
+
'external_domains' => array('description' => __('Allow Domains','wp-slimstat'), 'type' => 'textarea', 'long_description' => __("If you are getting an error saying that no 'Access-Control-Allow-Origin' header is present on the requested resource, when using the external tracking code here above, list the domains (complete with scheme) you would like to allow. For example: <code>http://my.domain.ext</code> (no trailing slash). Please see <a href='http://www.w3.org/TR/cors/#security' target='_blank'>this W3 resource</a> for more information on the security implications of allowing CORS requests.",'wp-slimstat'))
|
135 |
+
)
|
136 |
+
),
|
137 |
+
|
138 |
+
3 => array(
|
139 |
+
'title' => __( 'Filters', 'wp-slimstat' ),
|
140 |
+
'rows' => array(
|
141 |
+
'filters_categories_header' => array( 'description' => __( 'Profiling', 'wp-slimstat' ), 'type' => 'section_header' ),
|
142 |
+
'track_users' => array( 'description' => __( 'Track WP Users', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Enable this option to track logged in users.', 'wp-slimstat' ) ),
|
143 |
+
'ignore_spammers' => array( 'description' => __( 'Ignore Spammers', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "Enable this option if you don't want to track visits from users identified as spammers by third-party tools like Akismet. Pageviews generated by users whose comments are later marked as spam, will also be removed from the database.", 'wp-slimstat' ) ),
|
144 |
+
'ignore_bots' => array( 'description' => __( 'Ignore Bots', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "Turn on this feature if you want to have the accuracy level of server-side tracking, but not the inconvenience of getting your database clogged with pageviews generated by crawlers, spiders, search engine bots, etc. Please note that in Client mode, bots are ignored regardless of this setting.", 'wp-slimstat' ) ),
|
145 |
+
'ignore_prefetch' => array( 'description' => __( 'Ignore Prefetch Requests', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "Prevent Slimstat from tracking pageviews generated by Firefox's <a href='https://developer.mozilla.org/en/Link_prefetching_FAQ' target='_blank'>Link Prefetching functionality</a>.", 'wp-slimstat' ) ),
|
146 |
+
'anonymize_ip' => array( 'description' => __( 'Enable Privacy Mode', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( "Mask your visitors' IP addresses to comply with European Privacy Laws.", 'wp-slimstat' ) ),
|
147 |
+
|
148 |
+
'filters_users_header' => array( 'description' => __( 'User Properties', 'wp-slimstat' ), 'type' => 'section_header' ),
|
149 |
+
'ignore_users' => array( 'description' => __( 'Usernames', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "List all the usernames you don't want to track. Please be aware that spaces are <em>not</em> ignored and that usernames are case sensitive. Wildcards: <code>*</code> matches 'any string, including the empty string', <code>!</code> matches 'any character'. For example, <code>user*</code> will match user12 and userfoo, <code>u*100</code> will match user100 and uber100, <code>user!0</code> will match user10 and user90.", 'wp-slimstat' ) ),
|
150 |
+
'ignore_ip' => array( 'description' => __( 'IP Addresses', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "List all the IP addresses you don't want to track. Each subnet <strong>must</strong> be defined using the <a href='https://www.iplocation.net/subnet-mask' target='_blank'>CIDR notation</a> (i.e. <em>192.168.0.0/24</em>). This filter applies both to the public IP and the originating IP, if available. Using the CIDR notation, you will use octets to determine the subnet, so for example 54.0.0.0/8 means that the first number is represented by 8 bits, hence 8 after the slash. Then the second number would be another 8 bits, so you would write 54.12.0.0/16 (16 = 8 + 8), and you could do the same for the third number, for example 54.12.34.0/24 (24 = 8 + 8 + 8).", 'wp-slimstat' ) ),
|
151 |
+
'ignore_countries' => array( 'description' => __( 'Countries', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "Country codes (i.e.: <code>en-us, it, es</code>) that you don't want to track.", 'wp-slimstat' ) ),
|
152 |
+
'ignore_browsers' => array('description' => __( 'User Agents', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "Browsers (user agents) you don't want to track. You can specify the browser's version adding a slash after the name (i.e. <em>Firefox/3.6</em>). Wildcards: <code>*</code> matches 'any string, including the empty string', <code>!</code> matches 'any character'. For example, <code>Chr*</code> will match Chrome and Chromium, <code>IE/!.0</code> will match IE/7.0 and IE/8.0. Strings are case-insensitive.", 'wp-slimstat' ) ),
|
153 |
+
'ignore_platforms' => array( 'description' => __( 'Operating Systems', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "Operating system codes you don't want to track. Please refer to <a href='https://slimstat.freshdesk.com/solution/articles/12000031504-what-are-the-operating-system-codes-used-by-slimstat-' target='_blank'>this page</a> in our knowledge base to learn more about what codes you can use. Usual rules for using wildcards apply (see fields here above).", 'wp-slimstat' ) ),
|
154 |
+
'ignore_capabilities' => array( 'description' => __( 'Capabilities', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "Users having at least one of the <a href='http://codex.wordpress.org/Roles_and_Capabilities' target='_new'>capabilities</a> listed here below will not be tracked. Capabilities are case-insensitive.", 'wp-slimstat' ), 'skip_update' => true ),
|
155 |
+
|
156 |
+
'filters_pageview_header' => array( 'description' => __( 'Page Properties', 'wp-slimstat' ), 'type' => 'section_header' ),
|
157 |
+
'ignore_resources' => array( 'description' => __( 'Permalinks', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "List all the URLs on your website that you don't want to track. Don't include the domain name: <em>/about, ?p=1</em>, etc. Wildcards: <code>*</code> matches 'any string, including the empty string', <code>!</code> matches 'any character'. For example, <code>/abou*</code> will match /about and /abound, <code>/abo*t</code> will match /aboundant and /about, <code>/abo!t</code> will match /about and /abort. Strings are case-insensitive.", 'wp-slimstat' ) ),
|
158 |
+
'ignore_referers' => array( 'description' => __( 'Referring Sites', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "Referring URLs that you don't want to track: <code>http://mysite.com*</code>, <code>*/ignore-me-please</code>, etc. Wildcards: <code>*</code> matches 'any string, including the empty string', <code>!</code> matches 'any character'. Strings are case-insensitive. Please include either a wildcard or the protocol you want to filter (http://, https://).", 'wp-slimstat' ) ),
|
159 |
+
'ignore_content_types' => array( 'description' => __( 'Content Types', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "Slimstat categorizes pageviews by the associated WordPress content type: post, page, attachment, tag, 404, taxonomy, author, archive, search, feed, login and others. You can use this field to avoid tracking pages whose content type matches the ones you set here below.", 'wp-slimstat' ) )
|
160 |
+
)
|
161 |
+
),
|
162 |
+
|
163 |
+
4 => array(
|
164 |
+
'title' => __( 'Reports', 'wp-slimstat' ),
|
165 |
+
'rows' => array(
|
166 |
+
'reports_basic_header' => array( 'description' => __( 'Data Formats and Conversion', 'wp-slimstat' ), 'type' => 'section_header' ),
|
167 |
+
'use_european_separators' => array( 'description' => __( 'Number Format', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Choose the number format you want to use for your reports.','wp-slimstat' ), 'custom_label_on' => '1.234,5', 'custom_label_off' => '1,234.5' ),
|
168 |
+
'date_format' => array('description' => __('Date Format','wp-slimstat'), 'type' => 'text', 'long_description' => __("<a href='http://php.net/manual/en/function.date.php' target='_blank'>PHP Format</a> to use when displaying a pageview's date.", 'wp-slimstat')),
|
169 |
+
'time_format' => array('description' => __('Time Format','wp-slimstat'), 'type' => 'text', 'long_description' => __("<a href='http://php.net/manual/en/function.date.php' target='_blank'>PHP Format</a> to use when displaying a pageview's time.", 'wp-slimstat')),
|
170 |
+
'show_display_name' => array('description' => __('Use Display Name','wp-slimstat'), 'type' => 'toggle', 'long_description' => __('By default, users are listed by their usernames. Use this option to visualize their display names instead.','wp-slimstat')),
|
171 |
+
'convert_resource_urls_to_titles' => array('description' => __('Use Titles','wp-slimstat'), 'type' => 'toggle', 'long_description' => __('Slimstat converts your permalinks into post, page and category titles. Disable this feature if you need to see the URL in your reports.', 'wp-slimstat')),
|
172 |
+
'convert_ip_addresses' => array('description' => __('Convert IP Addresses','wp-slimstat'), 'type' => 'toggle', 'long_description' => __('Display provider names instead of IP addresses.','wp-slimstat')),
|
173 |
+
|
174 |
+
'reports_functionality_header' => array( 'description' => __( 'Functionality', 'wp-slimstat' ), 'type' => 'section_header' ),
|
175 |
+
'async_load' => array( 'description' => __( 'Async Mode', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Activate this feature if your reports take a while to load. It breaks down the load on your server into multiple requests, thus avoiding memory issues and performance problems.', 'wp-slimstat' ) ),
|
176 |
+
'use_current_month_timespan' => array( 'description' => __( 'Default Time Span', 'wp-slimstat' ), 'type' => 'toggle', 'long_description' => __( 'Determine what is the default time period for calculating all the data in each report: current month or past given number of days. The number of days is defined under Basic > Report Interval. You can always use the time filter dropdown to customize this value even further.', 'wp-slimstat' ), 'custom_label_on' => 'Month', 'custom_label_off' => 'Days' ),
|
177 |
+
'expand_details' => array('description' => __('Expand Details','wp-slimstat'), 'type' => 'toggle', 'long_description' => __("Expand each row's details by default, insted of on mousehover.",'wp-slimstat')),
|
178 |
+
'rows_to_show' => array('description' => __('Rows to Display','wp-slimstat'), 'type' => 'integer', 'long_description' => __('Specify the number of items in each report.','wp-slimstat')),
|
179 |
+
'limit_results' => array( 'description' => __( 'Max Results','wp-slimstat' ), 'type' => 'integer', 'long_description' => __( 'Decide how many records should be retrieved from the database in total. Depending on your server configuration, you may want to fine tune this value to avoid exceeding your PHP memory limit.', 'wp-slimstat' ) ),
|
180 |
+
'ip_lookup_service' => array('description' => __( 'IP Lookup', 'wp-slimstat' ), 'type' => 'text', 'long_description' => __( 'Customize the Geolocation service to be used in the reports. Default: <code>http://www.infosniper.net/?ip_address=</code>', 'wp-slimstat' ) ),
|
181 |
+
'mozcom_access_id' => array('description' => __( 'Mozscape Access ID', 'wp-slimstat' ), 'type' => 'text', 'long_description' => __( 'Get accurate rankings for your website through the free <a href="https://moz.com/community/join?redirect=/products/api/keys" target="_blank">Mozscape API</a> service. Sign up for a free community account to get started. Then enter your personal identification code here.', 'wp-slimstat' ) ),
|
182 |
+
'mozcom_secret_key' => array('description' => __( 'Mozscape Secret Key', 'wp-slimstat' ), 'type' => 'text', 'long_description' => __( 'Do not share your secret key with anyone or they will be able to make API requests on your account!', 'wp-slimstat' ) ),
|
183 |
+
|
184 |
+
'reports_right_now_header' => array( 'description' => __( 'Access Log and World Map', 'wp-slimstat' ), 'type' => 'section_header' ),
|
185 |
+
'refresh_interval' => array( 'description' => __( 'Auto Refresh', 'wp-slimstat' ), 'type' => 'integer', 'long_description' => __( 'Enable the Live View, which refreshes the Access Log every X seconds. Enter <strong>0</strong> (number zero) to deactivate this feature.', 'wp-slimstat' ), 'after_input_field' => __( 'seconds', 'wp-slimstat' ) ),
|
186 |
+
'number_results_raw_data' => array('description' => __( 'Rows to Display', 'wp-slimstat'), 'type' => 'integer', 'long_description' => __( 'Specify the number of items in the Access Log.', 'wp-slimstat' ) ),
|
187 |
+
'max_dots_on_map' => array('description' => __( 'Map Data Points', 'wp-slimstat'), 'type' => 'integer', 'long_description' => __( 'Customize the maximum number of dots displayed on the world map. Please note that large numbers might increase the amount of time needed to render the map.', 'wp-slimstat' ) ),
|
188 |
+
|
189 |
+
'reports_miscellaneous_header' => array('description' => __('Miscellaneous','wp-slimstat'), 'type' => 'section_header'),
|
190 |
+
'custom_css' => array( 'description' => __( 'Custom CSS', 'wp-slimstat' ), 'type' => 'textarea', 'rows' => 8, 'long_description' => __( "Paste here your custom stylesheet to personalize the way your reports look. <a href='https://slimstat.freshdesk.com/support/solutions/articles/5000528528-how-can-i-change-the-colors-associated-to-color-coded-pageviews-known-user-known-visitors-search-e' target='_blank'>Check the FAQ</a> for more information on how to use this setting.", 'wp-slimstat' ), 'use_tag_list' => false ),
|
191 |
+
'chart_colors' => array( 'description' => __( 'Chart Colors', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "Customize the look and feel of your charts by assigning personalized colors to each metric. List 4 hex colors, strictly in the following order: metric 1 previous, metric 2 previous, metric 1 current, metric 2 current. For example: <code>#ccc, #999, #bbcc44, #21759b</code>.", 'wp-slimstat' ) ),
|
192 |
+
'comparison_chart' => array( 'description' => __( 'Comparison Chart', 'wp-slimstat'), 'type' => 'toggle', 'long_description' => __( "Disable this option if you find the four line charts confusing, and prefer seeing only the selected time range.", 'wp-slimstat' ) ),
|
193 |
+
'show_complete_user_agent_tooltip' => array('description' => __('Show User Agent','wp-slimstat'), 'type' => 'toggle', 'long_description' => __('Choose if you want to see the browser name or a complete user agent string when hovering over each browser icon.','wp-slimstat')),
|
194 |
+
'enable_sov' => array('description' => __('Enable SOV','wp-slimstat'), 'type' => 'toggle', 'long_description' => __('In linguistic typology, a subject-object-verb (SOV) language is one in which the subject, object, and verb of a sentence appear in that order, like in Japanese.','wp-slimstat'))
|
195 |
+
)
|
196 |
+
),
|
197 |
+
|
198 |
+
5 => array(
|
199 |
+
'title' => __( 'Access Control', 'wp-slimstat' ),
|
200 |
+
'rows' => array(
|
201 |
+
'permissions_reports_header' => array('description' => __('Reports','wp-slimstat'), 'type' => 'section_header'),
|
202 |
+
'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')),
|
203 |
+
'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')),
|
204 |
+
'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),
|
205 |
+
|
206 |
+
'permissions_config_header' => array('description' => __('Settings','wp-slimstat'), 'type' => 'section_header'),
|
207 |
+
'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')),
|
208 |
+
'can_admin' => array('description' => __('Whitelist','wp-slimstat'), 'type' => 'textarea', 'long_description' => __("List all the users who can edit these options. Please be advised that admins <strong>are not</strong> implicitly allowed, so do not forget to include yourself! Usernames are case sensitive.",'wp-slimstat'), 'skip_update' => true),
|
209 |
+
|
210 |
+
'rest_api_header' => array( 'description' => __( 'Rest API', 'wp-slimstat' ), 'type' => 'section_header' ),
|
211 |
+
'rest_api_tokens' => array( 'description' => __( 'Tokens', 'wp-slimstat' ), 'type' => 'textarea', 'long_description' => __( "In order to send requests to <a href='https://slimstat.freshdesk.com/support/solutions/articles/12000033661-slimstat-rest-api' target='_blank'>the Slimstat REST API</a>, you will need to pass a valid token to the endpoint (param ?token=XXX). Using the field here below, you can define as many tokens as you like, to distribute them to your API users. Please note: treat these tokens as passwords, as they will grant read access to your reports to anyone who knows them. Use a service like <a href='https://randomkeygen.com/#ci_key' target='_blank'>RandomKeyGen.com</a> to generate unique secure tokens.", 'wp-slimstat' ) )
|
212 |
+
)
|
213 |
+
),
|
214 |
+
|
215 |
+
6 => array(
|
216 |
+
'title' => __( 'Maintenance', 'wp-slimstat' ),
|
217 |
+
'include' => dirname(__FILE__).'/maintenance.php'
|
218 |
+
),
|
219 |
+
|
220 |
+
7 => array(
|
221 |
+
'title' => __( 'Add-ons', 'wp-slimstat' )
|
222 |
+
)
|
223 |
+
);
|
224 |
+
|
225 |
+
$settings = apply_filters( 'slimstat_options_on_page', $settings );
|
226 |
+
|
227 |
+
$tabs_html = '';
|
228 |
+
foreach ( $settings as $a_tab_id => $a_tab_info ) {
|
229 |
+
if ( !empty( $a_tab_info[ 'rows' ] ) || !empty( $a_tab_info[ 'include' ] ) ) {
|
230 |
+
$tabs_html .= "<li class='nav-tab nav-tab".(($current_tab == $a_tab_id)?'-active':'-inactive')."'><a href='".wp_slimstat_admin::$config_url.$a_tab_id."'>{$a_tab_info[ 'title' ]}</a></li>";
|
231 |
+
}
|
232 |
+
}
|
233 |
+
|
234 |
+
echo '<div class="wrap slimstat-config"><h2>'.__('Settings','wp-slimstat').'</h2><ul class="nav-tabs">'.$tabs_html.'</ul>';
|
235 |
+
echo '<div class="notice slimstat-notice slimstat-tooltip-content" style="background-color:#ffa;border:0;padding:10px">' . __( '<strong>AdBlock browser extension detected</strong> - If you see this notice, it means that your browser is not loading our stylesheet and/or Javascript files correctly. This could be caused by an overzealous ad blocker feature enabled in your browser (AdBlock Plus and friends). <a href="https://slimstat.freshdesk.com/support/solutions/articles/12000000414-the-reports-are-not-being-rendered-correctly-or-buttons-do-not-work" target="_blank">Please make sure to add an exception</a> to your configuration and allow the browser to load these assets.', 'wp-slimstat' ) . '</div>';
|
236 |
+
|
237 |
+
// The maintenance tab has its own separate file
|
238 |
+
if ( !empty( $settings[ $current_tab ][ 'include' ] ) ) {
|
239 |
+
include_once( $settings[ $current_tab ][ 'include' ] );
|
240 |
+
}
|
241 |
+
else if ( !empty( $settings[ $current_tab ][ 'rows' ] ) ) {
|
242 |
+
wp_slimstat_admin::update_settings( $settings[ $current_tab ][ 'rows' ] );
|
243 |
+
wp_slimstat_admin::display_settings( $settings[ $current_tab ][ 'rows' ], $current_tab );
|
244 |
+
}
|
245 |
+
|
246 |
echo '</div>';
|
admin/css/slimstat.css
CHANGED
@@ -1,764 +1,765 @@
|
|
1 |
-
/* Links */
|
2 |
-
.wrap.slimstat a, [id^=slim_] a{
|
3 |
-
outline: none;
|
4 |
-
text-decoration: none;
|
5 |
-
}
|
6 |
-
[id^=slim_] a.slimstat-delete-entry:before{
|
7 |
-
color: #e22;
|
8 |
-
}
|
9 |
-
.slimstat-float-right{
|
10 |
-
float: right;
|
11 |
-
}
|
12 |
-
|
13 |
-
/* Admin Notice */
|
14 |
-
.slimstat-notice{
|
15 |
-
overflow: hidden;
|
16 |
-
}
|
17 |
-
.slimstat-notice span{
|
18 |
-
width: 97%;
|
19 |
-
}
|
20 |
-
.slimstat-notice .fixed-height {
|
21 |
-
height: 120px;
|
22 |
-
margin-bottom: 20px;
|
23 |
-
overflow: auto;
|
24 |
-
padding: 0 20px 0 0;
|
25 |
-
}
|
26 |
-
|
27 |
-
/* Filters */
|
28 |
-
#slimstat-filters-post{
|
29 |
-
display: none;
|
30 |
-
}
|
31 |
-
#slimstat-filters-form{
|
32 |
-
background-color: #e0e0e0;
|
33 |
-
margin-top: 10px;
|
34 |
-
padding: 5px;
|
35 |
-
position: relative;
|
36 |
-
}
|
37 |
-
#slimstat-filters input.text, #slimstat-filters select{
|
38 |
-
vertical-align: initial;
|
39 |
-
width: 15%;
|
40 |
-
}
|
41 |
-
#slimstat-filters-form label {
|
42 |
-
left:-9000px;
|
43 |
-
position: absolute;
|
44 |
-
}
|
45 |
-
#slimstat-date-filters{
|
46 |
-
padding: 4px 10px 6px 20px;
|
47 |
-
position: absolute;
|
48 |
-
right: 5px;
|
49 |
-
top: 5px;
|
50 |
-
}
|
51 |
-
#slimstat-date-filters>a{
|
52 |
-
color: #fff;
|
53 |
-
white-space: nowrap;
|
54 |
-
}
|
55 |
-
#slimstat-date-filters>a::after{
|
56 |
-
content: "\f140";
|
57 |
-
font: normal 20px/1 'dashicons';
|
58 |
-
vertical-align: bottom;
|
59 |
-
}
|
60 |
-
#slimstat-date-filters>a.open::after{
|
61 |
-
content: "\f142";
|
62 |
-
}
|
63 |
-
#slimstat-date-filters .dropdown {
|
64 |
-
background-color: #fff;
|
65 |
-
box-shadow: 0 1px 8px rgba(0, 0, 0, 0.2);
|
66 |
-
color: #222;
|
67 |
-
display: none;
|
68 |
-
padding: 5px 0 5px 5px;
|
69 |
-
position: absolute;
|
70 |
-
right: -4px;
|
71 |
-
top: 35px;
|
72 |
-
width:
|
73 |
-
z-index: 120;
|
74 |
-
}
|
75 |
-
#slimstat-date-filters .dropdown #slimstat-quick-filters a {
|
76 |
-
background-color: #eee;
|
77 |
-
display: block;
|
78 |
-
float: left;
|
79 |
-
margin: 0 5px 5px 0;
|
80 |
-
padding: 5px;
|
81 |
-
width:
|
82 |
-
}
|
83 |
-
#slimstat-date-filters .dropdown strong{
|
84 |
-
clear: both;
|
85 |
-
display: block;
|
86 |
-
font-weight: normal;
|
87 |
-
padding: 10px 5px 5px 0;
|
88 |
-
text-transform: uppercase;
|
89 |
-
}
|
90 |
-
#slimstat-date-filters .dropdown select, #slimstat-date-filters .dropdown input{
|
91 |
-
margin
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
margin-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
border-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
-
|
240 |
-
-
|
241 |
-
transform: scaleX(-1);
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
background-
|
266 |
-
background-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
color: #
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
color:#
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
color:#
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
color:#
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
border
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
border
|
368 |
-
|
369 |
-
|
370 |
-
font-
|
371 |
-
font-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
border-
|
507 |
-
border-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
margin-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
font-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
}
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
}
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
}
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
src: url('slimstat.eot?58272494
|
697 |
-
|
698 |
-
|
699 |
-
font-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
url('data:application/octet-stream;base64,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') format('truetype');
|
705 |
-
}
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
font-
|
710 |
-
font-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
.slimstat-font-
|
727 |
-
.slimstat-font-
|
728 |
-
.slimstat-font-
|
729 |
-
.slimstat-font-
|
730 |
-
.slimstat-font-
|
731 |
-
.slimstat-font-
|
732 |
-
.slimstat-font-
|
733 |
-
.slimstat-font-
|
734 |
-
.slimstat-font-
|
735 |
-
.slimstat-font-
|
736 |
-
.slimstat-font-
|
737 |
-
.slimstat-font-
|
738 |
-
.slimstat-font-angle-
|
739 |
-
.slimstat-font-angle-
|
740 |
-
.slimstat-font-angle-double-
|
741 |
-
.slimstat-font-
|
742 |
-
.slimstat-font-
|
743 |
-
.slimstat-font-
|
744 |
-
.slimstat-font-
|
745 |
-
.slimstat-font-
|
746 |
-
.slimstat-font-
|
747 |
-
.slimstat-font-
|
748 |
-
.slimstat-font-
|
749 |
-
.slimstat-font-user-
|
750 |
-
.slimstat-font-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
|
|
764 |
.tag-editor{list-style-type:none;padding:0 5px 0 0;margin:0;overflow:hidden;border:1px solid #eee;cursor:text;font:normal 14px sans-serif;color:#555;background:#fff;line-height:20px}.tag-editor li{display:block;float:left;overflow:hidden;margin:3px 0}.tag-editor div{float:left;padding:0 4px}.tag-editor .placeholder{padding:0 8px;color:#bbb}.tag-editor .tag-editor-spacer{padding:0;width:8px;overflow:hidden;color:transparent;background:none}.tag-editor input{vertical-align:inherit;border:0;outline:none;padding:0;margin:0;cursor:text;font-family:inherit;font-weight:inherit;font-size:inherit;font-style:inherit;box-shadow:none;background:none;color:#444}.tag-editor-hidden-src{position:absolute!important;left:-99999px}.tag-editor ::-ms-clear{display:none}.tag-editor .tag-editor-tag{padding-left:5px;color:#46799b;background:#e0eaf1;white-space:nowrap;overflow:hidden;cursor:pointer;border-radius:2px 0 0 2px}.tag-editor .tag-editor-delete{background:#e0eaf1;cursor:pointer;border-radius:0 2px 2px 0;padding-left:3px;padding-right:4px}.tag-editor .tag-editor-delete i{line-height:18px;display:inline-block}.tag-editor .tag-editor-delete i:before{font-size:16px;color:#8ba7ba;content:"×";font-style:normal}.tag-editor .tag-editor-delete:hover i:before{color:#d65454}.tag-editor .tag-editor-tag.active+.tag-editor-delete,.tag-editor .tag-editor-tag.active+.tag-editor-delete i{visibility:hidden;cursor:text}.tag-editor .tag-editor-tag.active{background:none!important}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default;font-size:14px}.ui-front{z-index:9999}.ui-menu{list-style:none;padding:1px;margin:0;display:block;outline:none}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:2px .4em;line-height:1.4;min-height:0}.ui-widget-content{border:1px solid #bbb;background:#fff;color:#555}.ui-widget-content a{color:#46799b}.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{background:#e0eaf1}.ui-helper-hidden-accessible{display:none}
|
1 |
+
/* Links */
|
2 |
+
.wrap.slimstat a, [id^=slim_] a{
|
3 |
+
outline: none;
|
4 |
+
text-decoration: none;
|
5 |
+
}
|
6 |
+
[id^=slim_] a.slimstat-delete-entry:before{
|
7 |
+
color: #e22;
|
8 |
+
}
|
9 |
+
.slimstat-float-right{
|
10 |
+
float: right;
|
11 |
+
}
|
12 |
+
|
13 |
+
/* Admin Notice */
|
14 |
+
.slimstat-notice{
|
15 |
+
overflow: hidden;
|
16 |
+
}
|
17 |
+
.slimstat-notice span{
|
18 |
+
width: 97%;
|
19 |
+
}
|
20 |
+
.slimstat-notice .fixed-height {
|
21 |
+
height: 120px;
|
22 |
+
margin-bottom: 20px;
|
23 |
+
overflow: auto;
|
24 |
+
padding: 0 20px 0 0;
|
25 |
+
}
|
26 |
+
|
27 |
+
/* Filters */
|
28 |
+
#slimstat-filters-post{
|
29 |
+
display: none;
|
30 |
+
}
|
31 |
+
#slimstat-filters-form{
|
32 |
+
background-color: #e0e0e0;
|
33 |
+
margin-top: 10px;
|
34 |
+
padding: 5px;
|
35 |
+
position: relative;
|
36 |
+
}
|
37 |
+
#slimstat-filters input.text, #slimstat-filters select{
|
38 |
+
vertical-align: initial;
|
39 |
+
width: 15%;
|
40 |
+
}
|
41 |
+
#slimstat-filters-form label {
|
42 |
+
left:-9000px;
|
43 |
+
position: absolute;
|
44 |
+
}
|
45 |
+
#slimstat-date-filters{
|
46 |
+
padding: 4px 10px 6px 20px;
|
47 |
+
position: absolute;
|
48 |
+
right: 5px;
|
49 |
+
top: 5px;
|
50 |
+
}
|
51 |
+
#slimstat-date-filters>a{
|
52 |
+
color: #fff;
|
53 |
+
white-space: nowrap;
|
54 |
+
}
|
55 |
+
#slimstat-date-filters>a::after{
|
56 |
+
content: "\f140";
|
57 |
+
font: normal 20px/1 'dashicons';
|
58 |
+
vertical-align: bottom;
|
59 |
+
}
|
60 |
+
#slimstat-date-filters>a.open::after{
|
61 |
+
content: "\f142";
|
62 |
+
}
|
63 |
+
#slimstat-date-filters .dropdown {
|
64 |
+
background-color: #fff;
|
65 |
+
box-shadow: 0 1px 8px rgba(0, 0, 0, 0.2);
|
66 |
+
color: #222;
|
67 |
+
display: none;
|
68 |
+
padding: 5px 0 5px 5px;
|
69 |
+
position: absolute;
|
70 |
+
right: -4px;
|
71 |
+
top: 35px;
|
72 |
+
width: 390px;
|
73 |
+
z-index: 120;
|
74 |
+
}
|
75 |
+
#slimstat-date-filters .dropdown #slimstat-quick-filters a {
|
76 |
+
background-color: #eee;
|
77 |
+
display: block;
|
78 |
+
float: left;
|
79 |
+
margin: 0 5px 5px 0;
|
80 |
+
padding: 5px;
|
81 |
+
width: 115px;
|
82 |
+
}
|
83 |
+
#slimstat-date-filters .dropdown strong{
|
84 |
+
clear: both;
|
85 |
+
display: block;
|
86 |
+
font-weight: normal;
|
87 |
+
padding: 10px 5px 5px 0;
|
88 |
+
text-transform: uppercase;
|
89 |
+
}
|
90 |
+
#slimstat-date-filters .dropdown select, #slimstat-date-filters .dropdown input{
|
91 |
+
margin: 0 5px 5px 0;
|
92 |
+
height: 27px;
|
93 |
+
width: 135px;
|
94 |
+
}
|
95 |
+
#slimstat-date-filters .dropdown select.short, #slimstat-date-filters .dropdown input.short{
|
96 |
+
width: 65px;
|
97 |
+
}
|
98 |
+
#slimstat-date-filters .dropdown .ui-datepicker-trigger{
|
99 |
+
float: right;
|
100 |
+
margin: 2px 5px 0 0;
|
101 |
+
}
|
102 |
+
#slimstat-current-filters{
|
103 |
+
background-color: #ccc;
|
104 |
+
border-top: 2px solid #eee;
|
105 |
+
color: #222;
|
106 |
+
font-size: 1.1em;
|
107 |
+
overflow: hidden;
|
108 |
+
padding: 5px;
|
109 |
+
position: relative
|
110 |
+
}
|
111 |
+
#slimstat-current-filters .slimstat-remove-filter{
|
112 |
+
color: #fff;
|
113 |
+
}
|
114 |
+
#slimstat-current-filters .slimstat-filter-list{
|
115 |
+
float: left;
|
116 |
+
margin: 0;
|
117 |
+
padding: 4px 0 5px 5px;;
|
118 |
+
}
|
119 |
+
#slimstat-current-filters .slimstat-filter-list li{
|
120 |
+
display: inline;
|
121 |
+
margin: 0 20px 0 0;
|
122 |
+
vertical-align: middle;
|
123 |
+
}
|
124 |
+
.slimstat-filter-action-button{
|
125 |
+
float: right;
|
126 |
+
margin-left: 10px !important;
|
127 |
+
}
|
128 |
+
|
129 |
+
/* Reports: Container */
|
130 |
+
.wrap.slimstat .meta-box-sortables {
|
131 |
+
margin-top: 20px;
|
132 |
+
}
|
133 |
+
|
134 |
+
/* Single Report */
|
135 |
+
.wrap.slimstat .postbox, .wrap.slimstat .sortable-placeholder {
|
136 |
+
box-sizing: border-box;
|
137 |
+
float: left;
|
138 |
+
margin-bottom: 7px;
|
139 |
+
margin-right: 0.5%;
|
140 |
+
min-width: 24.3%;
|
141 |
+
overflow: hidden;
|
142 |
+
width: 24.3%;
|
143 |
+
}
|
144 |
+
.wrap.slimstat .postbox.large {
|
145 |
+
width: 49.1%;
|
146 |
+
}
|
147 |
+
.wrap.slimstat .postbox.extralarge {
|
148 |
+
width: 73.9%;
|
149 |
+
}
|
150 |
+
.wrap.slimstat .postbox.full-width {
|
151 |
+
width: 98.7%;
|
152 |
+
}
|
153 |
+
|
154 |
+
.sortable-placeholder{
|
155 |
+
background-color: #ccc;
|
156 |
+
border: 1px dashed #bbb;
|
157 |
+
margin-bottom: 9px
|
158 |
+
}
|
159 |
+
|
160 |
+
/* Single Report: Header and Header Buttons */
|
161 |
+
.wrap.slimstat .postbox h3{
|
162 |
+
border-bottom: 1px solid #ddd;
|
163 |
+
font-size: 1.2em;
|
164 |
+
margin: 0;
|
165 |
+
padding: 10px;
|
166 |
+
}
|
167 |
+
.wrap.slimstat .postbox h3:hover:after {
|
168 |
+
color: #bbb;
|
169 |
+
content: attr(data-report-id);
|
170 |
+
margin-left: 10px;
|
171 |
+
}
|
172 |
+
.wrap.slimstat .postbox.tall h3{
|
173 |
+
cursor:auto;
|
174 |
+
}
|
175 |
+
.slimstat-header-buttons{
|
176 |
+
float: right;
|
177 |
+
padding: 10px 10px 0;
|
178 |
+
}
|
179 |
+
.slimstat-tooltip-trigger.corner{
|
180 |
+
background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAABkSURBVHjaYpw1a9YUBgaGbCD+AsR/GRCACYg/sACJXCBWBGIvBkzAC1L1H4i9gXgRFgUfmZA48UC8EF0FExo/AYgXIPH/MWExNhGI50PZnNgUgEASEG8FYg5cCkDAB4gnAAQYAGBCD4bcPf1fAAAAAElFTkSuQmCC) 0 0 no-repeat scroll;
|
181 |
+
cursor: help;
|
182 |
+
display: block;
|
183 |
+
height: 7px;
|
184 |
+
position: absolute;
|
185 |
+
top: 0;
|
186 |
+
width: 7px;
|
187 |
+
}
|
188 |
+
.slimstat-tooltip-content{
|
189 |
+
display: none;
|
190 |
+
}
|
191 |
+
.wrap.slimstat h3 .slimstat-tooltip-trigger.corner{
|
192 |
+
right: 0;
|
193 |
+
}
|
194 |
+
.slimstat .no-refresh .refresh{
|
195 |
+
display: none;
|
196 |
+
}
|
197 |
+
|
198 |
+
/* Single Report: Header and Header Buttons - Pagination */
|
199 |
+
[id^=slim_] p.pagination{
|
200 |
+
background-color: #e0e0e0;
|
201 |
+
border-bottom: 1px solid #cde;
|
202 |
+
border-top: 1px solid #cde;
|
203 |
+
color: #444;
|
204 |
+
line-height: 1em;
|
205 |
+
min-height: 5px;
|
206 |
+
}
|
207 |
+
[id^=slim_] p.pagination a{
|
208 |
+
color: #444;
|
209 |
+
float: right;
|
210 |
+
}
|
211 |
+
[id^=slim_] p.pagination a:hover{
|
212 |
+
text-shadow: 0 0 2px #000;
|
213 |
+
}
|
214 |
+
|
215 |
+
/* Single Report: Inside */
|
216 |
+
[id^=slim_] .inside{
|
217 |
+
height: 281px;
|
218 |
+
margin: 0 !important;
|
219 |
+
overflow: auto;
|
220 |
+
padding: 0 !important;
|
221 |
+
}
|
222 |
+
.wrap.slimstat .postbox.tall .inside{
|
223 |
+
height: 650px;
|
224 |
+
}
|
225 |
+
[id^=slim_] p {
|
226 |
+
border-bottom: 1px solid #ddd;
|
227 |
+
line-height: 1.5em;
|
228 |
+
margin: 0;
|
229 |
+
min-height: 20px;
|
230 |
+
overflow: auto;
|
231 |
+
padding: 7px 10px;
|
232 |
+
position: relative;
|
233 |
+
word-wrap: break-word;
|
234 |
+
}
|
235 |
+
[id^=slim_] p:last-child{
|
236 |
+
border-bottom:0;
|
237 |
+
}
|
238 |
+
[id^=slim_] p .slimstat-tooltip-trigger.corner{
|
239 |
+
-moz-transform: scaleX(-1);
|
240 |
+
-o-transform: scaleX(-1);
|
241 |
+
-webkit-transform: scaleX(-1);
|
242 |
+
transform: scaleX(-1);
|
243 |
+
filter: FlipH;
|
244 |
+
-ms-filter: "FlipH";
|
245 |
+
left: 0;
|
246 |
+
}
|
247 |
+
[id^=slim_] p.header{
|
248 |
+
background-color:#eee;
|
249 |
+
border-color:#a6a6a6;
|
250 |
+
}
|
251 |
+
[id^=slim_] p span{
|
252 |
+
float: right;
|
253 |
+
}
|
254 |
+
[id^=slim_] p span.pageview-screenres{
|
255 |
+
margin-right: 10px;
|
256 |
+
}
|
257 |
+
[id^=slim_] a:hover{
|
258 |
+
text-shadow: 0 0 2px #bbb;
|
259 |
+
}
|
260 |
+
[id^=slim_] .slimstat-tooltip-content.expanded{
|
261 |
+
display: block;
|
262 |
+
font-weight: normal;
|
263 |
+
}
|
264 |
+
[id^=slim_] .inline-icon{
|
265 |
+
background-color: transparent;
|
266 |
+
background-position: 0 0;
|
267 |
+
background-repeat: no-repeat;
|
268 |
+
display: inline-block;
|
269 |
+
height: 18px;
|
270 |
+
line-height: 18px;
|
271 |
+
margin-right: 5px;
|
272 |
+
vertical-align: middle;
|
273 |
+
width: 16px;
|
274 |
+
}
|
275 |
+
[id^=slim_] .spaced{
|
276 |
+
margin-left:15px;
|
277 |
+
}
|
278 |
+
#dashboard-widgets-wrap .whois{
|
279 |
+
display: none;
|
280 |
+
}
|
281 |
+
|
282 |
+
/* Single Report: Table */
|
283 |
+
[id^=slim_] .widefat th{
|
284 |
+
white-space: nowrap;
|
285 |
+
}
|
286 |
+
[id^=slim_] .widefat td{
|
287 |
+
border-bottom: 1px solid #e1e1e1;
|
288 |
+
}
|
289 |
+
|
290 |
+
/* Single Report: Debug Message */
|
291 |
+
[id^=slim_] .debug{
|
292 |
+
background-color: #000;
|
293 |
+
color: #fff;
|
294 |
+
display: block;
|
295 |
+
font-family: monospace;
|
296 |
+
opacity: .8;
|
297 |
+
padding: 20px;
|
298 |
+
position: relative;
|
299 |
+
}
|
300 |
+
|
301 |
+
/* Single Report: Color Coded Entries */
|
302 |
+
.little-color-box{
|
303 |
+
background-color: #eee;
|
304 |
+
border: 1px solid #aaa;
|
305 |
+
display: block;
|
306 |
+
float: left;
|
307 |
+
height: 15px;
|
308 |
+
margin-right: 10px;
|
309 |
+
width: 15px;
|
310 |
+
}
|
311 |
+
[id^=slim_] .header.is-search-engine, .little-color-box.is-search-engine{
|
312 |
+
background-color:#c1e751;
|
313 |
+
color:#444;
|
314 |
+
}
|
315 |
+
[id^=slim_] .header.is-direct, .little-color-box.is-direct{
|
316 |
+
background-color:#d0e0eb;
|
317 |
+
color:#111;
|
318 |
+
}
|
319 |
+
[id^=slim_] .header.is-known-user, .little-color-box.is-known-user{
|
320 |
+
background-color:#F1CF90;
|
321 |
+
}
|
322 |
+
[id^=slim_] .header.is-known-visitor, .little-color-box.is-known-visitor{
|
323 |
+
background-color:#EFFD8C;
|
324 |
+
}
|
325 |
+
[id^=slim_] .header.is-spam, .little-color-box.is-spam{
|
326 |
+
background-color:#AAB3AB;
|
327 |
+
color:#222;
|
328 |
+
}
|
329 |
+
[id^=slim_] p.loading{
|
330 |
+
font-size: 30px;
|
331 |
+
line-height: 4em;
|
332 |
+
margin-top: 60px;
|
333 |
+
text-align: center;
|
334 |
+
}
|
335 |
+
[id^=slim_] p.nodata{
|
336 |
+
border: 0;
|
337 |
+
color: #999;
|
338 |
+
padding-top: 95px;
|
339 |
+
text-align: center;
|
340 |
+
}
|
341 |
+
|
342 |
+
/* Single Report: Chart */
|
343 |
+
.chart-placeholder{
|
344 |
+
height: 280px;
|
345 |
+
}
|
346 |
+
|
347 |
+
/* Single Report: Modal Window */
|
348 |
+
.ui-widget-overlay{
|
349 |
+
background-color: #222;
|
350 |
+
filter: alpha(opacity=60);
|
351 |
+
height: 100%;
|
352 |
+
opacity: .6;
|
353 |
+
position: fixed;
|
354 |
+
top: 0;
|
355 |
+
width: 100%;
|
356 |
+
z-index: 100 !important;
|
357 |
+
}
|
358 |
+
.ui-dialog.slimstat{
|
359 |
+
border: 0;
|
360 |
+
border-radius: 0;
|
361 |
+
padding: 0;
|
362 |
+
width: 90% !important;
|
363 |
+
z-index: 100500 !important;
|
364 |
+
}
|
365 |
+
.ui-dialog.slimstat .ui-dialog-titlebar{
|
366 |
+
background: #4b8df8;
|
367 |
+
border: 0;
|
368 |
+
border-radius: 0;
|
369 |
+
color: #fff;
|
370 |
+
font-family: 'Open Sans', sans-serif;
|
371 |
+
font-size: 1.3em;
|
372 |
+
font-weight: normal;
|
373 |
+
height: 22px;
|
374 |
+
line-height: 1.3em;
|
375 |
+
margin: 0;
|
376 |
+
padding: 5px 10px;
|
377 |
+
}
|
378 |
+
.ui-dialog.slimstat .ui-dialog-titlebar-close{
|
379 |
+
background-color: transparent;
|
380 |
+
border: 0;
|
381 |
+
color: #fff;
|
382 |
+
float: right;
|
383 |
+
line-height: 1.3em;
|
384 |
+
padding: 0;
|
385 |
+
}
|
386 |
+
.ui-dialog.slimstat .ui-dialog-titlebar-close:before{
|
387 |
+
content:'\e803';
|
388 |
+
font-family: slimstat;
|
389 |
+
}
|
390 |
+
.ui-dialog .ui-dialog-content{
|
391 |
+
clear: both;
|
392 |
+
}
|
393 |
+
#slimstat-modal-dialog{
|
394 |
+
background-color: #fff;
|
395 |
+
display: none;
|
396 |
+
max-height: 650px !important;
|
397 |
+
overflow: auto;
|
398 |
+
padding: 0;
|
399 |
+
width: auto;
|
400 |
+
}
|
401 |
+
#slimstat-modal-dialog p{
|
402 |
+
margin: 0;
|
403 |
+
padding: 10px;
|
404 |
+
}
|
405 |
+
|
406 |
+
/* Dashboard Widgets */
|
407 |
+
#dashboard-widgets [id*=slim_p].postbox .inside {
|
408 |
+
height: 281px;
|
409 |
+
}
|
410 |
+
#dashboard-widgets [id*=slim_p][id*=_01].postbox .inside {
|
411 |
+
height: 290px;
|
412 |
+
}
|
413 |
+
#dashboard-widgets #slim_p7_02.postbox .inside {
|
414 |
+
height: 320px;
|
415 |
+
}
|
416 |
+
.closed .slimScrollDiv{
|
417 |
+
height: 0 !important;
|
418 |
+
}
|
419 |
+
|
420 |
+
/* Settings */
|
421 |
+
#slimstat-message{
|
422 |
+
background-color: #555;
|
423 |
+
clear: both;
|
424 |
+
color: #fff;
|
425 |
+
overflow: hidden;
|
426 |
+
padding: 0 10px;
|
427 |
+
}
|
428 |
+
#slimstat-message p:before{
|
429 |
+
content: "\f339";
|
430 |
+
font-family: 'dashicons';
|
431 |
+
margin-right: 10px;
|
432 |
+
vertical-align: bottom;
|
433 |
+
}
|
434 |
+
#slimstat-message.wp-ui-notification p:before{
|
435 |
+
content: "\f160";
|
436 |
+
}
|
437 |
+
#slimstat-message p{
|
438 |
+
line-height: 1em;
|
439 |
+
}
|
440 |
+
#slimstat-message a{
|
441 |
+
color: #fc0;
|
442 |
+
}
|
443 |
+
.nav-tabs{
|
444 |
+
margin: 20px 1px 0;
|
445 |
+
}
|
446 |
+
.nav-tab{
|
447 |
+
border-width: 1px 1px 0 !important;
|
448 |
+
font-size: 14px;
|
449 |
+
margin: 0 5px 0 0;
|
450 |
+
}
|
451 |
+
.nav-tab.nav-tab-active{
|
452 |
+
background-color: #fff !important;
|
453 |
+
}
|
454 |
+
.nav-tab a{
|
455 |
+
color: #444;
|
456 |
+
display: block;
|
457 |
+
text-decoration: none;
|
458 |
+
}
|
459 |
+
.form-table{
|
460 |
+
border: 1px solid #ccc !important;
|
461 |
+
margin-top: 0 !important;
|
462 |
+
}
|
463 |
+
.form-table th{
|
464 |
+
font-weight: 400 !important;
|
465 |
+
padding: 15px 10px !important;
|
466 |
+
}
|
467 |
+
.slimstat-options-section-header {
|
468 |
+
background-color: #e4e4e4;
|
469 |
+
font-size: 1.4em !important;
|
470 |
+
margin: 0;
|
471 |
+
padding: 5px 10px !important;
|
472 |
+
}
|
473 |
+
.form-table h3{
|
474 |
+
margin-top: 0;
|
475 |
+
}
|
476 |
+
.form-table td span.block-element{
|
477 |
+
padding: 0 30px 0 0;
|
478 |
+
}
|
479 |
+
.form-table .description{
|
480 |
+
color: #999;
|
481 |
+
display: block;
|
482 |
+
font-style: normal;
|
483 |
+
margin-top: 5px;
|
484 |
+
}
|
485 |
+
.form-table #slimstat-filter-name, .form-table #slimstat-filter-operator, .form-table #slimstat-filter-value{
|
486 |
+
width: 20%;
|
487 |
+
}
|
488 |
+
[id*=form-slimstat-options] input[type=number].small-text{
|
489 |
+
width: 85px;
|
490 |
+
}
|
491 |
+
[class*=bootstrap-switch-id-addon_network_settings] {
|
492 |
+
float: right;
|
493 |
+
}
|
494 |
+
|
495 |
+
/* Add-ons Page */
|
496 |
+
.wp-list-table.slimstat-addons{
|
497 |
+
margin-bottom: 20px;
|
498 |
+
}
|
499 |
+
.wp-list-table.slimstat-addons tbody th{
|
500 |
+
border-left: 5px solid #ccc;
|
501 |
+
}
|
502 |
+
.wp-list-table.slimstat-addons th,.wp-list-table.slimstat-addons td{
|
503 |
+
border-bottom: 1px solid #ccc;
|
504 |
+
}
|
505 |
+
.wp-list-table.slimstat-addons .active th{
|
506 |
+
border-color: #10a062;
|
507 |
+
border-style: solid;
|
508 |
+
border-width: 0 0 0 5px;
|
509 |
+
}
|
510 |
+
.wp-list-table.slimstat-addons .active td{
|
511 |
+
border: 0;
|
512 |
+
}
|
513 |
+
|
514 |
+
/* Edit Posts Page */
|
515 |
+
.column-wp-slimstat{
|
516 |
+
text-align: center !important;
|
517 |
+
width: 3em;
|
518 |
+
}
|
519 |
+
.slimstat-icon:before{
|
520 |
+
content: '\f239';
|
521 |
+
font-family: dashicons;
|
522 |
+
}
|
523 |
+
|
524 |
+
/* RTL Support */
|
525 |
+
.rtl #slimstat-current-filters .slimstat-filter-list{
|
526 |
+
padding: 0 0 0 75px;
|
527 |
+
}
|
528 |
+
.rtl #slimstat-current-filters .slimstat-filter-list li{
|
529 |
+
margin-left: 20px;
|
530 |
+
margin-right: 0;
|
531 |
+
}
|
532 |
+
.rtl #slimstat-remove-all-filters{
|
533 |
+
left: 5px;
|
534 |
+
right: inherit;
|
535 |
+
}
|
536 |
+
.rtl #slimstat-date-filters{
|
537 |
+
left: 5px;
|
538 |
+
right: inherit;
|
539 |
+
}
|
540 |
+
.rtl #slimstat-date-filters span{
|
541 |
+
left: 0;
|
542 |
+
right: inherit;
|
543 |
+
}
|
544 |
+
.rtl .wrap.slimstat .postbox{
|
545 |
+
float: right;
|
546 |
+
}
|
547 |
+
.rtl .slimScrollBar{
|
548 |
+
left: 2px !important;
|
549 |
+
right: inherit !important;
|
550 |
+
}
|
551 |
+
.rtl .slimstat-header-buttons{
|
552 |
+
float: left;
|
553 |
+
}
|
554 |
+
.rtl [id^=slim_] p.pagination a{
|
555 |
+
float: left;
|
556 |
+
}
|
557 |
+
.rtl [id^=slim_] p span{
|
558 |
+
float: left;
|
559 |
+
}
|
560 |
+
.rtl .qtip-content{
|
561 |
+
text-align: right;
|
562 |
+
}
|
563 |
+
.rtl .form-table td span.block-element{
|
564 |
+
padding: 0 0 0 30px;
|
565 |
+
}
|
566 |
+
|
567 |
+
/* Customizer */
|
568 |
+
.slimstat-layout .postbox-container {
|
569 |
+
border: 1px solid #ccc;
|
570 |
+
float: none;
|
571 |
+
margin-bottom: 20px;
|
572 |
+
overflow: hidden;
|
573 |
+
}
|
574 |
+
.slimstat-layout .meta-box-sortables {
|
575 |
+
overflow: hidden;
|
576 |
+
padding: 10px;
|
577 |
+
}
|
578 |
+
.slimstat-layout .postbox-container span.title {
|
579 |
+
background-color: #c0c0c0;
|
580 |
+
color: #fff;
|
581 |
+
font-size: 16px;
|
582 |
+
margin-bottom: 0;
|
583 |
+
padding: 10px;
|
584 |
+
}
|
585 |
+
.slimstat-layout .postbox, .slimstat-layout .sortable-placeholder {
|
586 |
+
float: left;
|
587 |
+
margin: 0 10px 10px 0;
|
588 |
+
min-width: 285px;
|
589 |
+
}
|
590 |
+
.slimstat-layout .postbox.invisible h3 {
|
591 |
+
color: #ccc;
|
592 |
+
}
|
593 |
+
.slimstat-layout h3 {
|
594 |
+
border: 0;
|
595 |
+
font-weight: 300;
|
596 |
+
font-size: 1.1em;
|
597 |
+
margin: 0;
|
598 |
+
padding: 5px 10px;
|
599 |
+
}
|
600 |
+
.slimstat-layout #postbox-container-slimview1 {
|
601 |
+
display: none;
|
602 |
+
}
|
603 |
+
|
604 |
+
/* Responsive */
|
605 |
+
@media screen and ( max-width: 1560px ) {
|
606 |
+
.wrap.slimstat .postbox {
|
607 |
+
width: 32.8%;
|
608 |
+
}
|
609 |
+
.wrap.slimstat .postbox.large {
|
610 |
+
width: 66.1%;
|
611 |
+
}
|
612 |
+
.wrap.slimstat .postbox.extralarge, .wrap.slimstat .postbox.full-width {
|
613 |
+
width: 99.4%;
|
614 |
+
}
|
615 |
+
.wrap.slimstat .postbox h3 {
|
616 |
+
font-size: 1em;
|
617 |
+
line-height: 1.5em;
|
618 |
+
}
|
619 |
+
.wrap.slimstat .postbox p {
|
620 |
+
font-size: 1em;
|
621 |
+
line-height: 1.5em;
|
622 |
+
}
|
623 |
+
}
|
624 |
+
|
625 |
+
@media screen and ( max-width: 1080px ) {
|
626 |
+
.wrap.slimstat .postbox{
|
627 |
+
width: 49.125%;
|
628 |
+
}
|
629 |
+
.wrap.slimstat .postbox.large, .wrap.slimstat .postbox.extralarge, .wrap.slimstat .postbox.full-width {
|
630 |
+
width: 99%;
|
631 |
+
}
|
632 |
+
}
|
633 |
+
@media screen and (max-width: 800px){
|
634 |
+
.slimstat-notice span {
|
635 |
+
width: 90%;
|
636 |
+
}
|
637 |
+
#slimstat-filters input.text, #slimstat-filters select {
|
638 |
+
margin: 0 .5% 0 0;
|
639 |
+
width: 26%;
|
640 |
+
}
|
641 |
+
.wp-core-ui .button-secondary {
|
642 |
+
height: 35px;
|
643 |
+
}
|
644 |
+
#slimstat-date-filters {
|
645 |
+
margin-top: 5px;
|
646 |
+
position: relative;
|
647 |
+
right: inherit;
|
648 |
+
top: inherit;
|
649 |
+
}
|
650 |
+
.wrap.slimstat .postbox, .wrap.slimstat .postbox.large, .wrap.slimstat .postbox.extralarge, .wrap.slimstat .postbox.full-width {
|
651 |
+
margin: 0 0 10px;
|
652 |
+
width: 99.5%;
|
653 |
+
}
|
654 |
+
.wrap.slimstat .postbox h3 {
|
655 |
+
font-size: 1.4em;
|
656 |
+
line-height: 1em;
|
657 |
+
}
|
658 |
+
.wrap.slimstat .postbox p {
|
659 |
+
font-size: 1.1em;
|
660 |
+
line-height: 1.4em;
|
661 |
+
}
|
662 |
+
|
663 |
+
/* Settings */
|
664 |
+
.nav-tab {
|
665 |
+
display: block;
|
666 |
+
margin: 0;
|
667 |
+
}
|
668 |
+
.form-table th {
|
669 |
+
font-size: 1.4em;
|
670 |
+
}
|
671 |
+
.form-table th label {
|
672 |
+
font-size: 1em;
|
673 |
+
}
|
674 |
+
.form-table td {
|
675 |
+
padding: 10px;
|
676 |
+
}
|
677 |
+
.form-table .button-primary,.form-table .button-secondary {
|
678 |
+
height: 30px;
|
679 |
+
margin-bottom: 5px;
|
680 |
+
text-align: center;
|
681 |
+
width: 100%;
|
682 |
+
}
|
683 |
+
.form-table #slimstat-filter-name, .form-table #slimstat-filter-operator, .form-table #slimstat-filter-value {
|
684 |
+
width: 100%;
|
685 |
+
}
|
686 |
+
|
687 |
+
/* Add-on: WP SlimStat - User Overview */
|
688 |
+
[id^='slim_'] .users .column-name {
|
689 |
+
display: none;
|
690 |
+
}
|
691 |
+
}
|
692 |
+
|
693 |
+
/* Fontello - Custom Icon Fonts for SlimStat | Uses Fontelico (C) 2012 by Fontello project, Elusive (C) 2013 by Aristeides Stathopoulos, Font Awesome (C) 2012 by Dave Gandy | http://www.fontello.com */
|
694 |
+
@font-face {
|
695 |
+
font-family: 'slimstat';
|
696 |
+
src: url('slimstat.eot?58272494');
|
697 |
+
src: url('slimstat.eot?58272494#iefix') format('embedded-opentype'),
|
698 |
+
url('slimstat.svg?58272494#fontello') format('svg');
|
699 |
+
font-weight: normal;
|
700 |
+
font-style: normal;
|
701 |
+
}
|
702 |
+
@font-face {
|
703 |
+
font-family: 'slimstat';
|
704 |
+
src: url('data:application/octet-stream;base64,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') format('woff'),
|
705 |
+
url('data:application/octet-stream;base64,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') format('truetype');
|
706 |
+
}
|
707 |
+
[class^="slimstat-font-"]:before, [class*=" slimstat-font-"]:before {
|
708 |
+
color: #aaa;
|
709 |
+
font-family: "slimstat";
|
710 |
+
font-style: normal;
|
711 |
+
font-weight: normal;
|
712 |
+
speak: none;
|
713 |
+
|
714 |
+
text-decoration: inherit;
|
715 |
+
width: 1em;
|
716 |
+
margin: 0 .2em;
|
717 |
+
text-align: center;
|
718 |
+
|
719 |
+
/* For safety - reset parent styles, that can break glyph codes*/
|
720 |
+
font-variant: normal;
|
721 |
+
text-transform: none;
|
722 |
+
|
723 |
+
/* fix buttons height, for twitter bootstrap */
|
724 |
+
line-height: 1em;
|
725 |
+
}
|
726 |
+
.slimstat-font-trash:before { content: '\e800'; } /* '' */
|
727 |
+
.slimstat-font-clock:before { content: '\e801'; } /* '' */
|
728 |
+
.slimstat-font-search:before { content: '\e802'; } /* '' */
|
729 |
+
.slimstat-font-cancel:before { content: '\e803'; } /* '' */
|
730 |
+
.slimstat-font-download:before { content: '\e804'; } /* '' */
|
731 |
+
.slimstat-font-upload:before { content: '\e805'; } /* '' */
|
732 |
+
.slimstat-font-download-cloud:before { content: '\e806'; } /* '' */
|
733 |
+
.slimstat-font-upload-cloud:before { content: '\e807'; } /* '' */
|
734 |
+
.slimstat-font-location-1:before { content: '\e808'; } /* '' */
|
735 |
+
.slimstat-font-arrows-cw-1:before { content: '\e809'; } /* '' */
|
736 |
+
.slimstat-font-login:before { content: '\e80a'; } /* '' */
|
737 |
+
.slimstat-font-logout:before { content: '\e80b'; } /* '' */
|
738 |
+
.slimstat-font-angle-left:before { content: '\e80c'; } /* '' */
|
739 |
+
.slimstat-font-angle-right:before { content: '\e80d'; } /* '' */
|
740 |
+
.slimstat-font-angle-double-left:before { content: '\e80e'; } /* '' */
|
741 |
+
.slimstat-font-angle-double-right:before { content: '\e80f'; } /* '' */
|
742 |
+
.slimstat-font-arrows-cw:before { content: '\e810'; } /* '' */
|
743 |
+
.slimstat-font-doc:before { content: '\e811'; } /* '' */
|
744 |
+
.slimstat-font-spin4:before { content: '\e812'; } /* '' */
|
745 |
+
.slimstat-font-edit:before { content: '\e813'; } /* '' */
|
746 |
+
.slimstat-font-gauge:before { content: '\e814'; } /* '' */
|
747 |
+
.slimstat-font-stopwatch:before { content: '\e815'; } /* '' */
|
748 |
+
.slimstat-font-docs:before { content: '\e816'; } /* '' */
|
749 |
+
.slimstat-font-user-plus:before { content: '\e817'; } /* '' */
|
750 |
+
.slimstat-font-user-times:before { content: '\e818'; } /* '' */
|
751 |
+
.slimstat-font-minus-circled:before { content: '\e819'; } /* '' */
|
752 |
+
|
753 |
+
.animate-spin{-moz-animation:spin 3s infinite linear;-o-animation:spin 3s infinite linear;-webkit-animation:spin 3s infinite linear;animation:spin 3s infinite linear;display:inline-block;line-height:1em;}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-ms-keyframes spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}
|
754 |
+
|
755 |
+
/* qTip2 v3.0.3 basic | http://qtip2.com */
|
756 |
+
.qtip{position:absolute;left:-28000px;top:-28000px;display:none;max-width:280px;min-width:50px;font-size:1em;line-height:1.5em;direction:ltr;box-shadow:none;border-radius:5px;padding:0}.qtip-content,.qtip-titlebar{position:relative;overflow:hidden}.qtip-content{padding:5px 9px;text-align:left;word-wrap:break-word}.qtip-titlebar{padding:5px 35px 5px 10px;border-width:0 0 1px;font-weight:700}.qtip-titlebar+.qtip-content{border-top-width:0!important}.qtip-close{position:absolute;right:-9px;top:-9px;z-index:11;cursor:pointer;outline:0;border:1px solid transparent}.qtip-titlebar .qtip-close{right:4px;top:50%;margin-top:-9px}* html .qtip-titlebar .qtip-close{top:16px}.qtip-icon .ui-icon,.qtip-titlebar .ui-icon{display:block;text-indent:-1000em;direction:ltr}.qtip-icon,.qtip-icon .ui-icon{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;text-decoration:none}.qtip-icon .ui-icon{width:18px;height:14px;line-height:1.5em;text-align:center;text-indent:0;font:normal 700 1em Tahoma,sans-serif;color:inherit;background:-100em -100em no-repeat}.qtip-default{border:1px solid #555;background-color:rgba(0,0,0,.9);color:#ddd}.qtip-default .qtip-titlebar{background-color:#FFEF93}.qtip-default .qtip-icon{border-color:#CCC;background:#F1F1F1;color:#777}.qtip-default .qtip-titlebar .qtip-close{border-color:#AAA;color:#111}.qtip .qtip-tip{margin:0 auto;overflow:hidden;z-index:10}.qtip .qtip-tip,x:-o-prefocus{visibility:hidden}.qtip .qtip-tip,.qtip .qtip-tip .qtip-vml,.qtip .qtip-tip canvas{position:absolute;color:#123456;background:0 0;border:0 dashed transparent}.qtip .qtip-tip canvas{top:0;left:0}.qtip .qtip-tip .qtip-vml{behavior:url(#default#VML);display:inline-block;visibility:visible}
|
757 |
+
|
758 |
+
/*! jQuery UI - v1.10.3 | http://jqueryui.com */
|
759 |
+
#ui-datepicker-div{display:none;}.ui-datepicker{background-color:#fff;border:1px solid #ccc;width:17em;padding:.2em .2em 0;display:none;}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month-year{width:100%}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:49%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:700;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}
|
760 |
+
|
761 |
+
/*! bootstrap-switch - v3.3.2 | http://www.bootstrap-switch.org */
|
762 |
+
.bootstrap-switch{display:inline-block;direction:ltr;cursor:pointer;border-radius:4px;border:1px solid #ccc;position:relative;text-align:left;overflow:hidden;line-height:8px;z-index:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle;-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.bootstrap-switch .bootstrap-switch-container{display:inline-block;top:0;border-radius:4px;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.bootstrap-switch .bootstrap-switch-handle-off,.bootstrap-switch .bootstrap-switch-handle-on,.bootstrap-switch .bootstrap-switch-label{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;cursor:pointer;display:inline-block!important;height:100%;padding:6px 12px;font-size:14px;line-height:20px}.bootstrap-switch .bootstrap-switch-handle-off,.bootstrap-switch .bootstrap-switch-handle-on{text-align:center;z-index:1}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-primary,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-primary{color:#fff;background:#337ab7}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-info,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-info{color:#fff;background:#5bc0de}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-success,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-success{color:#fff;background:#5cb85c}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-warning,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-warning{background:#f0ad4e;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-danger,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-danger{color:#fff;background:#d9534f}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-default,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-default{color:#000;background:#eee}.bootstrap-switch .bootstrap-switch-label{text-align:center;margin-top:-1px;margin-bottom:-1px;z-index:100;color:#333;background:#fff}.bootstrap-switch .bootstrap-switch-handle-on{border-bottom-left-radius:3px;border-top-left-radius:3px}.bootstrap-switch .bootstrap-switch-handle-off{border-bottom-right-radius:3px;border-top-right-radius:3px}.bootstrap-switch input[type=radio],.bootstrap-switch input[type=checkbox]{position:absolute!important;top:0;left:0;margin:0;z-index:-1;opacity:0 !important;filter:alpha(opacity=0)}.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-label{padding:1px 5px;font-size:12px;line-height:1.5}.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-label{padding:5px 10px;font-size:12px;line-height:1.5}.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-label{padding:6px 16px;font-size:18px;line-height:1.3333333}.bootstrap-switch.bootstrap-switch-disabled,.bootstrap-switch.bootstrap-switch-indeterminate,.bootstrap-switch.bootstrap-switch-readonly{cursor:default!important}.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-label,.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-label,.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-label{opacity:.5;filter:alpha(opacity=50);cursor:default!important}.bootstrap-switch.bootstrap-switch-animate .bootstrap-switch-container{-webkit-transition:margin-left .5s;-o-transition:margin-left .5s;transition:margin-left .5s}.bootstrap-switch.bootstrap-switch-inverse .bootstrap-switch-handle-on{border-radius:0 3px 3px 0}.bootstrap-switch.bootstrap-switch-inverse .bootstrap-switch-handle-off{border-radius:3px 0 0 3px}.bootstrap-switch.bootstrap-switch-focused{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.bootstrap-switch.bootstrap-switch-inverse.bootstrap-switch-off .bootstrap-switch-label,.bootstrap-switch.bootstrap-switch-on .bootstrap-switch-label{border-bottom-right-radius:3px;border-top-right-radius:3px}.bootstrap-switch.bootstrap-switch-inverse.bootstrap-switch-on .bootstrap-switch-label,.bootstrap-switch.bootstrap-switch-off .bootstrap-switch-label{border-bottom-left-radius:3px;border-top-left-radius:3px}
|
763 |
+
|
764 |
+
/* jQuery tagEditor v1.0.20 | https://github.com/Pixabay/jQuery-tagEditor */
|
765 |
.tag-editor{list-style-type:none;padding:0 5px 0 0;margin:0;overflow:hidden;border:1px solid #eee;cursor:text;font:normal 14px sans-serif;color:#555;background:#fff;line-height:20px}.tag-editor li{display:block;float:left;overflow:hidden;margin:3px 0}.tag-editor div{float:left;padding:0 4px}.tag-editor .placeholder{padding:0 8px;color:#bbb}.tag-editor .tag-editor-spacer{padding:0;width:8px;overflow:hidden;color:transparent;background:none}.tag-editor input{vertical-align:inherit;border:0;outline:none;padding:0;margin:0;cursor:text;font-family:inherit;font-weight:inherit;font-size:inherit;font-style:inherit;box-shadow:none;background:none;color:#444}.tag-editor-hidden-src{position:absolute!important;left:-99999px}.tag-editor ::-ms-clear{display:none}.tag-editor .tag-editor-tag{padding-left:5px;color:#46799b;background:#e0eaf1;white-space:nowrap;overflow:hidden;cursor:pointer;border-radius:2px 0 0 2px}.tag-editor .tag-editor-delete{background:#e0eaf1;cursor:pointer;border-radius:0 2px 2px 0;padding-left:3px;padding-right:4px}.tag-editor .tag-editor-delete i{line-height:18px;display:inline-block}.tag-editor .tag-editor-delete i:before{font-size:16px;color:#8ba7ba;content:"×";font-style:normal}.tag-editor .tag-editor-delete:hover i:before{color:#d65454}.tag-editor .tag-editor-tag.active+.tag-editor-delete,.tag-editor .tag-editor-tag.active+.tag-editor-delete i{visibility:hidden;cursor:text}.tag-editor .tag-editor-tag.active{background:none!important}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default;font-size:14px}.ui-front{z-index:9999}.ui-menu{list-style:none;padding:1px;margin:0;display:block;outline:none}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:2px .4em;line-height:1.4;min-height:0}.ui-widget-content{border:1px solid #bbb;background:#fff;color:#555}.ui-widget-content a{color:#46799b}.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{background:#e0eaf1}.ui-helper-hidden-accessible{display:none}
|
admin/js/slimstat.admin.js
CHANGED
@@ -1,518 +1,521 @@
|
|
1 |
-
if ( typeof SlimStatAdminParams == 'undefined' ) {
|
2 |
-
SlimStatAdminParams = {
|
3 |
-
refresh_interval: 0,
|
4 |
-
expand_details: 'no',
|
5 |
-
datepicker_image: '',
|
6 |
-
text_direction: ''
|
7 |
-
};
|
8 |
-
}
|
9 |
-
|
10 |
-
// ----- TABLE OF CONTENTS -----------------------------------------------------------
|
11 |
-
//
|
12 |
-
// 1. Data refresh
|
13 |
-
// 2. Filters
|
14 |
-
// 3. Activity log
|
15 |
-
// 4. Customizer
|
16 |
-
// 5. Miscellaneous
|
17 |
-
// 6. Init third-party libraries
|
18 |
-
//
|
19 |
-
// -----------------------------------------------------------------------------------
|
20 |
-
|
21 |
-
jQuery( function() {
|
22 |
-
|
23 |
-
// ----- BEGIN: DATA REFRESH -----------------------------------------------------
|
24 |
-
//
|
25 |
-
|
26 |
-
// Reload a report's data if it is (re)activated via the checkbox under Screen Options
|
27 |
-
jQuery( 'input.hide-postbox-tog[id^=slim_p]' ).on( 'click.postboxes', function () {
|
28 |
-
if ( jQuery( this ).prop( "checked" ) && jQuery( '#' + jQuery( this ).val() ).length ) {
|
29 |
-
SlimStatAdmin.refresh_report( jQuery( this ).val() );
|
30 |
-
}
|
31 |
-
});
|
32 |
-
|
33 |
-
// Reload a report's data if the corresponding refresh/pagination button is clicked
|
34 |
-
jQuery( document ).on( 'click', '[id^=slim_] .refresh', function( e ) {
|
35 |
-
e.preventDefault();
|
36 |
-
|
37 |
-
var id = jQuery( this ).parents( '.postbox' ).attr( 'id' );
|
38 |
-
|
39 |
-
// Is this a pagination link?
|
40 |
-
if ( typeof jQuery( this ).attr( 'href' ).split( '?' )[ 1 ] == 'string' ) {
|
41 |
-
clean_filters = SlimStatAdmin.get_query_string_filters( jQuery( this ).attr( 'href' ).split( '?' )[ 1 ].substring( 1 ) );
|
42 |
-
if ( typeof clean_filters[ 'fs[start_from]' ] == 'string' ) {
|
43 |
-
jQuery( '<input type="hidden" name="fs[start_from]" class="slimstat-post-filter slimstat-temp-filter" value="' + clean_filters[ 'fs[start_from]' ] + '">' ).appendTo( '#slimstat-filters-form' );
|
44 |
-
}
|
45 |
-
}
|
46 |
-
|
47 |
-
SlimStatAdmin.refresh_report( id );
|
48 |
-
|
49 |
-
// Remove any temporary filters (pagination) set here above
|
50 |
-
jQuery( '.slimstat-temp-filter' ).remove();
|
51 |
-
|
52 |
-
// Re-initialize SlimScroll on the new content
|
53 |
-
jQuery( '#' + id + ' .inside' ).slimScroll( {
|
54 |
-
scrollTo : '0px'
|
55 |
-
} );
|
56 |
-
} );
|
57 |
-
|
58 |
-
// Asynchronous reports are loaded dynamically after the page loads
|
59 |
-
if ( SlimStatAdminParams.async_load == 'on' ) {
|
60 |
-
jQuery( 'div[id^=slim_]' ).each( function() {
|
61 |
-
SlimStatAdmin.refresh_report( jQuery( this ).attr( 'id' ) );
|
62 |
-
} );
|
63 |
-
}
|
64 |
-
|
65 |
-
//
|
66 |
-
// ----- END: DATA REFRESH -------------------------------------------------------
|
67 |
-
|
68 |
-
// ----- BEGIN: FILTERS ----------------------------------------------------------
|
69 |
-
//
|
70 |
-
|
71 |
-
// Make input field read-only if certain operators are selected
|
72 |
-
jQuery( '#slimstat-filter-operator' ).on( 'change', function() {
|
73 |
-
if ( this.value == 'is_empty' || this.value == 'is_not_empty' ) {
|
74 |
-
jQuery( '#slimstat-filter-value' ).attr( 'readonly', 'readonly' );
|
75 |
-
}
|
76 |
-
else {
|
77 |
-
jQuery( '#slimstat-filter-value' ).removeAttr( 'readonly' );
|
78 |
-
}
|
79 |
-
} );
|
80 |
-
|
81 |
-
// Toggle the Date Filters dropdown menu
|
82 |
-
jQuery( '#slimstat-date-filters > a' ).on( 'click', function( e ) {
|
83 |
-
e.preventDefault();
|
84 |
-
jQuery( '#slimstat-date-filters > .dropdown' ).slideToggle( 250 );
|
85 |
-
} );
|
86 |
-
|
87 |
-
// Initialize the datepicker library and button (built-in)
|
88 |
-
if ( typeof jQuery( '.slimstat-filter-date' ).datepicker == 'function' ) {
|
89 |
-
jQuery( '.slimstat-filter-date' ).datepicker( {
|
90 |
-
buttonImage: SlimStatAdminParams.datepicker_image,
|
91 |
-
buttonImageOnly: true,
|
92 |
-
changeMonth: true,
|
93 |
-
changeYear: true,
|
94 |
-
dateFormat: 'yy-m-d',
|
95 |
-
maxDate: new Date,
|
96 |
-
nextText: '»',
|
97 |
-
prevText: '«',
|
98 |
-
showOn: 'both',
|
99 |
-
|
100 |
-
onClose: function( dateText, inst ) {
|
101 |
-
if ( dateText.length ) {
|
102 |
-
jQuery( '#slimstat-filter-
|
103 |
-
jQuery( '#slimstat-filter-
|
104 |
-
jQuery( '#slimstat-filter-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
jQuery( '
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
// -----
|
195 |
-
|
196 |
-
|
197 |
-
//
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
// -----
|
241 |
-
|
242 |
-
|
243 |
-
//
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
// -----
|
275 |
-
|
276 |
-
|
277 |
-
//
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
// -----
|
298 |
-
|
299 |
-
|
300 |
-
//
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
// -----
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
//
|
401 |
-
SlimStatAdmin.
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
jQuery( inner_content ).
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
jQuery( 'input[name="' + i + '"]' ).
|
473 |
-
}
|
474 |
-
else {
|
475 |
-
jQuery( '
|
476 |
-
}
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
/*
|
509 |
-
!function(a,b,c){!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):jQuery&&!jQuery.fn.qtip&&a(jQuery)}(function(d){"use strict";function e(a,b,c,e){this.id=c,this.target=a,this.tooltip=D,this.elements={target:a},this._id=Q+"-"+c,this.timers={img:{}},this.options=b,this.plugins={},this.cache={event:{},target:d(),disabled:C,attr:e,onTooltip:C,lastClass:""},this.rendered=this.destroyed=this.disabled=this.waiting=this.hiddenDuringWait=this.positioning=this.triggering=C}function f(a){return a===D||"object"!==d.type(a)}function g(a){return!(d.isFunction(a)||a&&a.attr||a.length||"object"===d.type(a)&&(a.jquery||a.then))}function h(a){var b,c,e,h;return f(a)?C:(f(a.metadata)&&(a.metadata={type:a.metadata}),"content"in a&&(b=a.content,f(b)||b.jquery||b.done?(c=g(b)?C:b,b=a.content={text:c}):c=b.text,"ajax"in b&&(e=b.ajax,h=e&&e.once!==C,delete b.ajax,b.text=function(a,b){var f=c||d(this).attr(b.options.content.attr)||"Loading...",g=d.ajax(d.extend({},e,{context:b})).then(e.success,D,e.error).then(function(a){return a&&h&&b.set("content.text",a),a},function(a,c,d){b.destroyed||0===a.status||b.set("content.text",c+": "+d)});return h?f:(b.set("content.text",f),g)}),"title"in b&&(d.isPlainObject(b.title)&&(b.button=b.title.button,b.title=b.title.text),g(b.title||C)&&(b.title=C))),"position"in a&&f(a.position)&&(a.position={my:a.position,at:a.position}),"show"in a&&f(a.show)&&(a.show=a.show.jquery?{target:a.show}:a.show===B?{ready:B}:{event:a.show}),"hide"in a&&f(a.hide)&&(a.hide=a.hide.jquery?{target:a.hide}:{event:a.hide}),"style"in a&&f(a.style)&&(a.style={classes:a.style}),d.each(P,function(){this.sanitize&&this.sanitize(a)}),a)}function i(a,b){for(var c,d=0,e=a,f=b.split(".");e=e[f[d++]];)d<f.length&&(c=e);return[c||a,f.pop()]}function j(a,b){var c,d,e;for(c in this.checks)if(this.checks.hasOwnProperty(c))for(d in this.checks[c])this.checks[c].hasOwnProperty(d)&&(e=new RegExp(d,"i").exec(a))&&(b.push(e),("builtin"===c||this.plugins[c])&&this.checks[c][d].apply(this.plugins[c]||this,b))}function k(a){return T.concat("").join(a?"-"+a+" ":" ")}function l(a,b){return b>0?setTimeout(d.proxy(a,this),b):void a.call(this)}function m(a){this.tooltip.hasClass($)||(clearTimeout(this.timers.show),clearTimeout(this.timers.hide),this.timers.show=l.call(this,function(){this.toggle(B,a)},this.options.show.delay))}function n(a){if(!this.tooltip.hasClass($)&&!this.destroyed){var b=d(a.relatedTarget),c=b.closest(U)[0]===this.tooltip[0],e=b[0]===this.options.show.target[0];if(clearTimeout(this.timers.show),clearTimeout(this.timers.hide),this!==b[0]&&"mouse"===this.options.position.target&&c||this.options.hide.fixed&&/mouse(out|leave|move)/.test(a.type)&&(c||e))try{a.preventDefault(),a.stopImmediatePropagation()}catch(f){}else this.timers.hide=l.call(this,function(){this.toggle(C,a)},this.options.hide.delay,this)}}function o(a){!this.tooltip.hasClass($)&&this.options.hide.inactive&&(clearTimeout(this.timers.inactive),this.timers.inactive=l.call(this,function(){this.hide(a)},this.options.hide.inactive))}function p(a){this.rendered&&this.tooltip[0].offsetWidth>0&&this.reposition(a)}function q(a,c,e){d(b.body).delegate(a,(c.split?c:c.join("."+Q+" "))+"."+Q,function(){var a=w.api[d.attr(this,S)];a&&!a.disabled&&e.apply(a,arguments)})}function r(a,c,f){var g,i,j,k,l,m=d(b.body),n=a[0]===b?m:a,o=a.metadata?a.metadata(f.metadata):D,p="html5"===f.metadata.type&&o?o[f.metadata.name]:D,q=a.data(f.metadata.name||"qtipopts");try{q="string"==typeof q?d.parseJSON(q):q}catch(r){}if(k=d.extend(B,{},w.defaults,f,"object"==typeof q?h(q):D,h(p||o)),i=k.position,k.id=c,"boolean"==typeof k.content.text){if(j=a.attr(k.content.attr),k.content.attr===C||!j)return C;k.content.text=j}if(i.container.length||(i.container=m),i.target===C&&(i.target=n),k.show.target===C&&(k.show.target=n),k.show.solo===B&&(k.show.solo=i.container.closest("body")),k.hide.target===C&&(k.hide.target=n),k.position.viewport===B&&(k.position.viewport=i.container),i.container=i.container.eq(0),i.at=new y(i.at,B),i.my=new y(i.my),a.data(Q))if(k.overwrite)a.qtip("destroy",!0);else if(k.overwrite===C)return C;return a.attr(R,c),k.suppress&&(l=a.attr("title"))&&a.removeAttr("title").attr(aa,l).attr("title",""),g=new e(a,k,c,!!j),a.data(Q,g),g}function s(a){return a.charAt(0).toUpperCase()+a.slice(1)}function t(a,b){var d,e,f=b.charAt(0).toUpperCase()+b.slice(1),g=(b+" "+ta.join(f+" ")+f).split(" "),h=0;if(sa[b])return a.css(sa[b]);for(;d=g[h++];)if((e=a.css(d))!==c)return sa[b]=d,e}function u(a,b){return Math.ceil(parseFloat(t(a,b)))}function v(a,b){this._ns="tip",this.options=b,this.offset=b.offset,this.size=[b.width,b.height],this.qtip=a,this.init(a)}var w,x,y,z,A,B=!0,C=!1,D=null,E="x",F="y",G="width",H="height",I="top",J="left",K="bottom",L="right",M="center",N="flipinvert",O="shift",P={},Q="qtip",R="data-hasqtip",S="data-qtip-id",T=["ui-widget","ui-tooltip"],U="."+Q,V="click dblclick mousedown mouseup mousemove mouseleave mouseenter".split(" "),W=Q+"-fixed",X=Q+"-default",Y=Q+"-focus",Z=Q+"-hover",$=Q+"-disabled",_="_replacedByqTip",aa="oldtitle",ba={ie:function(){var a,c;for(a=4,c=b.createElement("div");(c.innerHTML="<!--[if gt IE "+a+"]><i></i><![endif]-->")&&c.getElementsByTagName("i")[0];a+=1);return a>4?a:NaN}(),iOS:parseFloat((""+(/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent)||[0,""])[1]).replace("undefined","3_2").replace("_",".").replace("_",""))||C};x=e.prototype,x._when=function(a){return d.when.apply(d,a)},x.render=function(a){if(this.rendered||this.destroyed)return this;var b=this,c=this.options,e=this.cache,f=this.elements,g=c.content.text,h=c.content.title,i=c.content.button,j=c.position,k=[];return d.attr(this.target[0],"aria-describedby",this._id),e.posClass=this._createPosClass((this.position={my:j.my,at:j.at}).my),this.tooltip=f.tooltip=d("<div/>",{id:this._id,"class":[Q,X,c.style.classes,e.posClass].join(" "),width:c.style.width||"",height:c.style.height||"",tracking:"mouse"===j.target&&j.adjust.mouse,role:"alert","aria-live":"polite","aria-atomic":C,"aria-describedby":this._id+"-content","aria-hidden":B}).toggleClass($,this.disabled).attr(S,this.id).data(Q,this).appendTo(j.container).append(f.content=d("<div />",{"class":Q+"-content",id:this._id+"-content","aria-atomic":B})),this.rendered=-1,this.positioning=B,h&&(this._createTitle(),d.isFunction(h)||k.push(this._updateTitle(h,C))),i&&this._createButton(),d.isFunction(g)||k.push(this._updateContent(g,C)),this.rendered=B,this._setWidget(),d.each(P,function(a){var c;"render"===this.initialize&&(c=this(b))&&(b.plugins[a]=c)}),this._unassignEvents(),this._assignEvents(),this._when(k).then(function(){b._trigger("render"),b.positioning=C,b.hiddenDuringWait||!c.show.ready&&!a||b.toggle(B,e.event,C),b.hiddenDuringWait=C}),w.api[this.id]=this,this},x.destroy=function(a){function b(){if(!this.destroyed){this.destroyed=B;var a,b=this.target,c=b.attr(aa);this.rendered&&this.tooltip.stop(1,0).find("*").remove().end().remove(),d.each(this.plugins,function(){this.destroy&&this.destroy()});for(a in this.timers)this.timers.hasOwnProperty(a)&&clearTimeout(this.timers[a]);b.removeData(Q).removeAttr(S).removeAttr(R).removeAttr("aria-describedby"),this.options.suppress&&c&&b.attr("title",c).removeAttr(aa),this._unassignEvents(),this.options=this.elements=this.cache=this.timers=this.plugins=this.mouse=D,delete w.api[this.id]}}return this.destroyed?this.target:(a===B&&"hide"!==this.triggering||!this.rendered?b.call(this):(this.tooltip.one("tooltiphidden",d.proxy(b,this)),!this.triggering&&this.hide()),this.target)},z=x.checks={builtin:{"^id$":function(a,b,c,e){var f=c===B?w.nextid:c,g=Q+"-"+f;f!==C&&f.length>0&&!d("#"+g).length?(this._id=g,this.rendered&&(this.tooltip[0].id=this._id,this.elements.content[0].id=this._id+"-content",this.elements.title[0].id=this._id+"-title")):a[b]=e},"^prerender":function(a,b,c){c&&!this.rendered&&this.render(this.options.show.ready)},"^content.text$":function(a,b,c){this._updateContent(c)},"^content.attr$":function(a,b,c,d){this.options.content.text===this.target.attr(d)&&this._updateContent(this.target.attr(c))},"^content.title$":function(a,b,c){return c?(c&&!this.elements.title&&this._createTitle(),void this._updateTitle(c)):this._removeTitle()},"^content.button$":function(a,b,c){this._updateButton(c)},"^content.title.(text|button)$":function(a,b,c){this.set("content."+b,c)},"^position.(my|at)$":function(a,b,c){"string"==typeof c&&(this.position[b]=a[b]=new y(c,"at"===b))},"^position.container$":function(a,b,c){this.rendered&&this.tooltip.appendTo(c)},"^show.ready$":function(a,b,c){c&&(!this.rendered&&this.render(B)||this.toggle(B))},"^style.classes$":function(a,b,c,d){this.rendered&&this.tooltip.removeClass(d).addClass(c)},"^style.(width|height)":function(a,b,c){this.rendered&&this.tooltip.css(b,c)},"^style.widget|content.title":function(){this.rendered&&this._setWidget()},"^style.def":function(a,b,c){this.rendered&&this.tooltip.toggleClass(X,!!c)},"^events.(render|show|move|hide|focus|blur)$":function(a,b,c){this.rendered&&this.tooltip[(d.isFunction(c)?"":"un")+"bind"]("tooltip"+b,c)},"^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)":function(){if(this.rendered){var a=this.options.position;this.tooltip.attr("tracking","mouse"===a.target&&a.adjust.mouse),this._unassignEvents(),this._assignEvents()}}}},x.get=function(a){if(this.destroyed)return this;var b=i(this.options,a.toLowerCase()),c=b[0][b[1]];return c.precedance?c.string():c};var ca=/^position\.(my|at|adjust|target|container|viewport)|style|content|show\.ready/i,da=/^prerender|show\.ready/i;x.set=function(a,b){if(this.destroyed)return this;var c,e=this.rendered,f=C,g=this.options;return"string"==typeof a?(c=a,a={},a[c]=b):a=d.extend({},a),d.each(a,function(b,c){if(e&&da.test(b))return void delete a[b];var h,j=i(g,b.toLowerCase());h=j[0][j[1]],j[0][j[1]]=c&&c.nodeType?d(c):c,f=ca.test(b)||f,a[b]=[j[0],j[1],c,h]}),h(g),this.positioning=B,d.each(a,d.proxy(j,this)),this.positioning=C,this.rendered&&this.tooltip[0].offsetWidth>0&&f&&this.reposition("mouse"===g.position.target?D:this.cache.event),this},x._update=function(a,b){var c=this,e=this.cache;return this.rendered&&a?(d.isFunction(a)&&(a=a.call(this.elements.target,e.event,this)||""),d.isFunction(a.then)?(e.waiting=B,a.then(function(a){return e.waiting=C,c._update(a,b)},D,function(a){return c._update(a,b)})):a===C||!a&&""!==a?C:(a.jquery&&a.length>0?b.empty().append(a.css({display:"block",visibility:"visible"})):b.html(a),this._waitForContent(b).then(function(a){c.rendered&&c.tooltip[0].offsetWidth>0&&c.reposition(e.event,!a.length)}))):C},x._waitForContent=function(a){var b=this.cache;return b.waiting=B,(d.fn.imagesLoaded?a.imagesLoaded():(new d.Deferred).resolve([])).done(function(){b.waiting=C}).promise()},x._updateContent=function(a,b){this._update(a,this.elements.content,b)},x._updateTitle=function(a,b){this._update(a,this.elements.title,b)===C&&this._removeTitle(C)},x._createTitle=function(){var a=this.elements,b=this._id+"-title";a.titlebar&&this._removeTitle(),a.titlebar=d("<div />",{"class":Q+"-titlebar "+(this.options.style.widget?k("header"):"")}).append(a.title=d("<div />",{id:b,"class":Q+"-title","aria-atomic":B})).insertBefore(a.content).delegate(".qtip-close","mousedown keydown mouseup keyup mouseout",function(a){d(this).toggleClass("ui-state-active ui-state-focus","down"===a.type.substr(-4))}).delegate(".qtip-close","mouseover mouseout",function(a){d(this).toggleClass("ui-state-hover","mouseover"===a.type)}),this.options.content.button&&this._createButton()},x._removeTitle=function(a){var b=this.elements;b.title&&(b.titlebar.remove(),b.titlebar=b.title=b.button=D,a!==C&&this.reposition())},x._createPosClass=function(a){return Q+"-pos-"+(a||this.options.position.my).abbrev()},x.reposition=function(c,e){if(!this.rendered||this.positioning||this.destroyed)return this;this.positioning=B;var f,g,h,i,j=this.cache,k=this.tooltip,l=this.options.position,m=l.target,n=l.my,o=l.at,p=l.viewport,q=l.container,r=l.adjust,s=r.method.split(" "),t=k.outerWidth(C),u=k.outerHeight(C),v=0,w=0,x=k.css("position"),y={left:0,top:0},z=k[0].offsetWidth>0,A=c&&"scroll"===c.type,D=d(a),E=q[0].ownerDocument,F=this.mouse;if(d.isArray(m)&&2===m.length)o={x:J,y:I},y={left:m[0],top:m[1]};else if("mouse"===m)o={x:J,y:I},(!r.mouse||this.options.hide.distance)&&j.origin&&j.origin.pageX?c=j.origin:!c||c&&("resize"===c.type||"scroll"===c.type)?c=j.event:F&&F.pageX&&(c=F),"static"!==x&&(y=q.offset()),E.body.offsetWidth!==(a.innerWidth||E.documentElement.clientWidth)&&(g=d(b.body).offset()),y={left:c.pageX-y.left+(g&&g.left||0),top:c.pageY-y.top+(g&&g.top||0)},r.mouse&&A&&F&&(y.left-=(F.scrollX||0)-D.scrollLeft(),y.top-=(F.scrollY||0)-D.scrollTop());else{if("event"===m?c&&c.target&&"scroll"!==c.type&&"resize"!==c.type?j.target=d(c.target):c.target||(j.target=this.elements.target):"event"!==m&&(j.target=d(m.jquery?m:this.elements.target)),m=j.target,m=d(m).eq(0),0===m.length)return this;m[0]===b||m[0]===a?(v=ba.iOS?a.innerWidth:m.width(),w=ba.iOS?a.innerHeight:m.height(),m[0]===a&&(y={top:(p||m).scrollTop(),left:(p||m).scrollLeft()})):P.imagemap&&m.is("area")?f=P.imagemap(this,m,o,P.viewport?s:C):P.svg&&m&&m[0].ownerSVGElement?f=P.svg(this,m,o,P.viewport?s:C):(v=m.outerWidth(C),w=m.outerHeight(C),y=m.offset()),f&&(v=f.width,w=f.height,g=f.offset,y=f.position),y=this.reposition.offset(m,y,q),(ba.iOS>3.1&&ba.iOS<4.1||ba.iOS>=4.3&&ba.iOS<4.33||!ba.iOS&&"fixed"===x)&&(y.left-=D.scrollLeft(),y.top-=D.scrollTop()),(!f||f&&f.adjustable!==C)&&(y.left+=o.x===L?v:o.x===M?v/2:0,y.top+=o.y===K?w:o.y===M?w/2:0)}return y.left+=r.x+(n.x===L?-t:n.x===M?-t/2:0),y.top+=r.y+(n.y===K?-u:n.y===M?-u/2:0),P.viewport?(h=y.adjusted=P.viewport(this,y,l,v,w,t,u),g&&h.left&&(y.left+=g.left),g&&h.top&&(y.top+=g.top),h.my&&(this.position.my=h.my)):y.adjusted={left:0,top:0},j.posClass!==(i=this._createPosClass(this.position.my))&&(j.posClass=i,k.removeClass(j.posClass).addClass(i)),this._trigger("move",[y,p.elem||p],c)?(delete y.adjusted,e===C||!z||isNaN(y.left)||isNaN(y.top)||"mouse"===m||!d.isFunction(l.effect)?k.css(y):d.isFunction(l.effect)&&(l.effect.call(k,this,d.extend({},y)),k.queue(function(a){d(this).css({opacity:"",height:""}),ba.ie&&this.style.removeAttribute("filter"),a()})),this.positioning=C,this):this},x.reposition.offset=function(a,c,e){function f(a,b){c.left+=b*a.scrollLeft(),c.top+=b*a.scrollTop()}if(!e[0])return c;var g,h,i,j,k=d(a[0].ownerDocument),l=!!ba.ie&&"CSS1Compat"!==b.compatMode,m=e[0];do"static"!==(h=d.css(m,"position"))&&("fixed"===h?(i=m.getBoundingClientRect(),f(k,-1)):(i=d(m).position(),i.left+=parseFloat(d.css(m,"borderLeftWidth"))||0,i.top+=parseFloat(d.css(m,"borderTopWidth"))||0),c.left-=i.left+(parseFloat(d.css(m,"marginLeft"))||0),c.top-=i.top+(parseFloat(d.css(m,"marginTop"))||0),g||"hidden"===(j=d.css(m,"overflow"))||"visible"===j||(g=d(m)));while(m=m.offsetParent);return g&&(g[0]!==k[0]||l)&&f(g,1),c};var ea=(y=x.reposition.Corner=function(a,b){a=(""+a).replace(/([A-Z])/," $1").replace(/middle/gi,M).toLowerCase(),this.x=(a.match(/left|right/i)||a.match(/center/)||["inherit"])[0].toLowerCase(),this.y=(a.match(/top|bottom|center/i)||["inherit"])[0].toLowerCase(),this.forceY=!!b;var c=a.charAt(0);this.precedance="t"===c||"b"===c?F:E}).prototype;ea.invert=function(a,b){this[a]=this[a]===J?L:this[a]===L?J:b||this[a]},ea.string=function(a){var b=this.x,c=this.y,d=b!==c?"center"===b||"center"!==c&&(this.precedance===F||this.forceY)?[c,b]:[b,c]:[b];return a!==!1?d.join(" "):d},ea.abbrev=function(){var a=this.string(!1);return a[0].charAt(0)+(a[1]&&a[1].charAt(0)||"")},ea.clone=function(){return new y(this.string(),this.forceY)},x.toggle=function(a,c){var e=this.cache,f=this.options,g=this.tooltip;if(c){if(/over|enter/.test(c.type)&&e.event&&/out|leave/.test(e.event.type)&&f.show.target.add(c.target).length===f.show.target.length&&g.has(c.relatedTarget).length)return this;e.event=d.event.fix(c)}if(this.waiting&&!a&&(this.hiddenDuringWait=B),!this.rendered)return a?this.render(1):this;if(this.destroyed||this.disabled)return this;var h,i,j,k=a?"show":"hide",l=this.options[k],m=this.options.position,n=this.options.content,o=this.tooltip.css("width"),p=this.tooltip.is(":visible"),q=a||1===l.target.length,r=!c||l.target.length<2||e.target[0]===c.target;return(typeof a).search("boolean|number")&&(a=!p),h=!g.is(":animated")&&p===a&&r,i=h?D:!!this._trigger(k,[90]),this.destroyed?this:(i!==C&&a&&this.focus(c),!i||h?this:(d.attr(g[0],"aria-hidden",!a),a?(this.mouse&&(e.origin=d.event.fix(this.mouse)),d.isFunction(n.text)&&this._updateContent(n.text,C),d.isFunction(n.title)&&this._updateTitle(n.title,C),!A&&"mouse"===m.target&&m.adjust.mouse&&(d(b).bind("mousemove."+Q,this._storeMouse),A=B),o||g.css("width",g.outerWidth(C)),this.reposition(c,arguments[2]),o||g.css("width",""),l.solo&&("string"==typeof l.solo?d(l.solo):d(U,l.solo)).not(g).not(l.target).qtip("hide",new d.Event("tooltipsolo"))):(clearTimeout(this.timers.show),delete e.origin,A&&!d(U+'[tracking="true"]:visible',l.solo).not(g).length&&(d(b).unbind("mousemove."+Q),A=C),this.blur(c)),j=d.proxy(function(){a?(ba.ie&&g[0].style.removeAttribute("filter"),g.css("overflow",""),"string"==typeof l.autofocus&&d(this.options.show.autofocus,g).focus(),this.options.show.target.trigger("qtip-"+this.id+"-inactive")):g.css({display:"",visibility:"",opacity:"",left:"",top:""}),this._trigger(a?"visible":"hidden")},this),l.effect===C||q===C?(g[k](),j()):d.isFunction(l.effect)?(g.stop(1,1),l.effect.call(g,this),g.queue("fx",function(a){j(),a()})):g.fadeTo(90,a?1:0,j),a&&l.target.trigger("qtip-"+this.id+"-inactive"),this))},x.show=function(a){return this.toggle(B,a)},x.hide=function(a){return this.toggle(C,a)},x.focus=function(a){if(!this.rendered||this.destroyed)return this;var b=d(U),c=this.tooltip,e=parseInt(c[0].style.zIndex,10),f=w.zindex+b.length;return c.hasClass(Y)||this._trigger("focus",[f],a)&&(e!==f&&(b.each(function(){this.style.zIndex>e&&(this.style.zIndex=this.style.zIndex-1)}),b.filter("."+Y).qtip("blur",a)),c.addClass(Y)[0].style.zIndex=f),this},x.blur=function(a){return!this.rendered||this.destroyed?this:(this.tooltip.removeClass(Y),this._trigger("blur",[this.tooltip.css("zIndex")],a),this)},x.disable=function(a){return this.destroyed?this:("toggle"===a?a=!(this.rendered?this.tooltip.hasClass($):this.disabled):"boolean"!=typeof a&&(a=B),this.rendered&&this.tooltip.toggleClass($,a).attr("aria-disabled",a),this.disabled=!!a,this)},x.enable=function(){return this.disable(C)},x._createButton=function(){var a=this,b=this.elements,c=b.tooltip,e=this.options.content.button,f="string"==typeof e,g=f?e:"Close tooltip";b.button&&b.button.remove(),e.jquery?b.button=e:b.button=d("<a />",{"class":"qtip-close "+(this.options.style.widget?"":Q+"-icon"),title:g,"aria-label":g}).prepend(d("<span />",{"class":"ui-icon ui-icon-close",html:"×"})),b.button.appendTo(b.titlebar||c).attr("role","button").click(function(b){return c.hasClass($)||a.hide(b),C})},x._updateButton=function(a){if(!this.rendered)return C;var b=this.elements.button;a?this._createButton():b.remove()},x._setWidget=function(){var a=this.options.style.widget,b=this.elements,c=b.tooltip,d=c.hasClass($);c.removeClass($),$=a?"ui-state-disabled":"qtip-disabled",c.toggleClass($,d),c.toggleClass("ui-helper-reset "+k(),a).toggleClass(X,this.options.style.def&&!a),b.content&&b.content.toggleClass(k("content"),a),b.titlebar&&b.titlebar.toggleClass(k("header"),a),b.button&&b.button.toggleClass(Q+"-icon",!a)},x._storeMouse=function(a){return(this.mouse=d.event.fix(a)).type="mousemove",this},x._bind=function(a,b,c,e,f){if(a&&c&&b.length){var g="."+this._id+(e?"-"+e:"");return d(a).bind((b.split?b:b.join(g+" "))+g,d.proxy(c,f||this)),this}},x._unbind=function(a,b){return a&&d(a).unbind("."+this._id+(b?"-"+b:"")),this},x._trigger=function(a,b,c){var e=new d.Event("tooltip"+a);return e.originalEvent=c&&d.extend({},c)||this.cache.event||D,this.triggering=a,this.tooltip.trigger(e,[this].concat(b||[])),this.triggering=C,!e.isDefaultPrevented()},x._bindEvents=function(a,b,c,e,f,g){var h=c.filter(e).add(e.filter(c)),i=[];h.length&&(d.each(b,function(b,c){var e=d.inArray(c,a);e>-1&&i.push(a.splice(e,1)[0])}),i.length&&(this._bind(h,i,function(a){var b=this.rendered?this.tooltip[0].offsetWidth>0:!1;(b?g:f).call(this,a)}),c=c.not(h),e=e.not(h))),this._bind(c,a,f),this._bind(e,b,g)},x._assignInitialEvents=function(a){function b(a){return this.disabled||this.destroyed?C:(this.cache.event=a&&d.event.fix(a),this.cache.target=a&&d(a.target),clearTimeout(this.timers.show),void(this.timers.show=l.call(this,function(){this.render("object"==typeof a||c.show.ready)},c.prerender?0:c.show.delay)))}var c=this.options,e=c.show.target,f=c.hide.target,g=c.show.event?d.trim(""+c.show.event).split(" "):[],h=c.hide.event?d.trim(""+c.hide.event).split(" "):[];this._bind(this.elements.target,["remove","removeqtip"],function(){this.destroy(!0)},"destroy"),/mouse(over|enter)/i.test(c.show.event)&&!/mouse(out|leave)/i.test(c.hide.event)&&h.push("mouseleave"),this._bind(e,"mousemove",function(a){this._storeMouse(a),this.cache.onTarget=B}),this._bindEvents(g,h,e,f,b,function(){return this.timers?void clearTimeout(this.timers.show):C}),(c.show.ready||c.prerender)&&b.call(this,a)},x._assignEvents=function(){var c=this,e=this.options,f=e.position,g=this.tooltip,h=e.show.target,i=e.hide.target,j=f.container,k=f.viewport,l=d(b),q=d(a),r=e.show.event?d.trim(""+e.show.event).split(" "):[],s=e.hide.event?d.trim(""+e.hide.event).split(" "):[];d.each(e.events,function(a,b){c._bind(g,"toggle"===a?["tooltipshow","tooltiphide"]:["tooltip"+a],b,null,g)}),/mouse(out|leave)/i.test(e.hide.event)&&"window"===e.hide.leave&&this._bind(l,["mouseout","blur"],function(a){/select|option/.test(a.target.nodeName)||a.relatedTarget||this.hide(a)}),e.hide.fixed?i=i.add(g.addClass(W)):/mouse(over|enter)/i.test(e.show.event)&&this._bind(i,"mouseleave",function(){clearTimeout(this.timers.show)}),(""+e.hide.event).indexOf("unfocus")>-1&&this._bind(j.closest("html"),["mousedown","touchstart"],function(a){var b=d(a.target),c=this.rendered&&!this.tooltip.hasClass($)&&this.tooltip[0].offsetWidth>0,e=b.parents(U).filter(this.tooltip[0]).length>0;b[0]===this.target[0]||b[0]===this.tooltip[0]||e||this.target.has(b[0]).length||!c||this.hide(a)}),"number"==typeof e.hide.inactive&&(this._bind(h,"qtip-"+this.id+"-inactive",o,"inactive"),this._bind(i.add(g),w.inactiveEvents,o)),this._bindEvents(r,s,h,i,m,n),this._bind(h.add(g),"mousemove",function(a){if("number"==typeof e.hide.distance){var b=this.cache.origin||{},c=this.options.hide.distance,d=Math.abs;(d(a.pageX-b.pageX)>=c||d(a.pageY-b.pageY)>=c)&&this.hide(a)}this._storeMouse(a)}),"mouse"===f.target&&f.adjust.mouse&&(e.hide.event&&this._bind(h,["mouseenter","mouseleave"],function(a){return this.cache?void(this.cache.onTarget="mouseenter"===a.type):C}),this._bind(l,"mousemove",function(a){this.rendered&&this.cache.onTarget&&!this.tooltip.hasClass($)&&this.tooltip[0].offsetWidth>0&&this.reposition(a)})),(f.adjust.resize||k.length)&&this._bind(d.event.special.resize?k:q,"resize",p),f.adjust.scroll&&this._bind(q.add(f.container),"scroll",p)},x._unassignEvents=function(){var c=this.options,e=c.show.target,f=c.hide.target,g=d.grep([this.elements.target[0],this.rendered&&this.tooltip[0],c.position.container[0],c.position.viewport[0],c.position.container.closest("html")[0],a,b],function(a){return"object"==typeof a});e&&e.toArray&&(g=g.concat(e.toArray())),f&&f.toArray&&(g=g.concat(f.toArray())),this._unbind(g)._unbind(g,"destroy")._unbind(g,"inactive")},d(function(){q(U,["mouseenter","mouseleave"],function(a){var b="mouseenter"===a.type,c=d(a.currentTarget),e=d(a.relatedTarget||a.target),f=this.options;b?(this.focus(a),c.hasClass(W)&&!c.hasClass($)&&clearTimeout(this.timers.hide)):"mouse"===f.position.target&&f.position.adjust.mouse&&f.hide.event&&f.show.target&&!e.closest(f.show.target[0]).length&&this.hide(a),c.toggleClass(Z,b)}),q("["+S+"]",V,o)}),w=d.fn.qtip=function(a,b,e){var f=(""+a).toLowerCase(),g=D,i=d.makeArray(arguments).slice(1),j=i[i.length-1],k=this[0]?d.data(this[0],Q):D;return!arguments.length&&k||"api"===f?k:"string"==typeof a?(this.each(function(){var a=d.data(this,Q);if(!a)return B;if(j&&j.timeStamp&&(a.cache.event=j),!b||"option"!==f&&"options"!==f)a[f]&&a[f].apply(a,i);else{if(e===c&&!d.isPlainObject(b))return g=a.get(b),C;a.set(b,e)}}),g!==D?g:this):"object"!=typeof a&&arguments.length?void 0:(k=h(d.extend(B,{},a)),this.each(function(a){var b,c;return c=d.isArray(k.id)?k.id[a]:k.id,c=!c||c===C||c.length<1||w.api[c]?w.nextid++:c,b=r(d(this),c,k),b===C?B:(w.api[c]=b,d.each(P,function(){"initialize"===this.initialize&&this(b)}),void b._assignInitialEvents(j))}))},d.qtip=e,w.api={},d.each({attr:function(a,b){if(this.length){var c=this[0],e="title",f=d.data(c,"qtip");if(a===e&&f&&f.options&&"object"==typeof f&&"object"==typeof f.options&&f.options.suppress)return arguments.length<2?d.attr(c,aa):(f&&f.options.content.attr===e&&f.cache.attr&&f.set("content.text",b),this.attr(aa,b))}return d.fn["attr"+_].apply(this,arguments)},clone:function(a){var b=d.fn["clone"+_].apply(this,arguments);return a||b.filter("["+aa+"]").attr("title",function(){return d.attr(this,aa)}).removeAttr(aa),b}},function(a,b){if(!b||d.fn[a+_])return B;var c=d.fn[a+_]=d.fn[a];d.fn[a]=function(){return b.apply(this,arguments)||c.apply(this,arguments)}}),d.ui||(d["cleanData"+_]=d.cleanData,d.cleanData=function(a){for(var b,c=0;(b=d(a[c])).length;c++)if(b.attr(R))try{b.triggerHandler("removeqtip")}catch(e){}d["cleanData"+_].apply(this,arguments)}),w.version="3.0.3",w.nextid=0,w.inactiveEvents=V,w.zindex=15e3,w.defaults={prerender:C,id:C,overwrite:B,suppress:B,content:{text:B,attr:"title",title:C,button:C},position:{my:"top left",at:"bottom right",target:C,container:C,viewport:C,adjust:{x:0,y:0,mouse:B,scroll:B,resize:B,method:"flipinvert flipinvert"},effect:function(a,b){d(this).animate(b,{duration:200,queue:C})}},show:{target:C,event:"mouseenter",effect:B,delay:90,solo:C,ready:C,autofocus:C},hide:{target:C,event:"mouseleave",effect:B,delay:0,fixed:C,inactive:C,leave:"window",distance:C},style:{classes:"",widget:C,width:C,height:C,def:B},events:{render:D,move:D,show:D,hide:D,toggle:D,visible:D,hidden:D,focus:D,blur:D}};var fa,ga,ha,ia,ja,ka="margin",la="border",ma="color",na="background-color",oa="transparent",pa=" !important",qa=!!b.createElement("canvas").getContext,ra=/rgba?\(0, 0, 0(, 0)?\)|transparent|#123456/i,sa={},ta=["Webkit","O","Moz","ms"];qa?(ia=a.devicePixelRatio||1,ja=function(){var a=b.createElement("canvas").getContext("2d");return a.backingStorePixelRatio||a.webkitBackingStorePixelRatio||a.mozBackingStorePixelRatio||a.msBackingStorePixelRatio||a.oBackingStorePixelRatio||1}(),ha=ia/ja):ga=function(a,b,c){return"<qtipvml:"+a+' xmlns="urn:schemas-microsoft.com:vml" class="qtip-vml" '+(b||"")+' style="behavior: url(#default#VML); '+(c||"")+'" />'},d.extend(v.prototype,{init:function(a){var b,c;c=this.element=a.elements.tip=d("<div />",{"class":Q+"-tip"}).prependTo(a.tooltip),qa?(b=d("<canvas />").appendTo(this.element)[0].getContext("2d"),b.lineJoin="miter",b.miterLimit=1e5,b.save()):(b=ga("shape",'coordorigin="0,0"',"position:absolute;"),this.element.html(b+b),a._bind(d("*",c).add(c),["click","mousedown"],function(a){a.stopPropagation()},this._ns)),a._bind(a.tooltip,"tooltipmove",this.reposition,this._ns,this),this.create()},_swapDimensions:function(){this.size[0]=this.options.height,this.size[1]=this.options.width},_resetDimensions:function(){this.size[0]=this.options.width,this.size[1]=this.options.height},_useTitle:function(a){var b=this.qtip.elements.titlebar;return b&&(a.y===I||a.y===M&&this.element.position().top+this.size[1]/2+this.options.offset<b.outerHeight(B))},_parseCorner:function(a){var b=this.qtip.options.position.my;return a===C||b===C?a=C:a===B?a=new y(b.string()):a.string||(a=new y(a),a.fixed=B),a},_parseWidth:function(a,b,c){var d=this.qtip.elements,e=la+s(b)+"Width";return(c?u(c,e):u(d.content,e)||u(this._useTitle(a)&&d.titlebar||d.content,e)||u(d.tooltip,e))||0},_parseRadius:function(a){var b=this.qtip.elements,c=la+s(a.y)+s(a.x)+"Radius";return ba.ie<9?0:u(this._useTitle(a)&&b.titlebar||b.content,c)||u(b.tooltip,c)||0},_invalidColour:function(a,b,c){var d=a.css(b);return!d||c&&d===a.css(c)||ra.test(d)?C:d},_parseColours:function(a){var b=this.qtip.elements,c=this.element.css("cssText",""),e=la+s(a[a.precedance])+s(ma),f=this._useTitle(a)&&b.titlebar||b.content,g=this._invalidColour,h=[];return h[0]=g(c,na)||g(f,na)||g(b.content,na)||g(b.tooltip,na)||c.css(na),h[1]=g(c,e,ma)||g(f,e,ma)||g(b.content,e,ma)||g(b.tooltip,e,ma)||b.tooltip.css(e),d("*",c).add(c).css("cssText",na+":"+oa+pa+";"+la+":0"+pa+";"),h},_calculateSize:function(a){var b,c,d,e=a.precedance===F,f=this.options.width,g=this.options.height,h="c"===a.abbrev(),i=(e?f:g)*(h?.5:1),j=Math.pow,k=Math.round,l=Math.sqrt(j(i,2)+j(g,2)),m=[this.border/i*l,this.border/g*l];return m[2]=Math.sqrt(j(m[0],2)-j(this.border,2)),m[3]=Math.sqrt(j(m[1],2)-j(this.border,2)),b=l+m[2]+m[3]+(h?0:m[0]),c=b/l,d=[k(c*f),k(c*g)],e?d:d.reverse()},_calculateTip:function(a,b,c){c=c||1,b=b||this.size;var d=b[0]*c,e=b[1]*c,f=Math.ceil(d/2),g=Math.ceil(e/2),h={br:[0,0,d,e,d,0],bl:[0,0,d,0,0,e],tr:[0,e,d,0,d,e],tl:[0,0,0,e,d,e],tc:[0,e,f,0,d,e],bc:[0,0,d,0,f,e],rc:[0,0,d,g,0,e],lc:[d,0,d,e,0,g]};return h.lt=h.br,h.rt=h.bl,h.lb=h.tr,h.rb=h.tl,h[a.abbrev()]},_drawCoords:function(a,b){a.beginPath(),a.moveTo(b[0],b[1]),a.lineTo(b[2],b[3]),a.lineTo(b[4],b[5]),a.closePath()},create:function(){var a=this.corner=(qa||ba.ie)&&this._parseCorner(this.options.corner);return this.enabled=!!this.corner&&"c"!==this.corner.abbrev(),this.enabled&&(this.qtip.cache.corner=a.clone(),this.update()),this.element.toggle(this.enabled),this.corner},update:function(b,c){if(!this.enabled)return this;var e,f,g,h,i,j,k,l,m=this.qtip.elements,n=this.element,o=n.children(),p=this.options,q=this.size,r=p.mimic,s=Math.round;b||(b=this.qtip.cache.corner||this.corner),r===C?r=b:(r=new y(r),r.precedance=b.precedance,"inherit"===r.x?r.x=b.x:"inherit"===r.y?r.y=b.y:r.x===r.y&&(r[b.precedance]=b[b.precedance])),f=r.precedance,b.precedance===E?this._swapDimensions():this._resetDimensions(),e=this.color=this._parseColours(b),e[1]!==oa?(l=this.border=this._parseWidth(b,b[b.precedance]),p.border&&1>l&&!ra.test(e[1])&&(e[0]=e[1]),this.border=l=p.border!==B?p.border:l):this.border=l=0,k=this.size=this._calculateSize(b),n.css({width:k[0],height:k[1],lineHeight:k[1]+"px"}),j=b.precedance===F?[s(r.x===J?l:r.x===L?k[0]-q[0]-l:(k[0]-q[0])/2),s(r.y===I?k[1]-q[1]:0)]:[s(r.x===J?k[0]-q[0]:0),s(r.y===I?l:r.y===K?k[1]-q[1]-l:(k[1]-q[1])/2)],qa?(g=o[0].getContext("2d"),g.restore(),g.save(),g.clearRect(0,0,6e3,6e3),h=this._calculateTip(r,q,ha),i=this._calculateTip(r,this.size,ha),o.attr(G,k[0]*ha).attr(H,k[1]*ha),o.css(G,k[0]).css(H,k[1]),this._drawCoords(g,i),g.fillStyle=e[1],g.fill(),g.translate(j[0]*ha,j[1]*ha),this._drawCoords(g,h),g.fillStyle=e[0],g.fill()):(h=this._calculateTip(r),h="m"+h[0]+","+h[1]+" l"+h[2]+","+h[3]+" "+h[4]+","+h[5]+" xe",j[2]=l&&/^(r|b)/i.test(b.string())?8===ba.ie?2:1:0,o.css({coordsize:k[0]+l+" "+k[1]+l,antialias:""+(r.string().indexOf(M)>-1),left:j[0]-j[2]*Number(f===E),top:j[1]-j[2]*Number(f===F),width:k[0]+l,height:k[1]+l}).each(function(a){var b=d(this);b[b.prop?"prop":"attr"]({coordsize:k[0]+l+" "+k[1]+l,path:h,fillcolor:e[0],filled:!!a,stroked:!a}).toggle(!(!l&&!a)),!a&&b.html(ga("stroke",'weight="'+2*l+'px" color="'+e[1]+'" miterlimit="1000" joinstyle="miter"'))})),a.opera&&setTimeout(function(){m.tip.css({display:"inline-block",visibility:"visible"})},1),c!==C&&this.calculate(b,k)},calculate:function(a,b){if(!this.enabled)return C;var c,e,f=this,g=this.qtip.elements,h=this.element,i=this.options.offset,j={};return a=a||this.corner,c=a.precedance,b=b||this._calculateSize(a),e=[a.x,a.y],c===E&&e.reverse(),d.each(e,function(d,e){var h,k,l;e===M?(h=c===F?J:I,j[h]="50%",j[ka+"-"+h]=-Math.round(b[c===F?0:1]/2)+i):(h=f._parseWidth(a,e,g.tooltip),k=f._parseWidth(a,e,g.content),l=f._parseRadius(a),j[e]=Math.max(-f.border,d?k:i+(l>h?l:-h)))}),j[a[c]]-=b[c===E?0:1],h.css({margin:"",top:"",bottom:"",left:"",right:""}).css(j),j},reposition:function(a,b,d){function e(a,b,c,d,e){a===O&&j.precedance===b&&k[d]&&j[c]!==M?j.precedance=j.precedance===E?F:E:a!==O&&k[d]&&(j[b]=j[b]===M?k[d]>0?d:e:j[b]===d?e:d)}function f(a,b,e){j[a]===M?p[ka+"-"+b]=o[a]=g[ka+"-"+b]-k[b]:(h=g[e]!==c?[k[b],-g[b]]:[-k[b],g[b]],(o[a]=Math.max(h[0],h[1]))>h[0]&&(d[b]-=k[b],o[b]=C),p[g[e]!==c?e:b]=o[a])}if(this.enabled){var g,h,i=b.cache,j=this.corner.clone(),k=d.adjusted,l=b.options.position.adjust.method.split(" "),m=l[0],n=l[1]||l[0],o={left:C,top:C,x:0,y:0},p={};this.corner.fixed!==B&&(e(m,E,F,J,L),e(n,F,E,I,K),j.string()===i.corner.string()&&i.cornerTop===k.top&&i.cornerLeft===k.left||this.update(j,C)),g=this.calculate(j),g.right!==c&&(g.left=-g.right),g.bottom!==c&&(g.top=-g.bottom),g.user=this.offset,o.left=m===O&&!!k.left,o.left&&f(E,J,L),o.top=n===O&&!!k.top,o.top&&f(F,I,K),this.element.css(p).toggle(!(o.x&&o.y||j.x===M&&o.y||j.y===M&&o.x)),d.left-=g.left.charAt?g.user:m!==O||o.top||!o.left&&!o.top?g.left+this.border:0,d.top-=g.top.charAt?g.user:n!==O||o.left||!o.left&&!o.top?g.top+this.border:0,i.cornerLeft=k.left,i.cornerTop=k.top,i.corner=j.clone()}},destroy:function(){this.qtip._unbind(this.qtip.tooltip,this._ns),this.qtip.elements.tip&&this.qtip.elements.tip.find("*").remove().end().remove()}}),fa=P.tip=function(a){return new v(a,a.options.style.tip)},fa.initialize="render",fa.sanitize=function(a){if(a.style&&"tip"in a.style){var b=a.style.tip;"object"!=typeof b&&(b=a.style.tip={corner:b}),/string|boolean/i.test(typeof b.corner)||(b.corner=B)}},z.tip={"^position.my|style.tip.(corner|mimic|border)$":function(){this.create(),this.qtip.reposition()},"^style.tip.(height|width)$":function(a){this.size=[a.width,a.height],this.update(),this.qtip.reposition()},"^content.title|style.(classes|widget)$":function(){this.update()}},d.extend(B,w.defaults,{style:{tip:{corner:B,mimic:C,width:6,height:6,border:B,offset:0}}}),P.viewport=function(c,d,e,f,g,h,i){function j(a,b,c,e,f,g,h,i,j){var k=d[f],s=u[a],t=v[a],w=c===O,x=s===f?j:s===g?-j:-j/2,y=t===f?i:t===g?-i:-i/2,z=q[f]+r[f]-(n?0:m[f]),A=z-k,B=k+j-(h===G?o:p)-z,C=x-(u.precedance===a||s===u[b]?y:0)-(t===M?i/2:0);return w?(C=(s===f?1:-1)*x,d[f]+=A>0?A:B>0?-B:0,d[f]=Math.max(-m[f]+r[f],k-C,Math.min(Math.max(-m[f]+r[f]+(h===G?o:p),k+C),d[f],"center"===s?k-x:1e9))):(e*=c===N?2:0,A>0&&(s!==f||B>0)?(d[f]-=C+e,l.invert(a,f)):B>0&&(s!==g||A>0)&&(d[f]-=(s===M?-C:C)+e,l.invert(a,g)),d[f]<q[f]&&-d[f]>B&&(d[f]=k,l=u.clone())),d[f]-k}var k,l,m,n,o,p,q,r,s=e.target,t=c.elements.tooltip,u=e.my,v=e.at,w=e.adjust,x=w.method.split(" "),y=x[0],z=x[1]||x[0],A=e.viewport,B=e.container,D={left:0,top:0};return A.jquery&&s[0]!==a&&s[0]!==b.body&&"none"!==w.method?(m=B.offset()||D,n="static"===B.css("position"),k="fixed"===t.css("position"),o=A[0]===a?A.width():A.outerWidth(C),p=A[0]===a?A.height():A.outerHeight(C),q={left:k?0:A.scrollLeft(),top:k?0:A.scrollTop()},r=A.offset()||D,"shift"===y&&"shift"===z||(l=u.clone()),D={left:"none"!==y?j(E,F,y,w.x,J,L,G,f,h):0,top:"none"!==z?j(F,E,z,w.y,I,K,H,g,i):0,my:l}):D}})}(window,document);
|
510 |
-
|
511 |
-
/*
|
512 |
-
(function(a,b){if('function'==typeof define&&define.amd)define(['jquery'],b);else if('undefined'!=typeof exports)b(require('jquery'));else{b(a.jquery),a.bootstrapSwitch={exports:{}}.exports}})(this,function(a){'use strict';function c(j,k){if(!(j instanceof k))throw new TypeError('Cannot call a class as a function')}var d=function(j){return j&&j.__esModule?j:{default:j}}(a),e=Object.assign||function(j){for(var l,k=1;k<arguments.length;k++)for(var m in l=arguments[k],l)Object.prototype.hasOwnProperty.call(l,m)&&(j[m]=l[m]);return j},f=function(){function j(k,l){for(var n,m=0;m<l.length;m++)n=l[m],n.enumerable=n.enumerable||!1,n.configurable=!0,'value'in n&&(n.writable=!0),Object.defineProperty(k,n.key,n)}return function(k,l,m){return l&&j(k.prototype,l),m&&j(k,m),k}}(),g=d.default||window.jQuery||window.$,h=function(){function j(k){var l=this,m=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{};c(this,j),this.$element=g(k),this.options=g.extend({},g.fn.bootstrapSwitch.defaults,this._getElementOptions(),m),this.prevOptions={},this.$wrapper=g('<div>',{class:function(){var o=[];return o.push(l.options.state?'on':'off'),l.options.size&&o.push(l.options.size),l.options.disabled&&o.push('disabled'),l.options.readonly&&o.push('readonly'),l.options.indeterminate&&o.push('indeterminate'),l.options.inverse&&o.push('inverse'),l.$element.attr('id')&&o.push('id-'+l.$element.attr('id')),o.map(l._getClass.bind(l)).concat([l.options.baseClass],l._getClasses(l.options.wrapperClass)).join(' ')}}),this.$container=g('<div>',{class:this._getClass('container')}),this.$on=g('<span>',{html:this.options.onText,class:this._getClass('handle-on')+' '+this._getClass(this.options.onColor)}),this.$off=g('<span>',{html:this.options.offText,class:this._getClass('handle-off')+' '+this._getClass(this.options.offColor)}),this.$label=g('<span>',{html:this.options.labelText,class:this._getClass('label')}),this.$element.on('init.bootstrapSwitch',this.options.onInit.bind(this,k)),this.$element.on('switchChange.bootstrapSwitch',function(){for(var n=arguments.length,o=Array(n),p=0;p<n;p++)o[p]=arguments[p];!1===l.options.onSwitchChange.apply(k,o)&&(l.$element.is(':radio')?g('[name="'+l.$element.attr('name')+'"]').trigger('previousState.bootstrapSwitch',!0):l.$element.trigger('previousState.bootstrapSwitch',!0))}),this.$container=this.$element.wrap(this.$container).parent(),this.$wrapper=this.$container.wrap(this.$wrapper).parent(),this.$element.before(this.options.inverse?this.$off:this.$on).before(this.$label).before(this.options.inverse?this.$on:this.$off),this.options.indeterminate&&this.$element.prop('indeterminate',!0),this._init(),this._elementHandlers(),this._handleHandlers(),this._labelHandlers(),this._formHandler(),this._externalLabelHandler(),this.$element.trigger('init.bootstrapSwitch',this.options.state)}return f(j,[{key:'setPrevOptions',value:function(){this.prevOptions=e({},this.options)}},{key:'state',value:function(l,m){return'undefined'==typeof l?this.options.state:this.options.disabled||this.options.readonly||this.options.state&&!this.options.radioAllOff&&this.$element.is(':radio')?this.$element:(this.$element.is(':radio')?g('[name="'+this.$element.attr('name')+'"]').trigger('setPreviousOptions.bootstrapSwitch'):this.$element.trigger('setPreviousOptions.bootstrapSwitch'),this.options.indeterminate&&this.indeterminate(!1),this.$element.prop('checked',!!l).trigger('change.bootstrapSwitch',m),this.$element)}},{key:'toggleState',value:function(l){return this.options.disabled||this.options.readonly?this.$element:this.options.indeterminate?(this.indeterminate(!1),this.state(!0)):this.$element.prop('checked',!this.options.state).trigger('change.bootstrapSwitch',l)}},{key:'size',value:function(l){return'undefined'==typeof l?this.options.size:(null!=this.options.size&&this.$wrapper.removeClass(this._getClass(this.options.size)),l&&this.$wrapper.addClass(this._getClass(l)),this._width(),this._containerPosition(),this.options.size=l,this.$element)}},{key:'animate',value:function(l){return'undefined'==typeof l?this.options.animate:this.options.animate===!!l?this.$element:this.toggleAnimate()}},{key:'toggleAnimate',value:function(){return this.options.animate=!this.options.animate,this.$wrapper.toggleClass(this._getClass('animate')),this.$element}},{key:'disabled',value:function(l){return'undefined'==typeof l?this.options.disabled:this.options.disabled===!!l?this.$element:this.toggleDisabled()}},{key:'toggleDisabled',value:function(){return this.options.disabled=!this.options.disabled,this.$element.prop('disabled',this.options.disabled),this.$wrapper.toggleClass(this._getClass('disabled')),this.$element}},{key:'readonly',value:function(l){return'undefined'==typeof l?this.options.readonly:this.options.readonly===!!l?this.$element:this.toggleReadonly()}},{key:'toggleReadonly',value:function(){return this.options.readonly=!this.options.readonly,this.$element.prop('readonly',this.options.readonly),this.$wrapper.toggleClass(this._getClass('readonly')),this.$element}},{key:'indeterminate',value:function(l){return'undefined'==typeof l?this.options.indeterminate:this.options.indeterminate===!!l?this.$element:this.toggleIndeterminate()}},{key:'toggleIndeterminate',value:function(){return this.options.indeterminate=!this.options.indeterminate,this.$element.prop('indeterminate',this.options.indeterminate),this.$wrapper.toggleClass(this._getClass('indeterminate')),this._containerPosition(),this.$element}},{key:'inverse',value:function(l){return'undefined'==typeof l?this.options.inverse:this.options.inverse===!!l?this.$element:this.toggleInverse()}},{key:'toggleInverse',value:function(){this.$wrapper.toggleClass(this._getClass('inverse'));var l=this.$on.clone(!0),m=this.$off.clone(!0);return this.$on.replaceWith(m),this.$off.replaceWith(l),this.$on=m,this.$off=l,this.options.inverse=!this.options.inverse,this.$element}},{key:'onColor',value:function(l){return'undefined'==typeof l?this.options.onColor:(this.options.onColor&&this.$on.removeClass(this._getClass(this.options.onColor)),this.$on.addClass(this._getClass(l)),this.options.onColor=l,this.$element)}},{key:'offColor',value:function(l){return'undefined'==typeof l?this.options.offColor:(this.options.offColor&&this.$off.removeClass(this._getClass(this.options.offColor)),this.$off.addClass(this._getClass(l)),this.options.offColor=l,this.$element)}},{key:'onText',value:function(l){return'undefined'==typeof l?this.options.onText:(this.$on.html(l),this._width(),this._containerPosition(),this.options.onText=l,this.$element)}},{key:'offText',value:function(l){return'undefined'==typeof l?this.options.offText:(this.$off.html(l),this._width(),this._containerPosition(),this.options.offText=l,this.$element)}},{key:'labelText',value:function(l){return'undefined'==typeof l?this.options.labelText:(this.$label.html(l),this._width(),this.options.labelText=l,this.$element)}},{key:'handleWidth',value:function(l){return'undefined'==typeof l?this.options.handleWidth:(this.options.handleWidth=l,this._width(),this._containerPosition(),this.$element)}},{key:'labelWidth',value:function(l){return'undefined'==typeof l?this.options.labelWidth:(this.options.labelWidth=l,this._width(),this._containerPosition(),this.$element)}},{key:'baseClass',value:function(){return this.options.baseClass}},{key:'wrapperClass',value:function(l){return'undefined'==typeof l?this.options.wrapperClass:(l||(l=g.fn.bootstrapSwitch.defaults.wrapperClass),this.$wrapper.removeClass(this._getClasses(this.options.wrapperClass).join(' ')),this.$wrapper.addClass(this._getClasses(l).join(' ')),this.options.wrapperClass=l,this.$element)}},{key:'radioAllOff',value:function(l){if('undefined'==typeof l)return this.options.radioAllOff;var m=!!l;return this.options.radioAllOff===m?this.$element:(this.options.radioAllOff=m,this.$element)}},{key:'onInit',value:function(l){return'undefined'==typeof l?this.options.onInit:(l||(l=g.fn.bootstrapSwitch.defaults.onInit),this.options.onInit=l,this.$element)}},{key:'onSwitchChange',value:function(l){return'undefined'==typeof l?this.options.onSwitchChange:(l||(l=g.fn.bootstrapSwitch.defaults.onSwitchChange),this.options.onSwitchChange=l,this.$element)}},{key:'destroy',value:function(){var l=this.$element.closest('form');return l.length&&l.off('reset.bootstrapSwitch').removeData('bootstrap-switch'),this.$container.children().not(this.$element).remove(),this.$element.unwrap().unwrap().off('.bootstrapSwitch').removeData('bootstrap-switch'),this.$element}},{key:'_getElementOptions',value:function(){return{state:this.$element.is(':checked'),size:this.$element.data('size'),animate:this.$element.data('animate'),disabled:this.$element.is(':disabled'),readonly:this.$element.is('[readonly]'),indeterminate:this.$element.data('indeterminate'),inverse:this.$element.data('inverse'),radioAllOff:this.$element.data('radio-all-off'),onColor:this.$element.data('on-color'),offColor:this.$element.data('off-color'),onText:this.$element.data('on-text'),offText:this.$element.data('off-text'),labelText:this.$element.data('label-text'),handleWidth:this.$element.data('handle-width'),labelWidth:this.$element.data('label-width'),baseClass:this.$element.data('base-class'),wrapperClass:this.$element.data('wrapper-class')}}},{key:'_width',value:function(){var l=this,m=this.$on.add(this.$off).add(this.$label).css('width',''),n='auto'===this.options.handleWidth?Math.round(Math.max(this.$on.width(),this.$off.width())):this.options.handleWidth;return m.width(n),this.$label.width(function(o,p){return'auto'===l.options.labelWidth?p<n?n:p:l.options.labelWidth}),this._handleWidth=this.$on.outerWidth(),this._labelWidth=this.$label.outerWidth(),this.$container.width(2*this._handleWidth+this._labelWidth),this.$wrapper.width(this._handleWidth+this._labelWidth)}},{key:'_containerPosition',value:function(){var l=this,m=0<arguments.length&&void 0!==arguments[0]?arguments[0]:this.options.state,n=arguments[1];this.$container.css('margin-left',function(){var o=[0,'-'+l._handleWidth+'px'];return l.options.indeterminate?'-'+l._handleWidth/2+'px':m?l.options.inverse?o[1]:o[0]:l.options.inverse?o[0]:o[1]})}},{key:'_init',value:function(){var l=this,m=function(){l.setPrevOptions(),l._width(),l._containerPosition(),setTimeout(function(){if(l.options.animate)return l.$wrapper.addClass(l._getClass('animate'))},50)};if(this.$wrapper.is(':visible'))return void m();var n=window.setInterval(function(){if(l.$wrapper.is(':visible'))return m(),window.clearInterval(n)},50)}},{key:'_elementHandlers',value:function(){var l=this;return this.$element.on({'setPreviousOptions.bootstrapSwitch':this.setPrevOptions.bind(this),'previousState.bootstrapSwitch':function(){l.options=l.prevOptions,l.options.indeterminate&&l.$wrapper.addClass(l._getClass('indeterminate')),l.$element.prop('checked',l.options.state).trigger('change.bootstrapSwitch',!0)},'change.bootstrapSwitch':function(n,o){n.preventDefault(),n.stopImmediatePropagation();var p=l.$element.is(':checked');l._containerPosition(p),p===l.options.state||(l.options.state=p,l.$wrapper.toggleClass(l._getClass('off')).toggleClass(l._getClass('on')),!o&&(l.$element.is(':radio')&&g('[name="'+l.$element.attr('name')+'"]').not(l.$element).prop('checked',!1).trigger('change.bootstrapSwitch',!0),l.$element.trigger('switchChange.bootstrapSwitch',[p])))},'focus.bootstrapSwitch':function(n){n.preventDefault(),l.$wrapper.addClass(l._getClass('focused'))},'blur.bootstrapSwitch':function(n){n.preventDefault(),l.$wrapper.removeClass(l._getClass('focused'))},'keydown.bootstrapSwitch':function(n){!n.which||l.options.disabled||l.options.readonly||(37===n.which||39===n.which)&&(n.preventDefault(),n.stopImmediatePropagation(),l.state(39===n.which))}})}},{key:'_handleHandlers',value:function(){var l=this;return this.$on.on('click.bootstrapSwitch',function(m){return m.preventDefault(),m.stopPropagation(),l.state(!1),l.$element.trigger('focus.bootstrapSwitch')}),this.$off.on('click.bootstrapSwitch',function(m){return m.preventDefault(),m.stopPropagation(),l.state(!0),l.$element.trigger('focus.bootstrapSwitch')})}},{key:'_labelHandlers',value:function(){var l=this;this.$label.on({click:function(o){o.stopPropagation()},'mousedown.bootstrapSwitch touchstart.bootstrapSwitch':function(o){l._dragStart||l.options.disabled||l.options.readonly||(o.preventDefault(),o.stopPropagation(),l._dragStart=(o.pageX||o.originalEvent.touches[0].pageX)-parseInt(l.$container.css('margin-left'),10),l.options.animate&&l.$wrapper.removeClass(l._getClass('animate')),l.$element.trigger('focus.bootstrapSwitch'))},'mousemove.bootstrapSwitch touchmove.bootstrapSwitch':function(o){if(null!=l._dragStart){var p=(o.pageX||o.originalEvent.touches[0].pageX)-l._dragStart;o.preventDefault(),p<-l._handleWidth||0<p||(l._dragEnd=p,l.$container.css('margin-left',l._dragEnd+'px'))}},'mouseup.bootstrapSwitch touchend.bootstrapSwitch':function(o){if(l._dragStart){if(o.preventDefault(),l.options.animate&&l.$wrapper.addClass(l._getClass('animate')),l._dragEnd){var p=l._dragEnd>-(l._handleWidth/2);l._dragEnd=!1,l.state(l.options.inverse?!p:p)}else l.state(!l.options.state);l._dragStart=!1}},'mouseleave.bootstrapSwitch':function(){l.$label.trigger('mouseup.bootstrapSwitch')}})}},{key:'_externalLabelHandler',value:function(){var l=this,m=this.$element.closest('label');m.on('click',function(n){n.preventDefault(),n.stopImmediatePropagation(),n.target===m[0]&&l.toggleState()})}},{key:'_formHandler',value:function(){var l=this.$element.closest('form');l.data('bootstrap-switch')||l.on('reset.bootstrapSwitch',function(){window.setTimeout(function(){l.find('input').filter(function(){return g(this).data('bootstrap-switch')}).each(function(){return g(this).bootstrapSwitch('state',this.checked)})},1)}).data('bootstrap-switch',!0)}},{key:'_getClass',value:function(l){return this.options.baseClass+'-'+l}},{key:'_getClasses',value:function(l){return g.isArray(l)?l.map(this._getClass.bind(this)):[this._getClass(l)]}}]),j}();g.fn.bootstrapSwitch=function(j){for(var l=arguments.length,m=Array(1<l?l-1:0),n=1;n<l;n++)m[n-1]=arguments[n];return Array.prototype.reduce.call(this,function(o,p){var q=g(p),r=q.data('bootstrap-switch'),s=r||new h(p,j);return r||q.data('bootstrap-switch',s),'string'==typeof j?s[j].apply(s,m):o},this)},g.fn.bootstrapSwitch.Constructor=h,g.fn.bootstrapSwitch.defaults={state:!0,size:null,animate:!0,disabled:!1,readonly:!1,indeterminate:!1,inverse:!1,radioAllOff:!1,onColor:'primary',offColor:'default',onText:'ON',offText:'OFF',labelText:' ',handleWidth:'auto',labelWidth:'auto',baseClass:'bootstrap-switch',wrapperClass:'wrapper',onInit:function(){},onSwitchChange:function(){}}});
|
513 |
-
|
514 |
-
/*
|
515 |
-
!function(e){e.fn.caret=function(e){var t=this[0],n="true"===t.contentEditable;if(0==arguments.length){if(window.getSelection){if(n){t.focus();var o=window.getSelection().getRangeAt(0),r=o.cloneRange();return r.selectNodeContents(t),r.setEnd(o.endContainer,o.endOffset),r.toString().length}return t.selectionStart}if(document.selection){if(t.focus(),n){var o=document.selection.createRange(),r=document.body.createTextRange();return r.moveToElementText(t),r.setEndPoint("EndToEnd",o),r.text.length}var e=0,c=t.createTextRange(),r=document.selection.createRange().duplicate(),a=r.getBookmark();for(c.moveToBookmark(a);0!==c.moveStart("character",-1);)e++;return e}return t.selectionStart?t.selectionStart:0}if(-1==e&&(e=this[n?"text":"val"]().length),window.getSelection)n?(t.focus(),window.getSelection().collapse(t.firstChild,e)):t.setSelectionRange(e,e);else if(document.body.createTextRange)if(n){var c=document.body.createTextRange();c.moveToElementText(t),c.moveStart("character",e),c.collapse(!0),c.select()}else{var c=t.createTextRange();c.move("character",e),c.select()}return n||t.focus(),e}}(jQuery);
|
516 |
-
|
517 |
-
/*
|
|
|
|
|
|
|
518 |
!function(t){t.fn.tagEditorInput=function(){var e=" ",i=t(this),a=parseInt(i.css("fontSize")),r=t("<span/>").css({position:"absolute",top:-9999,left:-9999,width:"auto",fontSize:i.css("fontSize"),fontFamily:i.css("fontFamily"),fontWeight:i.css("fontWeight"),letterSpacing:i.css("letterSpacing"),whiteSpace:"nowrap"}),l=function(){if(e!==(e=i.val())){r.text(e);var t=r.width()+a;20>t&&(t=20),t!=i.width()&&i.width(t)}};return r.insertAfter(i),i.bind("keyup keydown focus",l)},t.fn.tagEditor=function(e,a,r){function l(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}var n,o=t.extend({},t.fn.tagEditor.defaults,e),c=this;if(o.dregex=new RegExp("["+o.delimiter.replace("-","-")+"]","g"),"string"==typeof e){var s=[];return c.each(function(){var i=t(this),l=i.data("options"),n=i.next(".tag-editor");if("getTags"==e)s.push({field:i[0],editor:n,tags:n.data("tags")});else if("addTag"==e){if(l.maxTags&&n.data("tags").length>=l.maxTags)return!1;t('<li><div class="tag-editor-spacer"> '+l.delimiter[0]+'</div><div class="tag-editor-tag"></div><div class="tag-editor-delete"><i></i></div></li>').appendTo(n).find(".tag-editor-tag").html('<input type="text" maxlength="'+l.maxLength+'">').addClass("active").find("input").val(a).blur(),r?t(".placeholder",n).remove():n.click()}else"removeTag"==e?(t(".tag-editor-tag",n).filter(function(){return t(this).text()==a}).closest("li").find(".tag-editor-delete").click(),r||n.click()):"destroy"==e&&i.removeClass("tag-editor-hidden-src").removeData("options").off("focus.tag-editor").next(".tag-editor").remove()}),"getTags"==e?s:this}return window.getSelection&&t(document).off("keydown.tag-editor").on("keydown.tag-editor",function(e){if(8==e.which||46==e.which||e.ctrlKey&&88==e.which){try{var a=getSelection(),r="INPUT"!=document.activeElement.tagName?t(a.getRangeAt(0).startContainer.parentNode).closest(".tag-editor"):0}catch(e){r=0}if(a.rangeCount>0&&r&&r.length){var l=[],n=a.toString().split(r.prev().data("options").dregex);for(i=0;i<n.length;i++){var o=t.trim(n[i]);o&&l.push(o)}return t(".tag-editor-tag",r).each(function(){~t.inArray(t(this).text(),l)&&t(this).closest("li").find(".tag-editor-delete").click()}),!1}}}),c.each(function(){function e(){!o.placeholder||c.length||t(".deleted, .placeholder, input",s).length||s.append('<li class="placeholder"><div>'+o.placeholder+"</div></li>")}function i(i){var a=c.toString();c=t(".tag-editor-tag:not(.deleted)",s).map(function(e,i){var a=t.trim(t(this).hasClass("active")?t(this).find("input").val():t(i).text());return a?a:void 0}).get(),s.data("tags",c),r.val(c.join(o.delimiter[0])),i||a!=c.toString()&&o.onChange(r,s,c),e()}function a(e){for(var a,n=e.closest("li"),d=e.val().replace(/ +/," ").split(o.dregex),g=e.data("old_tag"),f=c.slice(0),h=!1,u=0;u<d.length;u++)if(v=t.trim(d[u]).slice(0,o.maxLength),o.forceLowercase&&(v=v.toLowerCase()),a=o.beforeTagSave(r,s,f,g,v),v=a||v,a!==!1&&v&&(o.removeDuplicates&&~t.inArray(v,f)&&t(".tag-editor-tag",s).each(function(){t(this).text()==v&&t(this).closest("li").remove()}),f.push(v),n.before('<li><div class="tag-editor-spacer"> '+o.delimiter[0]+'</div><div class="tag-editor-tag">'+l(v)+'</div><div class="tag-editor-delete"><i></i></div></li>'),o.maxTags&&f.length>=o.maxTags)){h=!0;break}e.attr("maxlength",o.maxLength).removeData("old_tag").val(""),h?e.blur():e.focus(),i()}var r=t(this),c=[],s=t("<ul "+(o.clickDelete?'oncontextmenu="return false;" ':"")+'class="tag-editor"></ul>').insertAfter(r);r.addClass("tag-editor-hidden-src").data("options",o).on("focus.tag-editor",function(){s.click()}),s.append('<li style="width:1px"> </li>');var d='<li><div class="tag-editor-spacer"> '+o.delimiter[0]+'</div><div class="tag-editor-tag"></div><div class="tag-editor-delete"><i></i></div></li>';s.click(function(e,i){var a,r,l=99999;if(!window.getSelection||""==getSelection())return o.maxTags&&s.data("tags").length>=o.maxTags?(s.find("input").blur(),!1):(n=!0,t("input:focus",s).blur(),n?(n=!0,t(".placeholder",s).remove(),i&&i.length?r="before":t(".tag-editor-tag",s).each(function(){var n=t(this),o=n.offset(),c=o.left,s=o.top;e.pageY>=s&&e.pageY<=s+n.height()&&(e.pageX<c?(r="before",a=c-e.pageX):(r="after",a=e.pageX-c-n.width()),l>a&&(l=a,i=n))}),"before"==r?t(d).insertBefore(i.closest("li")).find(".tag-editor-tag").click():"after"==r?t(d).insertAfter(i.closest("li")).find(".tag-editor-tag").click():t(d).appendTo(s).find(".tag-editor-tag").click(),!1):!1)}),s.on("click",".tag-editor-delete",function(){if(t(this).prev().hasClass("active"))return t(this).closest("li").find("input").caret(-1),!1;var a=t(this).closest("li"),l=a.find(".tag-editor-tag");return o.beforeTagDelete(r,s,c,l.text())===!1?!1:(l.addClass("deleted").animate({width:0},o.animateDelete,function(){a.remove(),e()}),i(),!1)}),o.clickDelete&&s.on("mousedown",".tag-editor-tag",function(a){if(a.ctrlKey||a.which>1){var l=t(this).closest("li"),n=l.find(".tag-editor-tag");return o.beforeTagDelete(r,s,c,n.text())===!1?!1:(n.addClass("deleted").animate({width:0},o.animateDelete,function(){l.remove(),e()}),i(),!1)}}),s.on("click",".tag-editor-tag",function(e){if(o.clickDelete&&(e.ctrlKey||e.which>1))return!1;if(!t(this).hasClass("active")){var i=t(this).text(),a=Math.abs((t(this).offset().left-e.pageX)/t(this).width()),r=parseInt(i.length*a),n=t(this).html('<input type="text" maxlength="'+o.maxLength+'" value="'+l(i)+'">').addClass("active").find("input");if(n.data("old_tag",i).tagEditorInput().focus().caret(r),o.autocomplete){var c=t.extend({},o.autocomplete),d="select"in c?o.autocomplete.select:"";c.select=function(e,i){d&&d(e,i),setTimeout(function(){s.trigger("click",[t(".active",s).find("input").closest("li").next("li").find(".tag-editor-tag")])},20)},n.autocomplete(c)}}return!1}),s.on("blur","input",function(d){d.stopPropagation();var g=t(this),f=g.data("old_tag"),h=t.trim(g.val().replace(/ +/," ").replace(o.dregex,o.delimiter[0]));if(h){if(h.indexOf(o.delimiter[0])>=0)return void a(g);if(h!=f)if(o.forceLowercase&&(h=h.toLowerCase()),cb_val=o.beforeTagSave(r,s,c,f,h),h=cb_val||h,cb_val===!1){if(f)return g.val(f).focus(),n=!1,void i();try{g.closest("li").remove()}catch(d){}f&&i()}else o.removeDuplicates&&t(".tag-editor-tag:not(.active)",s).each(function(){t(this).text()==h&&t(this).closest("li").remove()})}else{if(f&&o.beforeTagDelete(r,s,c,f)===!1)return g.val(f).focus(),n=!1,void i();try{g.closest("li").remove()}catch(d){}f&&i()}g.parent().html(l(h)).removeClass("active"),h!=f&&i(),e()});var g;s.on("paste","input",function(){t(this).removeAttr("maxlength"),g=t(this),setTimeout(function(){a(g)},30)});var f;s.on("keypress","input",function(e){o.delimiter.indexOf(String.fromCharCode(e.which))>=0&&(f=t(this),setTimeout(function(){a(f)},20))}),s.on("keydown","input",function(e){var i=t(this);if((37==e.which||!o.autocomplete&&38==e.which)&&!i.caret()||8==e.which&&!i.val()){var a=i.closest("li").prev("li").find(".tag-editor-tag");return a.length?a.click().find("input").caret(-1):!i.val()||o.maxTags&&s.data("tags").length>=o.maxTags||t(d).insertBefore(i.closest("li")).find(".tag-editor-tag").click(),!1}if((39==e.which||!o.autocomplete&&40==e.which)&&i.caret()==i.val().length){var l=i.closest("li").next("li").find(".tag-editor-tag");return l.length?l.click().find("input").caret(0):i.val()&&s.click(),!1}if(9==e.which){if(e.shiftKey){var a=i.closest("li").prev("li").find(".tag-editor-tag");if(a.length)a.click().find("input").caret(0);else{if(!i.val()||o.maxTags&&s.data("tags").length>=o.maxTags)return r.attr("disabled","disabled"),void setTimeout(function(){r.removeAttr("disabled")},30);t(d).insertBefore(i.closest("li")).find(".tag-editor-tag").click()}return!1}var l=i.closest("li").next("li").find(".tag-editor-tag");if(l.length)l.click().find("input").caret(0);else{if(!i.val())return;s.click()}return!1}if(!(46!=e.which||t.trim(i.val())&&i.caret()!=i.val().length)){var l=i.closest("li").next("li").find(".tag-editor-tag");return l.length?l.click().find("input").caret(0):i.val()&&s.click(),!1}if(13==e.which)return s.trigger("click",[i.closest("li").next("li").find(".tag-editor-tag")]),o.maxTags&&s.data("tags").length>=o.maxTags&&s.find("input").blur(),!1;if(36!=e.which||i.caret()){if(35==e.which&&i.caret()==i.val().length)s.find(".tag-editor-tag").last().click();else if(27==e.which)return i.val(i.data("old_tag")?i.data("old_tag"):"").blur(),!1}else s.find(".tag-editor-tag").first().click()});for(var h=o.initialTags.length?o.initialTags:r.val().split(o.dregex),u=0;u<h.length&&!(o.maxTags&&u>=o.maxTags);u++){var v=t.trim(h[u].replace(/ +/," "));v&&(o.forceLowercase&&(v=v.toLowerCase()),c.push(v),s.append('<li><div class="tag-editor-spacer"> '+o.delimiter[0]+'</div><div class="tag-editor-tag">'+l(v)+'</div><div class="tag-editor-delete"><i></i></div></li>'))}i(!0),o.sortable&&t.fn.sortable&&s.sortable({distance:5,cancel:".tag-editor-spacer, input",helper:"clone",update:function(){i()}})})},t.fn.tagEditor.defaults={initialTags:[],maxTags:0,maxLength:50,delimiter:",;",placeholder:"",forceLowercase:!0,removeDuplicates:!0,clickDelete:!1,animateDelete:175,sortable:!0,autocomplete:null,onChange:function(){},beforeTagSave:function(){},beforeTagDelete:function(){}}}(jQuery);
|
1 |
+
if ( typeof SlimStatAdminParams == 'undefined' ) {
|
2 |
+
SlimStatAdminParams = {
|
3 |
+
refresh_interval: 0,
|
4 |
+
expand_details: 'no',
|
5 |
+
datepicker_image: '',
|
6 |
+
text_direction: ''
|
7 |
+
};
|
8 |
+
}
|
9 |
+
|
10 |
+
// ----- TABLE OF CONTENTS -----------------------------------------------------------
|
11 |
+
//
|
12 |
+
// 1. Data refresh
|
13 |
+
// 2. Filters
|
14 |
+
// 3. Activity log
|
15 |
+
// 4. Customizer
|
16 |
+
// 5. Miscellaneous
|
17 |
+
// 6. Init third-party libraries
|
18 |
+
//
|
19 |
+
// -----------------------------------------------------------------------------------
|
20 |
+
|
21 |
+
jQuery( function() {
|
22 |
+
|
23 |
+
// ----- BEGIN: DATA REFRESH -----------------------------------------------------
|
24 |
+
//
|
25 |
+
|
26 |
+
// Reload a report's data if it is (re)activated via the checkbox under Screen Options
|
27 |
+
jQuery( 'input.hide-postbox-tog[id^=slim_p]' ).on( 'click.postboxes', function () {
|
28 |
+
if ( jQuery( this ).prop( "checked" ) && jQuery( '#' + jQuery( this ).val() ).length ) {
|
29 |
+
SlimStatAdmin.refresh_report( jQuery( this ).val() );
|
30 |
+
}
|
31 |
+
});
|
32 |
+
|
33 |
+
// Reload a report's data if the corresponding refresh/pagination button is clicked
|
34 |
+
jQuery( document ).on( 'click', '[id^=slim_] .refresh', function( e ) {
|
35 |
+
e.preventDefault();
|
36 |
+
|
37 |
+
var id = jQuery( this ).parents( '.postbox' ).attr( 'id' );
|
38 |
+
|
39 |
+
// Is this a pagination link?
|
40 |
+
if ( typeof jQuery( this ).attr( 'href' ).split( '?' )[ 1 ] == 'string' ) {
|
41 |
+
clean_filters = SlimStatAdmin.get_query_string_filters( jQuery( this ).attr( 'href' ).split( '?' )[ 1 ].substring( 1 ) );
|
42 |
+
if ( typeof clean_filters[ 'fs[start_from]' ] == 'string' ) {
|
43 |
+
jQuery( '<input type="hidden" name="fs[start_from]" class="slimstat-post-filter slimstat-temp-filter" value="' + clean_filters[ 'fs[start_from]' ] + '">' ).appendTo( '#slimstat-filters-form' );
|
44 |
+
}
|
45 |
+
}
|
46 |
+
|
47 |
+
SlimStatAdmin.refresh_report( id );
|
48 |
+
|
49 |
+
// Remove any temporary filters (pagination) set here above
|
50 |
+
jQuery( '.slimstat-temp-filter' ).remove();
|
51 |
+
|
52 |
+
// Re-initialize SlimScroll on the new content
|
53 |
+
jQuery( '#' + id + ' .inside' ).slimScroll( {
|
54 |
+
scrollTo : '0px'
|
55 |
+
} );
|
56 |
+
} );
|
57 |
+
|
58 |
+
// Asynchronous reports are loaded dynamically after the page loads
|
59 |
+
if ( SlimStatAdminParams.async_load == 'on' ) {
|
60 |
+
jQuery( 'div[id^=slim_]' ).each( function() {
|
61 |
+
SlimStatAdmin.refresh_report( jQuery( this ).attr( 'id' ) );
|
62 |
+
} );
|
63 |
+
}
|
64 |
+
|
65 |
+
//
|
66 |
+
// ----- END: DATA REFRESH -------------------------------------------------------
|
67 |
+
|
68 |
+
// ----- BEGIN: FILTERS ----------------------------------------------------------
|
69 |
+
//
|
70 |
+
|
71 |
+
// Make input field read-only if certain operators are selected
|
72 |
+
jQuery( '#slimstat-filter-operator' ).on( 'change', function() {
|
73 |
+
if ( this.value == 'is_empty' || this.value == 'is_not_empty' ) {
|
74 |
+
jQuery( '#slimstat-filter-value' ).attr( 'readonly', 'readonly' );
|
75 |
+
}
|
76 |
+
else {
|
77 |
+
jQuery( '#slimstat-filter-value' ).removeAttr( 'readonly' );
|
78 |
+
}
|
79 |
+
} );
|
80 |
+
|
81 |
+
// Toggle the Date Filters dropdown menu
|
82 |
+
jQuery( '#slimstat-date-filters > a' ).on( 'click', function( e ) {
|
83 |
+
e.preventDefault();
|
84 |
+
jQuery( '#slimstat-date-filters > .dropdown' ).slideToggle( 250 );
|
85 |
+
} );
|
86 |
+
|
87 |
+
// Initialize the datepicker library and button (built-in)
|
88 |
+
if ( typeof jQuery( '.slimstat-filter-date' ).datepicker == 'function' ) {
|
89 |
+
jQuery( '.slimstat-filter-date' ).datepicker( {
|
90 |
+
buttonImage: SlimStatAdminParams.datepicker_image,
|
91 |
+
buttonImageOnly: true,
|
92 |
+
changeMonth: true,
|
93 |
+
changeYear: true,
|
94 |
+
dateFormat: 'yy-m-d',
|
95 |
+
maxDate: new Date,
|
96 |
+
nextText: '»',
|
97 |
+
prevText: '«',
|
98 |
+
showOn: 'both',
|
99 |
+
|
100 |
+
onClose: function( dateText, inst ) {
|
101 |
+
if ( dateText.length ) {
|
102 |
+
jQuery( '#slimstat-filter-hour' ).val( 0 );
|
103 |
+
jQuery( '#slimstat-filter-day' ).val( dateText.split( '-' )[ 2 ] );
|
104 |
+
jQuery( '#slimstat-filter-month' ).val( dateText.split( '-' )[ 1 ] );
|
105 |
+
jQuery( '#slimstat-filter-year' ).val( dateText.split( '-' )[ 0 ] );
|
106 |
+
jQuery( '#slimstat-filter-interval' ).val( -1 );
|
107 |
+
}
|
108 |
+
}
|
109 |
+
} );
|
110 |
+
}
|
111 |
+
|
112 |
+
// Save filters
|
113 |
+
jQuery( document ).on( 'click', '#slimstat-save-filter', function( e ) {
|
114 |
+
e.preventDefault();
|
115 |
+
|
116 |
+
data = {
|
117 |
+
action: 'slimstat_manage_filters',
|
118 |
+
security: jQuery( '#meta-box-order-nonce' ).val(),
|
119 |
+
type: 'save',
|
120 |
+
filter_array: jQuery( this ).attr( 'data-filter-array' )
|
121 |
+
};
|
122 |
+
|
123 |
+
var element = jQuery( this );
|
124 |
+
jQuery.post( ajaxurl, data, function( response ) {
|
125 |
+
element.text( response ).fadeOut( 1500 );
|
126 |
+
} );
|
127 |
+
} );
|
128 |
+
|
129 |
+
// Load saved filters: open a dialog with a list of filters
|
130 |
+
jQuery( document ).on( 'click', '#slimstat-load-saved-filters', function( e ) {
|
131 |
+
e.preventDefault();
|
132 |
+
var inner_html = '';
|
133 |
+
|
134 |
+
data = {
|
135 |
+
action: 'slimstat_manage_filters',
|
136 |
+
security: jQuery( '#meta-box-order-nonce' ).val(),
|
137 |
+
type: 'load',
|
138 |
+
page: SlimStatAdmin.get_current_tab()
|
139 |
+
};
|
140 |
+
|
141 |
+
var dialog_title = jQuery( this ).attr( 'title' ); // passed as an attribute so that it can be localized
|
142 |
+
jQuery.post( ajaxurl, data, function( response ) {
|
143 |
+
jQuery( '#slimstat-modal-dialog' ).dialog( {
|
144 |
+
dialogClass: 'slimstat',
|
145 |
+
title: dialog_title
|
146 |
+
} ).html( response ).dialog( 'open' );
|
147 |
+
} );
|
148 |
+
} );
|
149 |
+
|
150 |
+
// Delete saved filters
|
151 |
+
jQuery( document ).on( 'click', '.slimstat-delete-filter', function( e ) {
|
152 |
+
e.preventDefault();
|
153 |
+
|
154 |
+
data = {
|
155 |
+
action: 'slimstat_manage_filters',
|
156 |
+
security: jQuery( '#meta-box-order-nonce' ).val(),
|
157 |
+
page: SlimStatAdmin.get_current_tab(),
|
158 |
+
type: 'delete',
|
159 |
+
filter_id: jQuery( this ).attr( 'data-filter-id' )
|
160 |
+
};
|
161 |
+
|
162 |
+
jQuery.post( ajaxurl, data, function( response ) {
|
163 |
+
jQuery( '#slim_filters_overlay' ).parent().html( response );
|
164 |
+
} );
|
165 |
+
} );
|
166 |
+
|
167 |
+
// Since we handle all "filter links" as POST requests (see code here above), we need to add dummy form tag to the dashboard,
|
168 |
+
// for when our reports are displayed on that page
|
169 |
+
if ( !jQuery( '#slimstat-filters-form' ).length ) {
|
170 |
+
jQuery( '<form id="slimstat-filters-form" method="post"/>' ).appendTo('body');
|
171 |
+
}
|
172 |
+
|
173 |
+
|
174 |
+
jQuery( document ).on( 'click', '.slimstat-filter-link, #toplevel_page_slimview1 a, #wp-admin-bar-slimstat-header li a', function( e ) {
|
175 |
+
url = jQuery( this ).attr( 'href' );
|
176 |
+
|
177 |
+
// If this link doesn't have a valid HREF attribute, bail
|
178 |
+
if ( typeof url != 'string' ) {
|
179 |
+
return true;
|
180 |
+
}
|
181 |
+
|
182 |
+
e.preventDefault();
|
183 |
+
|
184 |
+
jQuery( 'form#slimstat-filters-form' ).attr( 'action', url.split( '?' )[ 0 ] + '?page=' + SlimStatAdmin.get_current_tab( url.split( '?' )[ 1 ] ) );
|
185 |
+
|
186 |
+
SlimStatAdmin.add_url_filters_to_form( url, typeof jQuery( this ).attr( 'data-reset-filters' ) != 'undefined' );
|
187 |
+
|
188 |
+
jQuery( '#slimstat-filters-form' ).submit();
|
189 |
+
|
190 |
+
return false;
|
191 |
+
});
|
192 |
+
|
193 |
+
//
|
194 |
+
// ----- END: FILTERS ------------------------------------------------------------
|
195 |
+
|
196 |
+
// ----- BEGIN: ACTIVITY LOG -----------------------------------------------------
|
197 |
+
//
|
198 |
+
|
199 |
+
// Reload the Activity Log every X seconds
|
200 |
+
if ( SlimStatAdminParams.refresh_interval > 0 && jQuery( '.refresh-timer' ).length > 0 ) {
|
201 |
+
SlimStatAdmin._refresh_timer = parseInt( SlimStatAdminParams.refresh_interval );
|
202 |
+
window.setTimeout( "SlimStatAdmin.refresh_countdown();", 1000 );
|
203 |
+
}
|
204 |
+
|
205 |
+
// Delete a pageview when the corresponding button is clicked.
|
206 |
+
// Since this content can be reloaded dynamically, we use the .on call with the classname
|
207 |
+
jQuery( document ).on( 'click', '.slimstat-delete-entry', function( e ) {
|
208 |
+
e.preventDefault();
|
209 |
+
|
210 |
+
data = {
|
211 |
+
action: 'slimstat_delete_pageview',
|
212 |
+
security: jQuery( '#meta-box-order-nonce' ).val(),
|
213 |
+
pageview_id : jQuery( this ).attr( 'data-pageview-id' )
|
214 |
+
};
|
215 |
+
|
216 |
+
var parent = jQuery( this ).parents( 'p' );
|
217 |
+
jQuery.post( ajaxurl, data, function( response ) {
|
218 |
+
parent.fadeOut( 500 );
|
219 |
+
} );
|
220 |
+
} );
|
221 |
+
|
222 |
+
// // Modal Window / Whois
|
223 |
+
jQuery( document ).on( 'click', '.whois', function( e ) {
|
224 |
+
e.preventDefault();
|
225 |
+
|
226 |
+
// If admin is using HTTPS and IP lookup service is not, open a new window/tab, instead of an overlay dialog
|
227 |
+
if ( document.location.href.substr( 0, document.location.href.indexOf( "://" ) ).toLowerCase() == 'https' && jQuery( this ).attr( 'href' ).substr( 0, jQuery( this ).attr( 'href' ).indexOf( "://" ) ).toLowerCase() == 'http' ) {
|
228 |
+
window.open( jQuery( this ).attr( 'href' ), '_blank' );
|
229 |
+
return -1;
|
230 |
+
}
|
231 |
+
|
232 |
+
jQuery('#slimstat-modal-dialog').dialog({
|
233 |
+
dialogClass: 'slimstat',
|
234 |
+
title: jQuery(this).attr('title')
|
235 |
+
}).html('<iframe id="ip2location" src="'+jQuery(this).attr('href')+'" width="100%" height="630"></iframe>');
|
236 |
+
jQuery('#slimstat-modal-dialog').dialog('open');
|
237 |
+
});
|
238 |
+
|
239 |
+
//
|
240 |
+
// ----- END: ACTIVITY LOG -------------------------------------------------------
|
241 |
+
|
242 |
+
// ----- BEGIN: CUSTOMIZER -------------------------------------------------------
|
243 |
+
//
|
244 |
+
|
245 |
+
// Clone and delete report placeholders
|
246 |
+
jQuery( '.slimstat-layout .slimstat-header-buttons a' ).on( 'click', function() {
|
247 |
+
if ( jQuery( this ).hasClass( 'slimstat-font-docs' ) ) {
|
248 |
+
jQuery( this ).removeClass( 'slimstat-font-docs' ).addClass( 'slimstat-font-trash' ).parents( '.postbox' ).clone( true ).appendTo( jQuery( this ).parents( '.meta-box-sortables' ) );
|
249 |
+
jQuery( this ).removeClass( 'slimstat-font-trash' ).addClass( 'slimstat-font-docs' );
|
250 |
+
}
|
251 |
+
else if ( jQuery( this ).hasClass( 'slimstat-font-minus-circled' ) ) {
|
252 |
+
jQuery( this ).removeClass( 'slimstat-font-minus-circled' ).parents( '.postbox' ).appendTo( jQuery( '#postbox-container-inactive .meta-box-sortables' ) );
|
253 |
+
}
|
254 |
+
else {
|
255 |
+
jQuery( this ).parents( '.postbox' ).remove();
|
256 |
+
}
|
257 |
+
|
258 |
+
// Save the new groups
|
259 |
+
var data = {
|
260 |
+
action: 'meta-box-order',
|
261 |
+
_ajax_nonce: jQuery( '#meta-box-order-nonce' ).val(),
|
262 |
+
page: 'slimstat_page_slimlayout',
|
263 |
+
page_columns: 0
|
264 |
+
};
|
265 |
+
|
266 |
+
jQuery( '.meta-box-sortables' ).each( function() {
|
267 |
+
data[ 'order[' + this.id.split("-")[0] + ']' ] = jQuery( this ).sortable( 'toArray' ).join( ',' );
|
268 |
+
});
|
269 |
+
|
270 |
+
jQuery.post( ajaxurl, data );
|
271 |
+
} );
|
272 |
+
|
273 |
+
//
|
274 |
+
// ----- END: CUSTOMIZER ---------------------------------------------------------
|
275 |
+
|
276 |
+
// ----- BEGIN: MISCELLANEOUS ----------------------------------------------------
|
277 |
+
//
|
278 |
+
|
279 |
+
// Hide a notice and send the corresponding ajax request to the server
|
280 |
+
jQuery( document ).on( 'click', '[id^=slimstat-hide-]', function( e ) {
|
281 |
+
e.preventDefault();
|
282 |
+
jQuery( this ).parents( '.slimstat-notice' ).slideUp( 1000 );
|
283 |
+
data = {
|
284 |
+
action: jQuery( this ).attr('id').replace(/-/g, '_'),
|
285 |
+
security: jQuery( '#meta-box-order-nonce' ).val()
|
286 |
+
};
|
287 |
+
|
288 |
+
jQuery.ajax({
|
289 |
+
url: ajaxurl,
|
290 |
+
type: 'post',
|
291 |
+
async: true,
|
292 |
+
data: data
|
293 |
+
});
|
294 |
+
});
|
295 |
+
|
296 |
+
//
|
297 |
+
// ----- END: MISCELLANEOUS ------------------------------------------------------
|
298 |
+
|
299 |
+
// ----- BEGIN: INIT THIRD-PARTY LIBRARIES ---------------------------------------
|
300 |
+
//
|
301 |
+
|
302 |
+
// SlimScroll
|
303 |
+
jQuery( '[id^=slim_] .inside' ).slimScroll( {
|
304 |
+
distance: '2px',
|
305 |
+
opacity: '0.15',
|
306 |
+
size: '5px',
|
307 |
+
wheelStep: 10
|
308 |
+
} );
|
309 |
+
|
310 |
+
// QTip
|
311 |
+
jQuery( document ).on( 'mouseover', '.slimstat-tooltip-trigger', function( e ) {
|
312 |
+
if ( typeof jQuery( this ).attr( 'data-hasqtip' ) != 'undefined' ) {
|
313 |
+
return true;
|
314 |
+
}
|
315 |
+
|
316 |
+
tooltip_content = jQuery( this ).find( '.slimstat-tooltip-content:not(.expanded)' );
|
317 |
+
|
318 |
+
if ( typeof tooltip_content == 'undefined' || tooltip_content == null || tooltip_content.length == 0 ) {
|
319 |
+
tooltip_content = jQuery( this ).attr( 'title' );
|
320 |
+
}
|
321 |
+
else {
|
322 |
+
tooltip_content = tooltip_content[ 0 ].innerHTML;
|
323 |
+
}
|
324 |
+
|
325 |
+
if ( typeof tooltip_content != 'undefined' && tooltip_content.length ) {
|
326 |
+
jQuery(this).qtip( {
|
327 |
+
overwrite: false,
|
328 |
+
content: {
|
329 |
+
text: tooltip_content
|
330 |
+
},
|
331 |
+
show: {
|
332 |
+
event: e.type,
|
333 |
+
ready: true
|
334 |
+
},
|
335 |
+
hide: {
|
336 |
+
delay: 250,
|
337 |
+
fixed: true
|
338 |
+
},
|
339 |
+
position: {
|
340 |
+
my: 'bottom right',
|
341 |
+
at: 'top left',
|
342 |
+
adjust: {
|
343 |
+
x: 5
|
344 |
+
},
|
345 |
+
viewport: jQuery( window )
|
346 |
+
},
|
347 |
+
style: {
|
348 |
+
classes: 'qtip-dark qtip-rounded'
|
349 |
+
}
|
350 |
+
}, e );
|
351 |
+
}
|
352 |
+
} );
|
353 |
+
|
354 |
+
// Modal Window
|
355 |
+
if ( typeof jQuery( '#slimstat-modal-dialog' ).dialog == 'function' ) {
|
356 |
+
jQuery( '#slimstat-modal-dialog' ).dialog( {
|
357 |
+
autoOpen: false,
|
358 |
+
closeOnEscape: true,
|
359 |
+
closeText: '',
|
360 |
+
draggable: true,
|
361 |
+
modal: true,
|
362 |
+
open: function(){
|
363 |
+
jQuery( '.ui-widget-overlay, .close-dialog' ).on( 'click', function() {
|
364 |
+
jQuery( '#slimstat-modal-dialog' ).dialog( 'close' );
|
365 |
+
} );
|
366 |
+
},
|
367 |
+
position: { my: "top center" },
|
368 |
+
resizable: false
|
369 |
+
} );
|
370 |
+
}
|
371 |
+
|
372 |
+
// BootstrapSwitch (pretty checkboxes in settings)
|
373 |
+
jQuery( 'input.slimstat-checkbox-toggle' ).not( '[data-switch-no-init]' ).bootstrapSwitch();
|
374 |
+
|
375 |
+
// TagEditor
|
376 |
+
jQuery( 'textarea.slimstat-taglist' ).tagEditor( {
|
377 |
+
forceLowercase: false,
|
378 |
+
maxLength: 1000
|
379 |
+
} );
|
380 |
+
|
381 |
+
//
|
382 |
+
// ----- END: INIT THIRD-PARTY LIBRARIES -----------------------------------------
|
383 |
+
} );
|
384 |
+
|
385 |
+
// ----- BEGIN: SLIMSTATADMIN HELPER FUNCTIONS ---------------------------------------
|
386 |
+
var SlimStatAdmin = {
|
387 |
+
_refresh_timer: 0,
|
388 |
+
|
389 |
+
refresh_countdown: function() {
|
390 |
+
SlimStatAdmin._refresh_timer--;
|
391 |
+
minutes = parseInt( SlimStatAdmin._refresh_timer / 60 );
|
392 |
+
seconds = parseInt( SlimStatAdmin._refresh_timer % 60 );
|
393 |
+
|
394 |
+
jQuery( '.refresh-timer' ).html( minutes + ':' + ( ( seconds < 10 ) ? '0' : '' ) + seconds );
|
395 |
+
|
396 |
+
if ( SlimStatAdmin._refresh_timer > 0 ) {
|
397 |
+
window.setTimeout( SlimStatAdmin.refresh_countdown, 1000 );
|
398 |
+
}
|
399 |
+
else {
|
400 |
+
// Request the data from the server
|
401 |
+
SlimStatAdmin.refresh_report( 'slim_p7_02' );
|
402 |
+
|
403 |
+
// Reset the countdown timer
|
404 |
+
SlimStatAdmin._refresh_timer = parseInt( SlimStatAdminParams.refresh_interval );
|
405 |
+
window.setTimeout( "SlimStatAdmin.refresh_countdown();", 1000 );
|
406 |
+
}
|
407 |
+
},
|
408 |
+
|
409 |
+
refresh_report: function( id ) {
|
410 |
+
var inner_content = '#' + id + ' .inside';
|
411 |
+
jQuery( inner_content ).html( '<p class="loading"><i class="slimstat-font-spin4 animate-spin"></i></p>' );
|
412 |
+
data = {
|
413 |
+
action: 'slimstat_load_report',
|
414 |
+
security: jQuery( '#meta-box-order-nonce' ).val(),
|
415 |
+
page: SlimStatAdmin.get_current_tab(),
|
416 |
+
report_id: id
|
417 |
+
};
|
418 |
+
|
419 |
+
// Append the data from the hidden form
|
420 |
+
filters_input = jQuery( '#slimstat-filters-form .slimstat-post-filter' ).toArray();
|
421 |
+
for ( i in filters_input ) {
|
422 |
+
data[ filters_input[ i ][ 'name' ] ] = filters_input[ i ][ 'value' ];
|
423 |
+
}
|
424 |
+
|
425 |
+
jQuery.post( ajaxurl, data, function( response ) {
|
426 |
+
// Charts don't play nice with the "fade" animation we have for the other reports
|
427 |
+
if ( id.indexOf( '_01' ) > 0 ) {
|
428 |
+
jQuery( inner_content ).html( response );
|
429 |
+
}
|
430 |
+
else{
|
431 |
+
jQuery( inner_content ).fadeOut( 500, function() { jQuery( this ).html( response ).fadeIn( 500 ); } );
|
432 |
+
|
433 |
+
// If we are refreshing the Activity Log, let's reset the countdown timer
|
434 |
+
if ( id == 'slim_p7_02' ) {
|
435 |
+
SlimStatAdmin._refresh_timer = SlimStatAdminParams.refresh_interval;
|
436 |
+
}
|
437 |
+
}
|
438 |
+
} );
|
439 |
+
},
|
440 |
+
|
441 |
+
get_query_string_filters: function( url ) {
|
442 |
+
|
443 |
+
// Parse the URL and update the form_filters object accordingly
|
444 |
+
query_string_pairs = url.substring( url.indexOf( '?' ) + 1 ).split( '&' );
|
445 |
+
clean_filters = {};
|
446 |
+
|
447 |
+
for ( i in query_string_pairs ) {
|
448 |
+
decoded_pair = decodeURIComponent( query_string_pairs[ i ].replace( /\+/g, '%20' ) );
|
449 |
+
|
450 |
+
if ( decoded_pair.indexOf( 'fs[' ) == -1 ) {
|
451 |
+
continue;
|
452 |
+
}
|
453 |
+
|
454 |
+
a_pair = decoded_pair.split( '=' );
|
455 |
+
if ( a_pair[ 0 ].length ) {
|
456 |
+
clean_filters[ a_pair[ 0 ] ] = a_pair[ 1 ];
|
457 |
+
}
|
458 |
+
}
|
459 |
+
|
460 |
+
return clean_filters;
|
461 |
+
},
|
462 |
+
|
463 |
+
add_url_filters_to_form: function( url, delete_existing_filters ) {
|
464 |
+
clean_filters = SlimStatAdmin.get_query_string_filters( url );
|
465 |
+
|
466 |
+
// Manipulate the existing list of filters (hidden input fields), if we don't want to delete them
|
467 |
+
if ( typeof delete_existing_filters == 'undefined' || !delete_existing_filters ) {
|
468 |
+
|
469 |
+
for( i in clean_filters ) {
|
470 |
+
// If value is empty (length is 1, meaning that it just has the operator but no value), delete corresponding input field
|
471 |
+
if ( clean_filters[ i ].trim().split( ' ' ).length == 1 ) {
|
472 |
+
jQuery( 'input[name="' + i + '"]' ).remove();
|
473 |
+
}
|
474 |
+
else if ( jQuery( 'input[name="' + i + '"]' ).length > 0 ) {
|
475 |
+
jQuery( 'input[name="' + i + '"]' ).attr( 'value', clean_filters[ i ] );
|
476 |
+
}
|
477 |
+
else {
|
478 |
+
jQuery( '<input type="hidden" name="' + i + '" class="slimstat-post-filter" value="' + clean_filters[ i ] + '">' ).appendTo( '#slimstat-filters-form' );
|
479 |
+
}
|
480 |
+
}
|
481 |
+
}
|
482 |
+
// Start from a clean slate
|
483 |
+
else {
|
484 |
+
jQuery( '.slimstat-post-filter' ).remove();
|
485 |
+
|
486 |
+
for( i in clean_filters ) {
|
487 |
+
jQuery( '<input type="hidden" name="' + i + '" class="slimstat-post-filter" value="' + clean_filters[ i ] + '">' ).appendTo( '#slimstat-filters-form' );
|
488 |
+
}
|
489 |
+
}
|
490 |
+
},
|
491 |
+
|
492 |
+
// Get the value of a given key in the query string passed via the URL
|
493 |
+
get_current_tab: function( query_string ) {
|
494 |
+
query_string = typeof query_string == 'undefined' ? window.location.search.substring( 1 ) : query_string;
|
495 |
+
var regex = new RegExp( "page(=([^&#]*)|&|#|$)" );
|
496 |
+
|
497 |
+
values = regex.exec( query_string );
|
498 |
+
|
499 |
+
if ( typeof values != 'undefined' && values != null && typeof values[ 2 ] == 'string' ) {
|
500 |
+
return decodeURIComponent( values[ 2 ].replace( /\+/g, " " ) );
|
501 |
+
}
|
502 |
+
|
503 |
+
return '';
|
504 |
+
}
|
505 |
+
}
|
506 |
+
// ----- END: SLIMSTATADMIN HELPER FUNCTIONS -----------------------------------------
|
507 |
+
|
508 |
+
/* SlimScroll v1.3.8 | http://rocha.la | Copyright (c) 2011 Piotr Rochala. Released under the MIT and GPL licenses. */
|
509 |
+
!function(e){e.fn.extend({slimScroll:function(i){var s={width:"auto",size:"7px",color:"#000",position:"right",distance:"1px",start:"top",opacity:.4,alwaysVisible:!1,disableFadeOut:!1,railVisible:!1,railColor:"#333",railOpacity:.2,railDraggable:!0,railClass:"slimScrollRail",barClass:"slimScrollBar",wrapperClass:"slimScrollDiv",allowPageScroll:!1,wheelStep:20,touchScrollStep:200,borderRadius:"7px",railBorderRadius:"7px"},o=e.extend(s,i);return this.each(function(){function s(t){if(h){var t=t||window.event,i=0;t.wheelDelta&&(i=-t.wheelDelta/120),t.detail&&(i=t.detail/3);var s=t.target||t.srcTarget||t.srcElement;e(s).closest("."+o.wrapperClass).is(x.parent())&&r(i,!0),t.preventDefault&&!y&&t.preventDefault(),y||(t.returnValue=!1)}}function r(e,t,i){y=!1;var s=e,r=x.outerHeight()-D.outerHeight();if(t&&(s=parseInt(D.css("top"))+e*parseInt(o.wheelStep)/100*D.outerHeight(),s=Math.min(Math.max(s,0),r),s=e>0?Math.ceil(s):Math.floor(s),D.css({top:s+"px"})),v=parseInt(D.css("top"))/(x.outerHeight()-D.outerHeight()),s=v*(x[0].scrollHeight-x.outerHeight()),i){s=e;var a=s/x[0].scrollHeight*x.outerHeight();a=Math.min(Math.max(a,0),r),D.css({top:a+"px"})}x.scrollTop(s),x.trigger("slimscrolling",~~s),n(),c()}function a(e){window.addEventListener?(e.addEventListener("DOMMouseScroll",s,!1),e.addEventListener("mousewheel",s,!1)):document.attachEvent("onmousewheel",s)}function l(){f=Math.max(x.outerHeight()/x[0].scrollHeight*x.outerHeight(),m),D.css({height:f+"px"});var e=f==x.outerHeight()?"none":"block";D.css({display:e})}function n(){if(l(),clearTimeout(p),v==~~v){if(y=o.allowPageScroll,b!=v){var e=0==~~v?"top":"bottom";x.trigger("slimscroll",e)}}else y=!1;return b=v,f>=x.outerHeight()?void(y=!0):(D.stop(!0,!0).fadeIn("fast"),void(o.railVisible&&R.stop(!0,!0).fadeIn("fast")))}function c(){o.alwaysVisible||(p=setTimeout(function(){o.disableFadeOut&&h||u||d||(D.fadeOut("slow"),R.fadeOut("slow"))},1e3))}var h,u,d,p,g,f,v,b,w="<div></div>",m=30,y=!1,x=e(this);if(x.parent().hasClass(o.wrapperClass)){var C=x.scrollTop();if(D=x.siblings("."+o.barClass),R=x.siblings("."+o.railClass),l(),e.isPlainObject(i)){if("height"in i&&"auto"==i.height){x.parent().css("height","auto"),x.css("height","auto");var H=x.parent().parent().height();x.parent().css("height",H),x.css("height",H)}else if("height"in i){var S=i.height;x.parent().css("height",S),x.css("height",S)}if("scrollTo"in i)C=parseInt(o.scrollTo);else if("scrollBy"in i)C+=parseInt(o.scrollBy);else if("destroy"in i)return D.remove(),R.remove(),void x.unwrap();r(C,!1,!0)}}else if(!(e.isPlainObject(i)&&"destroy"in i)){o.height="auto"==o.height?x.parent().height():o.height;var E=e(w).addClass(o.wrapperClass).css({position:"relative",overflow:"hidden",width:o.width,height:o.height});x.css({overflow:"hidden",width:o.width,height:o.height});var R=e(w).addClass(o.railClass).css({width:o.size,height:"100%",position:"absolute",top:0,display:o.alwaysVisible&&o.railVisible?"block":"none","border-radius":o.railBorderRadius,background:o.railColor,opacity:o.railOpacity,zIndex:90}),D=e(w).addClass(o.barClass).css({background:o.color,width:o.size,position:"absolute",top:0,opacity:o.opacity,display:o.alwaysVisible?"block":"none","border-radius":o.borderRadius,BorderRadius:o.borderRadius,MozBorderRadius:o.borderRadius,WebkitBorderRadius:o.borderRadius,zIndex:99}),M="right"==o.position?{right:o.distance}:{left:o.distance};R.css(M),D.css(M),x.wrap(E),x.parent().append(D),x.parent().append(R),o.railDraggable&&D.bind("mousedown",function(i){var s=e(document);return d=!0,t=parseFloat(D.css("top")),pageY=i.pageY,s.bind("mousemove.slimscroll",function(e){currTop=t+e.pageY-pageY,D.css("top",currTop),r(0,D.position().top,!1)}),s.bind("mouseup.slimscroll",function(e){d=!1,c(),s.unbind(".slimscroll")}),!1}).bind("selectstart.slimscroll",function(e){return e.stopPropagation(),e.preventDefault(),!1}),R.hover(function(){n()},function(){c()}),D.hover(function(){u=!0},function(){u=!1}),x.hover(function(){h=!0,n(),c()},function(){h=!1,c()}),x.bind("touchstart",function(e,t){e.originalEvent.touches.length&&(g=e.originalEvent.touches[0].pageY)}),x.bind("touchmove",function(e){if(y||e.originalEvent.preventDefault(),e.originalEvent.touches.length){var t=(g-e.originalEvent.touches[0].pageY)/o.touchScrollStep;r(t,!0),g=e.originalEvent.touches[0].pageY}}),l(),"bottom"===o.start?(D.css({top:x.outerHeight()-D.outerHeight()}),r(0,!0)):"top"!==o.start&&(r(e(o.start).position().top,null,!0),o.alwaysVisible||D.hide()),a(this)}}),this}}),e.fn.extend({slimscroll:e.fn.slimScroll})}(jQuery);
|
510 |
+
|
511 |
+
/* qTip2 v3.0.3 | http://qtip2.com | Released under the MIT and GPL licenses. */
|
512 |
+
!function(a,b,c){!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):jQuery&&!jQuery.fn.qtip&&a(jQuery)}(function(d){"use strict";function e(a,b,c,e){this.id=c,this.target=a,this.tooltip=D,this.elements={target:a},this._id=Q+"-"+c,this.timers={img:{}},this.options=b,this.plugins={},this.cache={event:{},target:d(),disabled:C,attr:e,onTooltip:C,lastClass:""},this.rendered=this.destroyed=this.disabled=this.waiting=this.hiddenDuringWait=this.positioning=this.triggering=C}function f(a){return a===D||"object"!==d.type(a)}function g(a){return!(d.isFunction(a)||a&&a.attr||a.length||"object"===d.type(a)&&(a.jquery||a.then))}function h(a){var b,c,e,h;return f(a)?C:(f(a.metadata)&&(a.metadata={type:a.metadata}),"content"in a&&(b=a.content,f(b)||b.jquery||b.done?(c=g(b)?C:b,b=a.content={text:c}):c=b.text,"ajax"in b&&(e=b.ajax,h=e&&e.once!==C,delete b.ajax,b.text=function(a,b){var f=c||d(this).attr(b.options.content.attr)||"Loading...",g=d.ajax(d.extend({},e,{context:b})).then(e.success,D,e.error).then(function(a){return a&&h&&b.set("content.text",a),a},function(a,c,d){b.destroyed||0===a.status||b.set("content.text",c+": "+d)});return h?f:(b.set("content.text",f),g)}),"title"in b&&(d.isPlainObject(b.title)&&(b.button=b.title.button,b.title=b.title.text),g(b.title||C)&&(b.title=C))),"position"in a&&f(a.position)&&(a.position={my:a.position,at:a.position}),"show"in a&&f(a.show)&&(a.show=a.show.jquery?{target:a.show}:a.show===B?{ready:B}:{event:a.show}),"hide"in a&&f(a.hide)&&(a.hide=a.hide.jquery?{target:a.hide}:{event:a.hide}),"style"in a&&f(a.style)&&(a.style={classes:a.style}),d.each(P,function(){this.sanitize&&this.sanitize(a)}),a)}function i(a,b){for(var c,d=0,e=a,f=b.split(".");e=e[f[d++]];)d<f.length&&(c=e);return[c||a,f.pop()]}function j(a,b){var c,d,e;for(c in this.checks)if(this.checks.hasOwnProperty(c))for(d in this.checks[c])this.checks[c].hasOwnProperty(d)&&(e=new RegExp(d,"i").exec(a))&&(b.push(e),("builtin"===c||this.plugins[c])&&this.checks[c][d].apply(this.plugins[c]||this,b))}function k(a){return T.concat("").join(a?"-"+a+" ":" ")}function l(a,b){return b>0?setTimeout(d.proxy(a,this),b):void a.call(this)}function m(a){this.tooltip.hasClass($)||(clearTimeout(this.timers.show),clearTimeout(this.timers.hide),this.timers.show=l.call(this,function(){this.toggle(B,a)},this.options.show.delay))}function n(a){if(!this.tooltip.hasClass($)&&!this.destroyed){var b=d(a.relatedTarget),c=b.closest(U)[0]===this.tooltip[0],e=b[0]===this.options.show.target[0];if(clearTimeout(this.timers.show),clearTimeout(this.timers.hide),this!==b[0]&&"mouse"===this.options.position.target&&c||this.options.hide.fixed&&/mouse(out|leave|move)/.test(a.type)&&(c||e))try{a.preventDefault(),a.stopImmediatePropagation()}catch(f){}else this.timers.hide=l.call(this,function(){this.toggle(C,a)},this.options.hide.delay,this)}}function o(a){!this.tooltip.hasClass($)&&this.options.hide.inactive&&(clearTimeout(this.timers.inactive),this.timers.inactive=l.call(this,function(){this.hide(a)},this.options.hide.inactive))}function p(a){this.rendered&&this.tooltip[0].offsetWidth>0&&this.reposition(a)}function q(a,c,e){d(b.body).delegate(a,(c.split?c:c.join("."+Q+" "))+"."+Q,function(){var a=w.api[d.attr(this,S)];a&&!a.disabled&&e.apply(a,arguments)})}function r(a,c,f){var g,i,j,k,l,m=d(b.body),n=a[0]===b?m:a,o=a.metadata?a.metadata(f.metadata):D,p="html5"===f.metadata.type&&o?o[f.metadata.name]:D,q=a.data(f.metadata.name||"qtipopts");try{q="string"==typeof q?d.parseJSON(q):q}catch(r){}if(k=d.extend(B,{},w.defaults,f,"object"==typeof q?h(q):D,h(p||o)),i=k.position,k.id=c,"boolean"==typeof k.content.text){if(j=a.attr(k.content.attr),k.content.attr===C||!j)return C;k.content.text=j}if(i.container.length||(i.container=m),i.target===C&&(i.target=n),k.show.target===C&&(k.show.target=n),k.show.solo===B&&(k.show.solo=i.container.closest("body")),k.hide.target===C&&(k.hide.target=n),k.position.viewport===B&&(k.position.viewport=i.container),i.container=i.container.eq(0),i.at=new y(i.at,B),i.my=new y(i.my),a.data(Q))if(k.overwrite)a.qtip("destroy",!0);else if(k.overwrite===C)return C;return a.attr(R,c),k.suppress&&(l=a.attr("title"))&&a.removeAttr("title").attr(aa,l).attr("title",""),g=new e(a,k,c,!!j),a.data(Q,g),g}function s(a){return a.charAt(0).toUpperCase()+a.slice(1)}function t(a,b){var d,e,f=b.charAt(0).toUpperCase()+b.slice(1),g=(b+" "+ta.join(f+" ")+f).split(" "),h=0;if(sa[b])return a.css(sa[b]);for(;d=g[h++];)if((e=a.css(d))!==c)return sa[b]=d,e}function u(a,b){return Math.ceil(parseFloat(t(a,b)))}function v(a,b){this._ns="tip",this.options=b,this.offset=b.offset,this.size=[b.width,b.height],this.qtip=a,this.init(a)}var w,x,y,z,A,B=!0,C=!1,D=null,E="x",F="y",G="width",H="height",I="top",J="left",K="bottom",L="right",M="center",N="flipinvert",O="shift",P={},Q="qtip",R="data-hasqtip",S="data-qtip-id",T=["ui-widget","ui-tooltip"],U="."+Q,V="click dblclick mousedown mouseup mousemove mouseleave mouseenter".split(" "),W=Q+"-fixed",X=Q+"-default",Y=Q+"-focus",Z=Q+"-hover",$=Q+"-disabled",_="_replacedByqTip",aa="oldtitle",ba={ie:function(){var a,c;for(a=4,c=b.createElement("div");(c.innerHTML="<!--[if gt IE "+a+"]><i></i><![endif]-->")&&c.getElementsByTagName("i")[0];a+=1);return a>4?a:NaN}(),iOS:parseFloat((""+(/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent)||[0,""])[1]).replace("undefined","3_2").replace("_",".").replace("_",""))||C};x=e.prototype,x._when=function(a){return d.when.apply(d,a)},x.render=function(a){if(this.rendered||this.destroyed)return this;var b=this,c=this.options,e=this.cache,f=this.elements,g=c.content.text,h=c.content.title,i=c.content.button,j=c.position,k=[];return d.attr(this.target[0],"aria-describedby",this._id),e.posClass=this._createPosClass((this.position={my:j.my,at:j.at}).my),this.tooltip=f.tooltip=d("<div/>",{id:this._id,"class":[Q,X,c.style.classes,e.posClass].join(" "),width:c.style.width||"",height:c.style.height||"",tracking:"mouse"===j.target&&j.adjust.mouse,role:"alert","aria-live":"polite","aria-atomic":C,"aria-describedby":this._id+"-content","aria-hidden":B}).toggleClass($,this.disabled).attr(S,this.id).data(Q,this).appendTo(j.container).append(f.content=d("<div />",{"class":Q+"-content",id:this._id+"-content","aria-atomic":B})),this.rendered=-1,this.positioning=B,h&&(this._createTitle(),d.isFunction(h)||k.push(this._updateTitle(h,C))),i&&this._createButton(),d.isFunction(g)||k.push(this._updateContent(g,C)),this.rendered=B,this._setWidget(),d.each(P,function(a){var c;"render"===this.initialize&&(c=this(b))&&(b.plugins[a]=c)}),this._unassignEvents(),this._assignEvents(),this._when(k).then(function(){b._trigger("render"),b.positioning=C,b.hiddenDuringWait||!c.show.ready&&!a||b.toggle(B,e.event,C),b.hiddenDuringWait=C}),w.api[this.id]=this,this},x.destroy=function(a){function b(){if(!this.destroyed){this.destroyed=B;var a,b=this.target,c=b.attr(aa);this.rendered&&this.tooltip.stop(1,0).find("*").remove().end().remove(),d.each(this.plugins,function(){this.destroy&&this.destroy()});for(a in this.timers)this.timers.hasOwnProperty(a)&&clearTimeout(this.timers[a]);b.removeData(Q).removeAttr(S).removeAttr(R).removeAttr("aria-describedby"),this.options.suppress&&c&&b.attr("title",c).removeAttr(aa),this._unassignEvents(),this.options=this.elements=this.cache=this.timers=this.plugins=this.mouse=D,delete w.api[this.id]}}return this.destroyed?this.target:(a===B&&"hide"!==this.triggering||!this.rendered?b.call(this):(this.tooltip.one("tooltiphidden",d.proxy(b,this)),!this.triggering&&this.hide()),this.target)},z=x.checks={builtin:{"^id$":function(a,b,c,e){var f=c===B?w.nextid:c,g=Q+"-"+f;f!==C&&f.length>0&&!d("#"+g).length?(this._id=g,this.rendered&&(this.tooltip[0].id=this._id,this.elements.content[0].id=this._id+"-content",this.elements.title[0].id=this._id+"-title")):a[b]=e},"^prerender":function(a,b,c){c&&!this.rendered&&this.render(this.options.show.ready)},"^content.text$":function(a,b,c){this._updateContent(c)},"^content.attr$":function(a,b,c,d){this.options.content.text===this.target.attr(d)&&this._updateContent(this.target.attr(c))},"^content.title$":function(a,b,c){return c?(c&&!this.elements.title&&this._createTitle(),void this._updateTitle(c)):this._removeTitle()},"^content.button$":function(a,b,c){this._updateButton(c)},"^content.title.(text|button)$":function(a,b,c){this.set("content."+b,c)},"^position.(my|at)$":function(a,b,c){"string"==typeof c&&(this.position[b]=a[b]=new y(c,"at"===b))},"^position.container$":function(a,b,c){this.rendered&&this.tooltip.appendTo(c)},"^show.ready$":function(a,b,c){c&&(!this.rendered&&this.render(B)||this.toggle(B))},"^style.classes$":function(a,b,c,d){this.rendered&&this.tooltip.removeClass(d).addClass(c)},"^style.(width|height)":function(a,b,c){this.rendered&&this.tooltip.css(b,c)},"^style.widget|content.title":function(){this.rendered&&this._setWidget()},"^style.def":function(a,b,c){this.rendered&&this.tooltip.toggleClass(X,!!c)},"^events.(render|show|move|hide|focus|blur)$":function(a,b,c){this.rendered&&this.tooltip[(d.isFunction(c)?"":"un")+"bind"]("tooltip"+b,c)},"^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)":function(){if(this.rendered){var a=this.options.position;this.tooltip.attr("tracking","mouse"===a.target&&a.adjust.mouse),this._unassignEvents(),this._assignEvents()}}}},x.get=function(a){if(this.destroyed)return this;var b=i(this.options,a.toLowerCase()),c=b[0][b[1]];return c.precedance?c.string():c};var ca=/^position\.(my|at|adjust|target|container|viewport)|style|content|show\.ready/i,da=/^prerender|show\.ready/i;x.set=function(a,b){if(this.destroyed)return this;var c,e=this.rendered,f=C,g=this.options;return"string"==typeof a?(c=a,a={},a[c]=b):a=d.extend({},a),d.each(a,function(b,c){if(e&&da.test(b))return void delete a[b];var h,j=i(g,b.toLowerCase());h=j[0][j[1]],j[0][j[1]]=c&&c.nodeType?d(c):c,f=ca.test(b)||f,a[b]=[j[0],j[1],c,h]}),h(g),this.positioning=B,d.each(a,d.proxy(j,this)),this.positioning=C,this.rendered&&this.tooltip[0].offsetWidth>0&&f&&this.reposition("mouse"===g.position.target?D:this.cache.event),this},x._update=function(a,b){var c=this,e=this.cache;return this.rendered&&a?(d.isFunction(a)&&(a=a.call(this.elements.target,e.event,this)||""),d.isFunction(a.then)?(e.waiting=B,a.then(function(a){return e.waiting=C,c._update(a,b)},D,function(a){return c._update(a,b)})):a===C||!a&&""!==a?C:(a.jquery&&a.length>0?b.empty().append(a.css({display:"block",visibility:"visible"})):b.html(a),this._waitForContent(b).then(function(a){c.rendered&&c.tooltip[0].offsetWidth>0&&c.reposition(e.event,!a.length)}))):C},x._waitForContent=function(a){var b=this.cache;return b.waiting=B,(d.fn.imagesLoaded?a.imagesLoaded():(new d.Deferred).resolve([])).done(function(){b.waiting=C}).promise()},x._updateContent=function(a,b){this._update(a,this.elements.content,b)},x._updateTitle=function(a,b){this._update(a,this.elements.title,b)===C&&this._removeTitle(C)},x._createTitle=function(){var a=this.elements,b=this._id+"-title";a.titlebar&&this._removeTitle(),a.titlebar=d("<div />",{"class":Q+"-titlebar "+(this.options.style.widget?k("header"):"")}).append(a.title=d("<div />",{id:b,"class":Q+"-title","aria-atomic":B})).insertBefore(a.content).delegate(".qtip-close","mousedown keydown mouseup keyup mouseout",function(a){d(this).toggleClass("ui-state-active ui-state-focus","down"===a.type.substr(-4))}).delegate(".qtip-close","mouseover mouseout",function(a){d(this).toggleClass("ui-state-hover","mouseover"===a.type)}),this.options.content.button&&this._createButton()},x._removeTitle=function(a){var b=this.elements;b.title&&(b.titlebar.remove(),b.titlebar=b.title=b.button=D,a!==C&&this.reposition())},x._createPosClass=function(a){return Q+"-pos-"+(a||this.options.position.my).abbrev()},x.reposition=function(c,e){if(!this.rendered||this.positioning||this.destroyed)return this;this.positioning=B;var f,g,h,i,j=this.cache,k=this.tooltip,l=this.options.position,m=l.target,n=l.my,o=l.at,p=l.viewport,q=l.container,r=l.adjust,s=r.method.split(" "),t=k.outerWidth(C),u=k.outerHeight(C),v=0,w=0,x=k.css("position"),y={left:0,top:0},z=k[0].offsetWidth>0,A=c&&"scroll"===c.type,D=d(a),E=q[0].ownerDocument,F=this.mouse;if(d.isArray(m)&&2===m.length)o={x:J,y:I},y={left:m[0],top:m[1]};else if("mouse"===m)o={x:J,y:I},(!r.mouse||this.options.hide.distance)&&j.origin&&j.origin.pageX?c=j.origin:!c||c&&("resize"===c.type||"scroll"===c.type)?c=j.event:F&&F.pageX&&(c=F),"static"!==x&&(y=q.offset()),E.body.offsetWidth!==(a.innerWidth||E.documentElement.clientWidth)&&(g=d(b.body).offset()),y={left:c.pageX-y.left+(g&&g.left||0),top:c.pageY-y.top+(g&&g.top||0)},r.mouse&&A&&F&&(y.left-=(F.scrollX||0)-D.scrollLeft(),y.top-=(F.scrollY||0)-D.scrollTop());else{if("event"===m?c&&c.target&&"scroll"!==c.type&&"resize"!==c.type?j.target=d(c.target):c.target||(j.target=this.elements.target):"event"!==m&&(j.target=d(m.jquery?m:this.elements.target)),m=j.target,m=d(m).eq(0),0===m.length)return this;m[0]===b||m[0]===a?(v=ba.iOS?a.innerWidth:m.width(),w=ba.iOS?a.innerHeight:m.height(),m[0]===a&&(y={top:(p||m).scrollTop(),left:(p||m).scrollLeft()})):P.imagemap&&m.is("area")?f=P.imagemap(this,m,o,P.viewport?s:C):P.svg&&m&&m[0].ownerSVGElement?f=P.svg(this,m,o,P.viewport?s:C):(v=m.outerWidth(C),w=m.outerHeight(C),y=m.offset()),f&&(v=f.width,w=f.height,g=f.offset,y=f.position),y=this.reposition.offset(m,y,q),(ba.iOS>3.1&&ba.iOS<4.1||ba.iOS>=4.3&&ba.iOS<4.33||!ba.iOS&&"fixed"===x)&&(y.left-=D.scrollLeft(),y.top-=D.scrollTop()),(!f||f&&f.adjustable!==C)&&(y.left+=o.x===L?v:o.x===M?v/2:0,y.top+=o.y===K?w:o.y===M?w/2:0)}return y.left+=r.x+(n.x===L?-t:n.x===M?-t/2:0),y.top+=r.y+(n.y===K?-u:n.y===M?-u/2:0),P.viewport?(h=y.adjusted=P.viewport(this,y,l,v,w,t,u),g&&h.left&&(y.left+=g.left),g&&h.top&&(y.top+=g.top),h.my&&(this.position.my=h.my)):y.adjusted={left:0,top:0},j.posClass!==(i=this._createPosClass(this.position.my))&&(j.posClass=i,k.removeClass(j.posClass).addClass(i)),this._trigger("move",[y,p.elem||p],c)?(delete y.adjusted,e===C||!z||isNaN(y.left)||isNaN(y.top)||"mouse"===m||!d.isFunction(l.effect)?k.css(y):d.isFunction(l.effect)&&(l.effect.call(k,this,d.extend({},y)),k.queue(function(a){d(this).css({opacity:"",height:""}),ba.ie&&this.style.removeAttribute("filter"),a()})),this.positioning=C,this):this},x.reposition.offset=function(a,c,e){function f(a,b){c.left+=b*a.scrollLeft(),c.top+=b*a.scrollTop()}if(!e[0])return c;var g,h,i,j,k=d(a[0].ownerDocument),l=!!ba.ie&&"CSS1Compat"!==b.compatMode,m=e[0];do"static"!==(h=d.css(m,"position"))&&("fixed"===h?(i=m.getBoundingClientRect(),f(k,-1)):(i=d(m).position(),i.left+=parseFloat(d.css(m,"borderLeftWidth"))||0,i.top+=parseFloat(d.css(m,"borderTopWidth"))||0),c.left-=i.left+(parseFloat(d.css(m,"marginLeft"))||0),c.top-=i.top+(parseFloat(d.css(m,"marginTop"))||0),g||"hidden"===(j=d.css(m,"overflow"))||"visible"===j||(g=d(m)));while(m=m.offsetParent);return g&&(g[0]!==k[0]||l)&&f(g,1),c};var ea=(y=x.reposition.Corner=function(a,b){a=(""+a).replace(/([A-Z])/," $1").replace(/middle/gi,M).toLowerCase(),this.x=(a.match(/left|right/i)||a.match(/center/)||["inherit"])[0].toLowerCase(),this.y=(a.match(/top|bottom|center/i)||["inherit"])[0].toLowerCase(),this.forceY=!!b;var c=a.charAt(0);this.precedance="t"===c||"b"===c?F:E}).prototype;ea.invert=function(a,b){this[a]=this[a]===J?L:this[a]===L?J:b||this[a]},ea.string=function(a){var b=this.x,c=this.y,d=b!==c?"center"===b||"center"!==c&&(this.precedance===F||this.forceY)?[c,b]:[b,c]:[b];return a!==!1?d.join(" "):d},ea.abbrev=function(){var a=this.string(!1);return a[0].charAt(0)+(a[1]&&a[1].charAt(0)||"")},ea.clone=function(){return new y(this.string(),this.forceY)},x.toggle=function(a,c){var e=this.cache,f=this.options,g=this.tooltip;if(c){if(/over|enter/.test(c.type)&&e.event&&/out|leave/.test(e.event.type)&&f.show.target.add(c.target).length===f.show.target.length&&g.has(c.relatedTarget).length)return this;e.event=d.event.fix(c)}if(this.waiting&&!a&&(this.hiddenDuringWait=B),!this.rendered)return a?this.render(1):this;if(this.destroyed||this.disabled)return this;var h,i,j,k=a?"show":"hide",l=this.options[k],m=this.options.position,n=this.options.content,o=this.tooltip.css("width"),p=this.tooltip.is(":visible"),q=a||1===l.target.length,r=!c||l.target.length<2||e.target[0]===c.target;return(typeof a).search("boolean|number")&&(a=!p),h=!g.is(":animated")&&p===a&&r,i=h?D:!!this._trigger(k,[90]),this.destroyed?this:(i!==C&&a&&this.focus(c),!i||h?this:(d.attr(g[0],"aria-hidden",!a),a?(this.mouse&&(e.origin=d.event.fix(this.mouse)),d.isFunction(n.text)&&this._updateContent(n.text,C),d.isFunction(n.title)&&this._updateTitle(n.title,C),!A&&"mouse"===m.target&&m.adjust.mouse&&(d(b).bind("mousemove."+Q,this._storeMouse),A=B),o||g.css("width",g.outerWidth(C)),this.reposition(c,arguments[2]),o||g.css("width",""),l.solo&&("string"==typeof l.solo?d(l.solo):d(U,l.solo)).not(g).not(l.target).qtip("hide",new d.Event("tooltipsolo"))):(clearTimeout(this.timers.show),delete e.origin,A&&!d(U+'[tracking="true"]:visible',l.solo).not(g).length&&(d(b).unbind("mousemove."+Q),A=C),this.blur(c)),j=d.proxy(function(){a?(ba.ie&&g[0].style.removeAttribute("filter"),g.css("overflow",""),"string"==typeof l.autofocus&&d(this.options.show.autofocus,g).focus(),this.options.show.target.trigger("qtip-"+this.id+"-inactive")):g.css({display:"",visibility:"",opacity:"",left:"",top:""}),this._trigger(a?"visible":"hidden")},this),l.effect===C||q===C?(g[k](),j()):d.isFunction(l.effect)?(g.stop(1,1),l.effect.call(g,this),g.queue("fx",function(a){j(),a()})):g.fadeTo(90,a?1:0,j),a&&l.target.trigger("qtip-"+this.id+"-inactive"),this))},x.show=function(a){return this.toggle(B,a)},x.hide=function(a){return this.toggle(C,a)},x.focus=function(a){if(!this.rendered||this.destroyed)return this;var b=d(U),c=this.tooltip,e=parseInt(c[0].style.zIndex,10),f=w.zindex+b.length;return c.hasClass(Y)||this._trigger("focus",[f],a)&&(e!==f&&(b.each(function(){this.style.zIndex>e&&(this.style.zIndex=this.style.zIndex-1)}),b.filter("."+Y).qtip("blur",a)),c.addClass(Y)[0].style.zIndex=f),this},x.blur=function(a){return!this.rendered||this.destroyed?this:(this.tooltip.removeClass(Y),this._trigger("blur",[this.tooltip.css("zIndex")],a),this)},x.disable=function(a){return this.destroyed?this:("toggle"===a?a=!(this.rendered?this.tooltip.hasClass($):this.disabled):"boolean"!=typeof a&&(a=B),this.rendered&&this.tooltip.toggleClass($,a).attr("aria-disabled",a),this.disabled=!!a,this)},x.enable=function(){return this.disable(C)},x._createButton=function(){var a=this,b=this.elements,c=b.tooltip,e=this.options.content.button,f="string"==typeof e,g=f?e:"Close tooltip";b.button&&b.button.remove(),e.jquery?b.button=e:b.button=d("<a />",{"class":"qtip-close "+(this.options.style.widget?"":Q+"-icon"),title:g,"aria-label":g}).prepend(d("<span />",{"class":"ui-icon ui-icon-close",html:"×"})),b.button.appendTo(b.titlebar||c).attr("role","button").click(function(b){return c.hasClass($)||a.hide(b),C})},x._updateButton=function(a){if(!this.rendered)return C;var b=this.elements.button;a?this._createButton():b.remove()},x._setWidget=function(){var a=this.options.style.widget,b=this.elements,c=b.tooltip,d=c.hasClass($);c.removeClass($),$=a?"ui-state-disabled":"qtip-disabled",c.toggleClass($,d),c.toggleClass("ui-helper-reset "+k(),a).toggleClass(X,this.options.style.def&&!a),b.content&&b.content.toggleClass(k("content"),a),b.titlebar&&b.titlebar.toggleClass(k("header"),a),b.button&&b.button.toggleClass(Q+"-icon",!a)},x._storeMouse=function(a){return(this.mouse=d.event.fix(a)).type="mousemove",this},x._bind=function(a,b,c,e,f){if(a&&c&&b.length){var g="."+this._id+(e?"-"+e:"");return d(a).bind((b.split?b:b.join(g+" "))+g,d.proxy(c,f||this)),this}},x._unbind=function(a,b){return a&&d(a).unbind("."+this._id+(b?"-"+b:"")),this},x._trigger=function(a,b,c){var e=new d.Event("tooltip"+a);return e.originalEvent=c&&d.extend({},c)||this.cache.event||D,this.triggering=a,this.tooltip.trigger(e,[this].concat(b||[])),this.triggering=C,!e.isDefaultPrevented()},x._bindEvents=function(a,b,c,e,f,g){var h=c.filter(e).add(e.filter(c)),i=[];h.length&&(d.each(b,function(b,c){var e=d.inArray(c,a);e>-1&&i.push(a.splice(e,1)[0])}),i.length&&(this._bind(h,i,function(a){var b=this.rendered?this.tooltip[0].offsetWidth>0:!1;(b?g:f).call(this,a)}),c=c.not(h),e=e.not(h))),this._bind(c,a,f),this._bind(e,b,g)},x._assignInitialEvents=function(a){function b(a){return this.disabled||this.destroyed?C:(this.cache.event=a&&d.event.fix(a),this.cache.target=a&&d(a.target),clearTimeout(this.timers.show),void(this.timers.show=l.call(this,function(){this.render("object"==typeof a||c.show.ready)},c.prerender?0:c.show.delay)))}var c=this.options,e=c.show.target,f=c.hide.target,g=c.show.event?d.trim(""+c.show.event).split(" "):[],h=c.hide.event?d.trim(""+c.hide.event).split(" "):[];this._bind(this.elements.target,["remove","removeqtip"],function(){this.destroy(!0)},"destroy"),/mouse(over|enter)/i.test(c.show.event)&&!/mouse(out|leave)/i.test(c.hide.event)&&h.push("mouseleave"),this._bind(e,"mousemove",function(a){this._storeMouse(a),this.cache.onTarget=B}),this._bindEvents(g,h,e,f,b,function(){return this.timers?void clearTimeout(this.timers.show):C}),(c.show.ready||c.prerender)&&b.call(this,a)},x._assignEvents=function(){var c=this,e=this.options,f=e.position,g=this.tooltip,h=e.show.target,i=e.hide.target,j=f.container,k=f.viewport,l=d(b),q=d(a),r=e.show.event?d.trim(""+e.show.event).split(" "):[],s=e.hide.event?d.trim(""+e.hide.event).split(" "):[];d.each(e.events,function(a,b){c._bind(g,"toggle"===a?["tooltipshow","tooltiphide"]:["tooltip"+a],b,null,g)}),/mouse(out|leave)/i.test(e.hide.event)&&"window"===e.hide.leave&&this._bind(l,["mouseout","blur"],function(a){/select|option/.test(a.target.nodeName)||a.relatedTarget||this.hide(a)}),e.hide.fixed?i=i.add(g.addClass(W)):/mouse(over|enter)/i.test(e.show.event)&&this._bind(i,"mouseleave",function(){clearTimeout(this.timers.show)}),(""+e.hide.event).indexOf("unfocus")>-1&&this._bind(j.closest("html"),["mousedown","touchstart"],function(a){var b=d(a.target),c=this.rendered&&!this.tooltip.hasClass($)&&this.tooltip[0].offsetWidth>0,e=b.parents(U).filter(this.tooltip[0]).length>0;b[0]===this.target[0]||b[0]===this.tooltip[0]||e||this.target.has(b[0]).length||!c||this.hide(a)}),"number"==typeof e.hide.inactive&&(this._bind(h,"qtip-"+this.id+"-inactive",o,"inactive"),this._bind(i.add(g),w.inactiveEvents,o)),this._bindEvents(r,s,h,i,m,n),this._bind(h.add(g),"mousemove",function(a){if("number"==typeof e.hide.distance){var b=this.cache.origin||{},c=this.options.hide.distance,d=Math.abs;(d(a.pageX-b.pageX)>=c||d(a.pageY-b.pageY)>=c)&&this.hide(a)}this._storeMouse(a)}),"mouse"===f.target&&f.adjust.mouse&&(e.hide.event&&this._bind(h,["mouseenter","mouseleave"],function(a){return this.cache?void(this.cache.onTarget="mouseenter"===a.type):C}),this._bind(l,"mousemove",function(a){this.rendered&&this.cache.onTarget&&!this.tooltip.hasClass($)&&this.tooltip[0].offsetWidth>0&&this.reposition(a)})),(f.adjust.resize||k.length)&&this._bind(d.event.special.resize?k:q,"resize",p),f.adjust.scroll&&this._bind(q.add(f.container),"scroll",p)},x._unassignEvents=function(){var c=this.options,e=c.show.target,f=c.hide.target,g=d.grep([this.elements.target[0],this.rendered&&this.tooltip[0],c.position.container[0],c.position.viewport[0],c.position.container.closest("html")[0],a,b],function(a){return"object"==typeof a});e&&e.toArray&&(g=g.concat(e.toArray())),f&&f.toArray&&(g=g.concat(f.toArray())),this._unbind(g)._unbind(g,"destroy")._unbind(g,"inactive")},d(function(){q(U,["mouseenter","mouseleave"],function(a){var b="mouseenter"===a.type,c=d(a.currentTarget),e=d(a.relatedTarget||a.target),f=this.options;b?(this.focus(a),c.hasClass(W)&&!c.hasClass($)&&clearTimeout(this.timers.hide)):"mouse"===f.position.target&&f.position.adjust.mouse&&f.hide.event&&f.show.target&&!e.closest(f.show.target[0]).length&&this.hide(a),c.toggleClass(Z,b)}),q("["+S+"]",V,o)}),w=d.fn.qtip=function(a,b,e){var f=(""+a).toLowerCase(),g=D,i=d.makeArray(arguments).slice(1),j=i[i.length-1],k=this[0]?d.data(this[0],Q):D;return!arguments.length&&k||"api"===f?k:"string"==typeof a?(this.each(function(){var a=d.data(this,Q);if(!a)return B;if(j&&j.timeStamp&&(a.cache.event=j),!b||"option"!==f&&"options"!==f)a[f]&&a[f].apply(a,i);else{if(e===c&&!d.isPlainObject(b))return g=a.get(b),C;a.set(b,e)}}),g!==D?g:this):"object"!=typeof a&&arguments.length?void 0:(k=h(d.extend(B,{},a)),this.each(function(a){var b,c;return c=d.isArray(k.id)?k.id[a]:k.id,c=!c||c===C||c.length<1||w.api[c]?w.nextid++:c,b=r(d(this),c,k),b===C?B:(w.api[c]=b,d.each(P,function(){"initialize"===this.initialize&&this(b)}),void b._assignInitialEvents(j))}))},d.qtip=e,w.api={},d.each({attr:function(a,b){if(this.length){var c=this[0],e="title",f=d.data(c,"qtip");if(a===e&&f&&f.options&&"object"==typeof f&&"object"==typeof f.options&&f.options.suppress)return arguments.length<2?d.attr(c,aa):(f&&f.options.content.attr===e&&f.cache.attr&&f.set("content.text",b),this.attr(aa,b))}return d.fn["attr"+_].apply(this,arguments)},clone:function(a){var b=d.fn["clone"+_].apply(this,arguments);return a||b.filter("["+aa+"]").attr("title",function(){return d.attr(this,aa)}).removeAttr(aa),b}},function(a,b){if(!b||d.fn[a+_])return B;var c=d.fn[a+_]=d.fn[a];d.fn[a]=function(){return b.apply(this,arguments)||c.apply(this,arguments)}}),d.ui||(d["cleanData"+_]=d.cleanData,d.cleanData=function(a){for(var b,c=0;(b=d(a[c])).length;c++)if(b.attr(R))try{b.triggerHandler("removeqtip")}catch(e){}d["cleanData"+_].apply(this,arguments)}),w.version="3.0.3",w.nextid=0,w.inactiveEvents=V,w.zindex=15e3,w.defaults={prerender:C,id:C,overwrite:B,suppress:B,content:{text:B,attr:"title",title:C,button:C},position:{my:"top left",at:"bottom right",target:C,container:C,viewport:C,adjust:{x:0,y:0,mouse:B,scroll:B,resize:B,method:"flipinvert flipinvert"},effect:function(a,b){d(this).animate(b,{duration:200,queue:C})}},show:{target:C,event:"mouseenter",effect:B,delay:90,solo:C,ready:C,autofocus:C},hide:{target:C,event:"mouseleave",effect:B,delay:0,fixed:C,inactive:C,leave:"window",distance:C},style:{classes:"",widget:C,width:C,height:C,def:B},events:{render:D,move:D,show:D,hide:D,toggle:D,visible:D,hidden:D,focus:D,blur:D}};var fa,ga,ha,ia,ja,ka="margin",la="border",ma="color",na="background-color",oa="transparent",pa=" !important",qa=!!b.createElement("canvas").getContext,ra=/rgba?\(0, 0, 0(, 0)?\)|transparent|#123456/i,sa={},ta=["Webkit","O","Moz","ms"];qa?(ia=a.devicePixelRatio||1,ja=function(){var a=b.createElement("canvas").getContext("2d");return a.backingStorePixelRatio||a.webkitBackingStorePixelRatio||a.mozBackingStorePixelRatio||a.msBackingStorePixelRatio||a.oBackingStorePixelRatio||1}(),ha=ia/ja):ga=function(a,b,c){return"<qtipvml:"+a+' xmlns="urn:schemas-microsoft.com:vml" class="qtip-vml" '+(b||"")+' style="behavior: url(#default#VML); '+(c||"")+'" />'},d.extend(v.prototype,{init:function(a){var b,c;c=this.element=a.elements.tip=d("<div />",{"class":Q+"-tip"}).prependTo(a.tooltip),qa?(b=d("<canvas />").appendTo(this.element)[0].getContext("2d"),b.lineJoin="miter",b.miterLimit=1e5,b.save()):(b=ga("shape",'coordorigin="0,0"',"position:absolute;"),this.element.html(b+b),a._bind(d("*",c).add(c),["click","mousedown"],function(a){a.stopPropagation()},this._ns)),a._bind(a.tooltip,"tooltipmove",this.reposition,this._ns,this),this.create()},_swapDimensions:function(){this.size[0]=this.options.height,this.size[1]=this.options.width},_resetDimensions:function(){this.size[0]=this.options.width,this.size[1]=this.options.height},_useTitle:function(a){var b=this.qtip.elements.titlebar;return b&&(a.y===I||a.y===M&&this.element.position().top+this.size[1]/2+this.options.offset<b.outerHeight(B))},_parseCorner:function(a){var b=this.qtip.options.position.my;return a===C||b===C?a=C:a===B?a=new y(b.string()):a.string||(a=new y(a),a.fixed=B),a},_parseWidth:function(a,b,c){var d=this.qtip.elements,e=la+s(b)+"Width";return(c?u(c,e):u(d.content,e)||u(this._useTitle(a)&&d.titlebar||d.content,e)||u(d.tooltip,e))||0},_parseRadius:function(a){var b=this.qtip.elements,c=la+s(a.y)+s(a.x)+"Radius";return ba.ie<9?0:u(this._useTitle(a)&&b.titlebar||b.content,c)||u(b.tooltip,c)||0},_invalidColour:function(a,b,c){var d=a.css(b);return!d||c&&d===a.css(c)||ra.test(d)?C:d},_parseColours:function(a){var b=this.qtip.elements,c=this.element.css("cssText",""),e=la+s(a[a.precedance])+s(ma),f=this._useTitle(a)&&b.titlebar||b.content,g=this._invalidColour,h=[];return h[0]=g(c,na)||g(f,na)||g(b.content,na)||g(b.tooltip,na)||c.css(na),h[1]=g(c,e,ma)||g(f,e,ma)||g(b.content,e,ma)||g(b.tooltip,e,ma)||b.tooltip.css(e),d("*",c).add(c).css("cssText",na+":"+oa+pa+";"+la+":0"+pa+";"),h},_calculateSize:function(a){var b,c,d,e=a.precedance===F,f=this.options.width,g=this.options.height,h="c"===a.abbrev(),i=(e?f:g)*(h?.5:1),j=Math.pow,k=Math.round,l=Math.sqrt(j(i,2)+j(g,2)),m=[this.border/i*l,this.border/g*l];return m[2]=Math.sqrt(j(m[0],2)-j(this.border,2)),m[3]=Math.sqrt(j(m[1],2)-j(this.border,2)),b=l+m[2]+m[3]+(h?0:m[0]),c=b/l,d=[k(c*f),k(c*g)],e?d:d.reverse()},_calculateTip:function(a,b,c){c=c||1,b=b||this.size;var d=b[0]*c,e=b[1]*c,f=Math.ceil(d/2),g=Math.ceil(e/2),h={br:[0,0,d,e,d,0],bl:[0,0,d,0,0,e],tr:[0,e,d,0,d,e],tl:[0,0,0,e,d,e],tc:[0,e,f,0,d,e],bc:[0,0,d,0,f,e],rc:[0,0,d,g,0,e],lc:[d,0,d,e,0,g]};return h.lt=h.br,h.rt=h.bl,h.lb=h.tr,h.rb=h.tl,h[a.abbrev()]},_drawCoords:function(a,b){a.beginPath(),a.moveTo(b[0],b[1]),a.lineTo(b[2],b[3]),a.lineTo(b[4],b[5]),a.closePath()},create:function(){var a=this.corner=(qa||ba.ie)&&this._parseCorner(this.options.corner);return this.enabled=!!this.corner&&"c"!==this.corner.abbrev(),this.enabled&&(this.qtip.cache.corner=a.clone(),this.update()),this.element.toggle(this.enabled),this.corner},update:function(b,c){if(!this.enabled)return this;var e,f,g,h,i,j,k,l,m=this.qtip.elements,n=this.element,o=n.children(),p=this.options,q=this.size,r=p.mimic,s=Math.round;b||(b=this.qtip.cache.corner||this.corner),r===C?r=b:(r=new y(r),r.precedance=b.precedance,"inherit"===r.x?r.x=b.x:"inherit"===r.y?r.y=b.y:r.x===r.y&&(r[b.precedance]=b[b.precedance])),f=r.precedance,b.precedance===E?this._swapDimensions():this._resetDimensions(),e=this.color=this._parseColours(b),e[1]!==oa?(l=this.border=this._parseWidth(b,b[b.precedance]),p.border&&1>l&&!ra.test(e[1])&&(e[0]=e[1]),this.border=l=p.border!==B?p.border:l):this.border=l=0,k=this.size=this._calculateSize(b),n.css({width:k[0],height:k[1],lineHeight:k[1]+"px"}),j=b.precedance===F?[s(r.x===J?l:r.x===L?k[0]-q[0]-l:(k[0]-q[0])/2),s(r.y===I?k[1]-q[1]:0)]:[s(r.x===J?k[0]-q[0]:0),s(r.y===I?l:r.y===K?k[1]-q[1]-l:(k[1]-q[1])/2)],qa?(g=o[0].getContext("2d"),g.restore(),g.save(),g.clearRect(0,0,6e3,6e3),h=this._calculateTip(r,q,ha),i=this._calculateTip(r,this.size,ha),o.attr(G,k[0]*ha).attr(H,k[1]*ha),o.css(G,k[0]).css(H,k[1]),this._drawCoords(g,i),g.fillStyle=e[1],g.fill(),g.translate(j[0]*ha,j[1]*ha),this._drawCoords(g,h),g.fillStyle=e[0],g.fill()):(h=this._calculateTip(r),h="m"+h[0]+","+h[1]+" l"+h[2]+","+h[3]+" "+h[4]+","+h[5]+" xe",j[2]=l&&/^(r|b)/i.test(b.string())?8===ba.ie?2:1:0,o.css({coordsize:k[0]+l+" "+k[1]+l,antialias:""+(r.string().indexOf(M)>-1),left:j[0]-j[2]*Number(f===E),top:j[1]-j[2]*Number(f===F),width:k[0]+l,height:k[1]+l}).each(function(a){var b=d(this);b[b.prop?"prop":"attr"]({coordsize:k[0]+l+" "+k[1]+l,path:h,fillcolor:e[0],filled:!!a,stroked:!a}).toggle(!(!l&&!a)),!a&&b.html(ga("stroke",'weight="'+2*l+'px" color="'+e[1]+'" miterlimit="1000" joinstyle="miter"'))})),a.opera&&setTimeout(function(){m.tip.css({display:"inline-block",visibility:"visible"})},1),c!==C&&this.calculate(b,k)},calculate:function(a,b){if(!this.enabled)return C;var c,e,f=this,g=this.qtip.elements,h=this.element,i=this.options.offset,j={};return a=a||this.corner,c=a.precedance,b=b||this._calculateSize(a),e=[a.x,a.y],c===E&&e.reverse(),d.each(e,function(d,e){var h,k,l;e===M?(h=c===F?J:I,j[h]="50%",j[ka+"-"+h]=-Math.round(b[c===F?0:1]/2)+i):(h=f._parseWidth(a,e,g.tooltip),k=f._parseWidth(a,e,g.content),l=f._parseRadius(a),j[e]=Math.max(-f.border,d?k:i+(l>h?l:-h)))}),j[a[c]]-=b[c===E?0:1],h.css({margin:"",top:"",bottom:"",left:"",right:""}).css(j),j},reposition:function(a,b,d){function e(a,b,c,d,e){a===O&&j.precedance===b&&k[d]&&j[c]!==M?j.precedance=j.precedance===E?F:E:a!==O&&k[d]&&(j[b]=j[b]===M?k[d]>0?d:e:j[b]===d?e:d)}function f(a,b,e){j[a]===M?p[ka+"-"+b]=o[a]=g[ka+"-"+b]-k[b]:(h=g[e]!==c?[k[b],-g[b]]:[-k[b],g[b]],(o[a]=Math.max(h[0],h[1]))>h[0]&&(d[b]-=k[b],o[b]=C),p[g[e]!==c?e:b]=o[a])}if(this.enabled){var g,h,i=b.cache,j=this.corner.clone(),k=d.adjusted,l=b.options.position.adjust.method.split(" "),m=l[0],n=l[1]||l[0],o={left:C,top:C,x:0,y:0},p={};this.corner.fixed!==B&&(e(m,E,F,J,L),e(n,F,E,I,K),j.string()===i.corner.string()&&i.cornerTop===k.top&&i.cornerLeft===k.left||this.update(j,C)),g=this.calculate(j),g.right!==c&&(g.left=-g.right),g.bottom!==c&&(g.top=-g.bottom),g.user=this.offset,o.left=m===O&&!!k.left,o.left&&f(E,J,L),o.top=n===O&&!!k.top,o.top&&f(F,I,K),this.element.css(p).toggle(!(o.x&&o.y||j.x===M&&o.y||j.y===M&&o.x)),d.left-=g.left.charAt?g.user:m!==O||o.top||!o.left&&!o.top?g.left+this.border:0,d.top-=g.top.charAt?g.user:n!==O||o.left||!o.left&&!o.top?g.top+this.border:0,i.cornerLeft=k.left,i.cornerTop=k.top,i.corner=j.clone()}},destroy:function(){this.qtip._unbind(this.qtip.tooltip,this._ns),this.qtip.elements.tip&&this.qtip.elements.tip.find("*").remove().end().remove()}}),fa=P.tip=function(a){return new v(a,a.options.style.tip)},fa.initialize="render",fa.sanitize=function(a){if(a.style&&"tip"in a.style){var b=a.style.tip;"object"!=typeof b&&(b=a.style.tip={corner:b}),/string|boolean/i.test(typeof b.corner)||(b.corner=B)}},z.tip={"^position.my|style.tip.(corner|mimic|border)$":function(){this.create(),this.qtip.reposition()},"^style.tip.(height|width)$":function(a){this.size=[a.width,a.height],this.update(),this.qtip.reposition()},"^content.title|style.(classes|widget)$":function(){this.update()}},d.extend(B,w.defaults,{style:{tip:{corner:B,mimic:C,width:6,height:6,border:B,offset:0}}}),P.viewport=function(c,d,e,f,g,h,i){function j(a,b,c,e,f,g,h,i,j){var k=d[f],s=u[a],t=v[a],w=c===O,x=s===f?j:s===g?-j:-j/2,y=t===f?i:t===g?-i:-i/2,z=q[f]+r[f]-(n?0:m[f]),A=z-k,B=k+j-(h===G?o:p)-z,C=x-(u.precedance===a||s===u[b]?y:0)-(t===M?i/2:0);return w?(C=(s===f?1:-1)*x,d[f]+=A>0?A:B>0?-B:0,d[f]=Math.max(-m[f]+r[f],k-C,Math.min(Math.max(-m[f]+r[f]+(h===G?o:p),k+C),d[f],"center"===s?k-x:1e9))):(e*=c===N?2:0,A>0&&(s!==f||B>0)?(d[f]-=C+e,l.invert(a,f)):B>0&&(s!==g||A>0)&&(d[f]-=(s===M?-C:C)+e,l.invert(a,g)),d[f]<q[f]&&-d[f]>B&&(d[f]=k,l=u.clone())),d[f]-k}var k,l,m,n,o,p,q,r,s=e.target,t=c.elements.tooltip,u=e.my,v=e.at,w=e.adjust,x=w.method.split(" "),y=x[0],z=x[1]||x[0],A=e.viewport,B=e.container,D={left:0,top:0};return A.jquery&&s[0]!==a&&s[0]!==b.body&&"none"!==w.method?(m=B.offset()||D,n="static"===B.css("position"),k="fixed"===t.css("position"),o=A[0]===a?A.width():A.outerWidth(C),p=A[0]===a?A.height():A.outerHeight(C),q={left:k?0:A.scrollLeft(),top:k?0:A.scrollTop()},r=A.offset()||D,"shift"===y&&"shift"===z||(l=u.clone()),D={left:"none"!==y?j(E,F,y,w.x,J,L,G,f,h):0,top:"none"!==z?j(F,E,z,w.y,I,K,H,g,i):0,my:l}):D}})}(window,document);
|
513 |
+
|
514 |
+
/* bootstrap-switch v3.3.4 | http://bootstrapswitch.com/ | Copyright (c) 2012-2017 Mattia Larentis & Emanuele Marchi. Released under the Apache 2.0 license. */
|
515 |
+
(function(a,b){if('function'==typeof define&&define.amd)define(['jquery'],b);else if('undefined'!=typeof exports)b(require('jquery'));else{b(a.jquery),a.bootstrapSwitch={exports:{}}.exports}})(this,function(a){'use strict';function c(j,k){if(!(j instanceof k))throw new TypeError('Cannot call a class as a function')}var d=function(j){return j&&j.__esModule?j:{default:j}}(a),e=Object.assign||function(j){for(var l,k=1;k<arguments.length;k++)for(var m in l=arguments[k],l)Object.prototype.hasOwnProperty.call(l,m)&&(j[m]=l[m]);return j},f=function(){function j(k,l){for(var n,m=0;m<l.length;m++)n=l[m],n.enumerable=n.enumerable||!1,n.configurable=!0,'value'in n&&(n.writable=!0),Object.defineProperty(k,n.key,n)}return function(k,l,m){return l&&j(k.prototype,l),m&&j(k,m),k}}(),g=d.default||window.jQuery||window.$,h=function(){function j(k){var l=this,m=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{};c(this,j),this.$element=g(k),this.options=g.extend({},g.fn.bootstrapSwitch.defaults,this._getElementOptions(),m),this.prevOptions={},this.$wrapper=g('<div>',{class:function(){var o=[];return o.push(l.options.state?'on':'off'),l.options.size&&o.push(l.options.size),l.options.disabled&&o.push('disabled'),l.options.readonly&&o.push('readonly'),l.options.indeterminate&&o.push('indeterminate'),l.options.inverse&&o.push('inverse'),l.$element.attr('id')&&o.push('id-'+l.$element.attr('id')),o.map(l._getClass.bind(l)).concat([l.options.baseClass],l._getClasses(l.options.wrapperClass)).join(' ')}}),this.$container=g('<div>',{class:this._getClass('container')}),this.$on=g('<span>',{html:this.options.onText,class:this._getClass('handle-on')+' '+this._getClass(this.options.onColor)}),this.$off=g('<span>',{html:this.options.offText,class:this._getClass('handle-off')+' '+this._getClass(this.options.offColor)}),this.$label=g('<span>',{html:this.options.labelText,class:this._getClass('label')}),this.$element.on('init.bootstrapSwitch',this.options.onInit.bind(this,k)),this.$element.on('switchChange.bootstrapSwitch',function(){for(var n=arguments.length,o=Array(n),p=0;p<n;p++)o[p]=arguments[p];!1===l.options.onSwitchChange.apply(k,o)&&(l.$element.is(':radio')?g('[name="'+l.$element.attr('name')+'"]').trigger('previousState.bootstrapSwitch',!0):l.$element.trigger('previousState.bootstrapSwitch',!0))}),this.$container=this.$element.wrap(this.$container).parent(),this.$wrapper=this.$container.wrap(this.$wrapper).parent(),this.$element.before(this.options.inverse?this.$off:this.$on).before(this.$label).before(this.options.inverse?this.$on:this.$off),this.options.indeterminate&&this.$element.prop('indeterminate',!0),this._init(),this._elementHandlers(),this._handleHandlers(),this._labelHandlers(),this._formHandler(),this._externalLabelHandler(),this.$element.trigger('init.bootstrapSwitch',this.options.state)}return f(j,[{key:'setPrevOptions',value:function(){this.prevOptions=e({},this.options)}},{key:'state',value:function(l,m){return'undefined'==typeof l?this.options.state:this.options.disabled||this.options.readonly||this.options.state&&!this.options.radioAllOff&&this.$element.is(':radio')?this.$element:(this.$element.is(':radio')?g('[name="'+this.$element.attr('name')+'"]').trigger('setPreviousOptions.bootstrapSwitch'):this.$element.trigger('setPreviousOptions.bootstrapSwitch'),this.options.indeterminate&&this.indeterminate(!1),this.$element.prop('checked',!!l).trigger('change.bootstrapSwitch',m),this.$element)}},{key:'toggleState',value:function(l){return this.options.disabled||this.options.readonly?this.$element:this.options.indeterminate?(this.indeterminate(!1),this.state(!0)):this.$element.prop('checked',!this.options.state).trigger('change.bootstrapSwitch',l)}},{key:'size',value:function(l){return'undefined'==typeof l?this.options.size:(null!=this.options.size&&this.$wrapper.removeClass(this._getClass(this.options.size)),l&&this.$wrapper.addClass(this._getClass(l)),this._width(),this._containerPosition(),this.options.size=l,this.$element)}},{key:'animate',value:function(l){return'undefined'==typeof l?this.options.animate:this.options.animate===!!l?this.$element:this.toggleAnimate()}},{key:'toggleAnimate',value:function(){return this.options.animate=!this.options.animate,this.$wrapper.toggleClass(this._getClass('animate')),this.$element}},{key:'disabled',value:function(l){return'undefined'==typeof l?this.options.disabled:this.options.disabled===!!l?this.$element:this.toggleDisabled()}},{key:'toggleDisabled',value:function(){return this.options.disabled=!this.options.disabled,this.$element.prop('disabled',this.options.disabled),this.$wrapper.toggleClass(this._getClass('disabled')),this.$element}},{key:'readonly',value:function(l){return'undefined'==typeof l?this.options.readonly:this.options.readonly===!!l?this.$element:this.toggleReadonly()}},{key:'toggleReadonly',value:function(){return this.options.readonly=!this.options.readonly,this.$element.prop('readonly',this.options.readonly),this.$wrapper.toggleClass(this._getClass('readonly')),this.$element}},{key:'indeterminate',value:function(l){return'undefined'==typeof l?this.options.indeterminate:this.options.indeterminate===!!l?this.$element:this.toggleIndeterminate()}},{key:'toggleIndeterminate',value:function(){return this.options.indeterminate=!this.options.indeterminate,this.$element.prop('indeterminate',this.options.indeterminate),this.$wrapper.toggleClass(this._getClass('indeterminate')),this._containerPosition(),this.$element}},{key:'inverse',value:function(l){return'undefined'==typeof l?this.options.inverse:this.options.inverse===!!l?this.$element:this.toggleInverse()}},{key:'toggleInverse',value:function(){this.$wrapper.toggleClass(this._getClass('inverse'));var l=this.$on.clone(!0),m=this.$off.clone(!0);return this.$on.replaceWith(m),this.$off.replaceWith(l),this.$on=m,this.$off=l,this.options.inverse=!this.options.inverse,this.$element}},{key:'onColor',value:function(l){return'undefined'==typeof l?this.options.onColor:(this.options.onColor&&this.$on.removeClass(this._getClass(this.options.onColor)),this.$on.addClass(this._getClass(l)),this.options.onColor=l,this.$element)}},{key:'offColor',value:function(l){return'undefined'==typeof l?this.options.offColor:(this.options.offColor&&this.$off.removeClass(this._getClass(this.options.offColor)),this.$off.addClass(this._getClass(l)),this.options.offColor=l,this.$element)}},{key:'onText',value:function(l){return'undefined'==typeof l?this.options.onText:(this.$on.html(l),this._width(),this._containerPosition(),this.options.onText=l,this.$element)}},{key:'offText',value:function(l){return'undefined'==typeof l?this.options.offText:(this.$off.html(l),this._width(),this._containerPosition(),this.options.offText=l,this.$element)}},{key:'labelText',value:function(l){return'undefined'==typeof l?this.options.labelText:(this.$label.html(l),this._width(),this.options.labelText=l,this.$element)}},{key:'handleWidth',value:function(l){return'undefined'==typeof l?this.options.handleWidth:(this.options.handleWidth=l,this._width(),this._containerPosition(),this.$element)}},{key:'labelWidth',value:function(l){return'undefined'==typeof l?this.options.labelWidth:(this.options.labelWidth=l,this._width(),this._containerPosition(),this.$element)}},{key:'baseClass',value:function(){return this.options.baseClass}},{key:'wrapperClass',value:function(l){return'undefined'==typeof l?this.options.wrapperClass:(l||(l=g.fn.bootstrapSwitch.defaults.wrapperClass),this.$wrapper.removeClass(this._getClasses(this.options.wrapperClass).join(' ')),this.$wrapper.addClass(this._getClasses(l).join(' ')),this.options.wrapperClass=l,this.$element)}},{key:'radioAllOff',value:function(l){if('undefined'==typeof l)return this.options.radioAllOff;var m=!!l;return this.options.radioAllOff===m?this.$element:(this.options.radioAllOff=m,this.$element)}},{key:'onInit',value:function(l){return'undefined'==typeof l?this.options.onInit:(l||(l=g.fn.bootstrapSwitch.defaults.onInit),this.options.onInit=l,this.$element)}},{key:'onSwitchChange',value:function(l){return'undefined'==typeof l?this.options.onSwitchChange:(l||(l=g.fn.bootstrapSwitch.defaults.onSwitchChange),this.options.onSwitchChange=l,this.$element)}},{key:'destroy',value:function(){var l=this.$element.closest('form');return l.length&&l.off('reset.bootstrapSwitch').removeData('bootstrap-switch'),this.$container.children().not(this.$element).remove(),this.$element.unwrap().unwrap().off('.bootstrapSwitch').removeData('bootstrap-switch'),this.$element}},{key:'_getElementOptions',value:function(){return{state:this.$element.is(':checked'),size:this.$element.data('size'),animate:this.$element.data('animate'),disabled:this.$element.is(':disabled'),readonly:this.$element.is('[readonly]'),indeterminate:this.$element.data('indeterminate'),inverse:this.$element.data('inverse'),radioAllOff:this.$element.data('radio-all-off'),onColor:this.$element.data('on-color'),offColor:this.$element.data('off-color'),onText:this.$element.data('on-text'),offText:this.$element.data('off-text'),labelText:this.$element.data('label-text'),handleWidth:this.$element.data('handle-width'),labelWidth:this.$element.data('label-width'),baseClass:this.$element.data('base-class'),wrapperClass:this.$element.data('wrapper-class')}}},{key:'_width',value:function(){var l=this,m=this.$on.add(this.$off).add(this.$label).css('width',''),n='auto'===this.options.handleWidth?Math.round(Math.max(this.$on.width(),this.$off.width())):this.options.handleWidth;return m.width(n),this.$label.width(function(o,p){return'auto'===l.options.labelWidth?p<n?n:p:l.options.labelWidth}),this._handleWidth=this.$on.outerWidth(),this._labelWidth=this.$label.outerWidth(),this.$container.width(2*this._handleWidth+this._labelWidth),this.$wrapper.width(this._handleWidth+this._labelWidth)}},{key:'_containerPosition',value:function(){var l=this,m=0<arguments.length&&void 0!==arguments[0]?arguments[0]:this.options.state,n=arguments[1];this.$container.css('margin-left',function(){var o=[0,'-'+l._handleWidth+'px'];return l.options.indeterminate?'-'+l._handleWidth/2+'px':m?l.options.inverse?o[1]:o[0]:l.options.inverse?o[0]:o[1]})}},{key:'_init',value:function(){var l=this,m=function(){l.setPrevOptions(),l._width(),l._containerPosition(),setTimeout(function(){if(l.options.animate)return l.$wrapper.addClass(l._getClass('animate'))},50)};if(this.$wrapper.is(':visible'))return void m();var n=window.setInterval(function(){if(l.$wrapper.is(':visible'))return m(),window.clearInterval(n)},50)}},{key:'_elementHandlers',value:function(){var l=this;return this.$element.on({'setPreviousOptions.bootstrapSwitch':this.setPrevOptions.bind(this),'previousState.bootstrapSwitch':function(){l.options=l.prevOptions,l.options.indeterminate&&l.$wrapper.addClass(l._getClass('indeterminate')),l.$element.prop('checked',l.options.state).trigger('change.bootstrapSwitch',!0)},'change.bootstrapSwitch':function(n,o){n.preventDefault(),n.stopImmediatePropagation();var p=l.$element.is(':checked');l._containerPosition(p),p===l.options.state||(l.options.state=p,l.$wrapper.toggleClass(l._getClass('off')).toggleClass(l._getClass('on')),!o&&(l.$element.is(':radio')&&g('[name="'+l.$element.attr('name')+'"]').not(l.$element).prop('checked',!1).trigger('change.bootstrapSwitch',!0),l.$element.trigger('switchChange.bootstrapSwitch',[p])))},'focus.bootstrapSwitch':function(n){n.preventDefault(),l.$wrapper.addClass(l._getClass('focused'))},'blur.bootstrapSwitch':function(n){n.preventDefault(),l.$wrapper.removeClass(l._getClass('focused'))},'keydown.bootstrapSwitch':function(n){!n.which||l.options.disabled||l.options.readonly||(37===n.which||39===n.which)&&(n.preventDefault(),n.stopImmediatePropagation(),l.state(39===n.which))}})}},{key:'_handleHandlers',value:function(){var l=this;return this.$on.on('click.bootstrapSwitch',function(m){return m.preventDefault(),m.stopPropagation(),l.state(!1),l.$element.trigger('focus.bootstrapSwitch')}),this.$off.on('click.bootstrapSwitch',function(m){return m.preventDefault(),m.stopPropagation(),l.state(!0),l.$element.trigger('focus.bootstrapSwitch')})}},{key:'_labelHandlers',value:function(){var l=this;this.$label.on({click:function(o){o.stopPropagation()},'mousedown.bootstrapSwitch touchstart.bootstrapSwitch':function(o){l._dragStart||l.options.disabled||l.options.readonly||(o.preventDefault(),o.stopPropagation(),l._dragStart=(o.pageX||o.originalEvent.touches[0].pageX)-parseInt(l.$container.css('margin-left'),10),l.options.animate&&l.$wrapper.removeClass(l._getClass('animate')),l.$element.trigger('focus.bootstrapSwitch'))},'mousemove.bootstrapSwitch touchmove.bootstrapSwitch':function(o){if(null!=l._dragStart){var p=(o.pageX||o.originalEvent.touches[0].pageX)-l._dragStart;o.preventDefault(),p<-l._handleWidth||0<p||(l._dragEnd=p,l.$container.css('margin-left',l._dragEnd+'px'))}},'mouseup.bootstrapSwitch touchend.bootstrapSwitch':function(o){if(l._dragStart){if(o.preventDefault(),l.options.animate&&l.$wrapper.addClass(l._getClass('animate')),l._dragEnd){var p=l._dragEnd>-(l._handleWidth/2);l._dragEnd=!1,l.state(l.options.inverse?!p:p)}else l.state(!l.options.state);l._dragStart=!1}},'mouseleave.bootstrapSwitch':function(){l.$label.trigger('mouseup.bootstrapSwitch')}})}},{key:'_externalLabelHandler',value:function(){var l=this,m=this.$element.closest('label');m.on('click',function(n){n.preventDefault(),n.stopImmediatePropagation(),n.target===m[0]&&l.toggleState()})}},{key:'_formHandler',value:function(){var l=this.$element.closest('form');l.data('bootstrap-switch')||l.on('reset.bootstrapSwitch',function(){window.setTimeout(function(){l.find('input').filter(function(){return g(this).data('bootstrap-switch')}).each(function(){return g(this).bootstrapSwitch('state',this.checked)})},1)}).data('bootstrap-switch',!0)}},{key:'_getClass',value:function(l){return this.options.baseClass+'-'+l}},{key:'_getClasses',value:function(l){return g.isArray(l)?l.map(this._getClass.bind(this)):[this._getClass(l)]}}]),j}();g.fn.bootstrapSwitch=function(j){for(var l=arguments.length,m=Array(1<l?l-1:0),n=1;n<l;n++)m[n-1]=arguments[n];return Array.prototype.reduce.call(this,function(o,p){var q=g(p),r=q.data('bootstrap-switch'),s=r||new h(p,j);return r||q.data('bootstrap-switch',s),'string'==typeof j?s[j].apply(s,m):o},this)},g.fn.bootstrapSwitch.Constructor=h,g.fn.bootstrapSwitch.defaults={state:!0,size:null,animate:!0,disabled:!1,readonly:!1,indeterminate:!1,inverse:!1,radioAllOff:!1,onColor:'primary',offColor:'default',onText:'ON',offText:'OFF',labelText:' ',handleWidth:'auto',labelWidth:'auto',baseClass:'bootstrap-switch',wrapperClass:'wrapper',onInit:function(){},onSwitchChange:function(){}}});
|
516 |
+
|
517 |
+
/* caret v1.3.3 | https://github.com/accursoft/caret | Copyright (c) 2009 Gideon Sireling. Released under the BSD3 license. */
|
518 |
+
!function(e){e.fn.caret=function(e){var t=this[0],n="true"===t.contentEditable;if(0==arguments.length){if(window.getSelection){if(n){t.focus();var o=window.getSelection().getRangeAt(0),r=o.cloneRange();return r.selectNodeContents(t),r.setEnd(o.endContainer,o.endOffset),r.toString().length}return t.selectionStart}if(document.selection){if(t.focus(),n){var o=document.selection.createRange(),r=document.body.createTextRange();return r.moveToElementText(t),r.setEndPoint("EndToEnd",o),r.text.length}var e=0,c=t.createTextRange(),r=document.selection.createRange().duplicate(),a=r.getBookmark();for(c.moveToBookmark(a);0!==c.moveStart("character",-1);)e++;return e}return t.selectionStart?t.selectionStart:0}if(-1==e&&(e=this[n?"text":"val"]().length),window.getSelection)n?(t.focus(),window.getSelection().collapse(t.firstChild,e)):t.setSelectionRange(e,e);else if(document.body.createTextRange)if(n){var c=document.body.createTextRange();c.moveToElementText(t),c.moveStart("character",e),c.collapse(!0),c.select()}else{var c=t.createTextRange();c.move("character",e),c.select()}return n||t.focus(),e}}(jQuery);
|
519 |
+
|
520 |
+
/* jQuery tagEditor v1.0.21 | https://github.com/Pixabay/jQuery-tagEditor | Copyright (c) 2013 Pixabay. Licensed under the MIT license. */
|
521 |
!function(t){t.fn.tagEditorInput=function(){var e=" ",i=t(this),a=parseInt(i.css("fontSize")),r=t("<span/>").css({position:"absolute",top:-9999,left:-9999,width:"auto",fontSize:i.css("fontSize"),fontFamily:i.css("fontFamily"),fontWeight:i.css("fontWeight"),letterSpacing:i.css("letterSpacing"),whiteSpace:"nowrap"}),l=function(){if(e!==(e=i.val())){r.text(e);var t=r.width()+a;20>t&&(t=20),t!=i.width()&&i.width(t)}};return r.insertAfter(i),i.bind("keyup keydown focus",l)},t.fn.tagEditor=function(e,a,r){function l(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}var n,o=t.extend({},t.fn.tagEditor.defaults,e),c=this;if(o.dregex=new RegExp("["+o.delimiter.replace("-","-")+"]","g"),"string"==typeof e){var s=[];return c.each(function(){var i=t(this),l=i.data("options"),n=i.next(".tag-editor");if("getTags"==e)s.push({field:i[0],editor:n,tags:n.data("tags")});else if("addTag"==e){if(l.maxTags&&n.data("tags").length>=l.maxTags)return!1;t('<li><div class="tag-editor-spacer"> '+l.delimiter[0]+'</div><div class="tag-editor-tag"></div><div class="tag-editor-delete"><i></i></div></li>').appendTo(n).find(".tag-editor-tag").html('<input type="text" maxlength="'+l.maxLength+'">').addClass("active").find("input").val(a).blur(),r?t(".placeholder",n).remove():n.click()}else"removeTag"==e?(t(".tag-editor-tag",n).filter(function(){return t(this).text()==a}).closest("li").find(".tag-editor-delete").click(),r||n.click()):"destroy"==e&&i.removeClass("tag-editor-hidden-src").removeData("options").off("focus.tag-editor").next(".tag-editor").remove()}),"getTags"==e?s:this}return window.getSelection&&t(document).off("keydown.tag-editor").on("keydown.tag-editor",function(e){if(8==e.which||46==e.which||e.ctrlKey&&88==e.which){try{var a=getSelection(),r="INPUT"!=document.activeElement.tagName?t(a.getRangeAt(0).startContainer.parentNode).closest(".tag-editor"):0}catch(e){r=0}if(a.rangeCount>0&&r&&r.length){var l=[],n=a.toString().split(r.prev().data("options").dregex);for(i=0;i<n.length;i++){var o=t.trim(n[i]);o&&l.push(o)}return t(".tag-editor-tag",r).each(function(){~t.inArray(t(this).text(),l)&&t(this).closest("li").find(".tag-editor-delete").click()}),!1}}}),c.each(function(){function e(){!o.placeholder||c.length||t(".deleted, .placeholder, input",s).length||s.append('<li class="placeholder"><div>'+o.placeholder+"</div></li>")}function i(i){var a=c.toString();c=t(".tag-editor-tag:not(.deleted)",s).map(function(e,i){var a=t.trim(t(this).hasClass("active")?t(this).find("input").val():t(i).text());return a?a:void 0}).get(),s.data("tags",c),r.val(c.join(o.delimiter[0])),i||a!=c.toString()&&o.onChange(r,s,c),e()}function a(e){for(var a,n=e.closest("li"),d=e.val().replace(/ +/," ").split(o.dregex),g=e.data("old_tag"),f=c.slice(0),h=!1,u=0;u<d.length;u++)if(v=t.trim(d[u]).slice(0,o.maxLength),o.forceLowercase&&(v=v.toLowerCase()),a=o.beforeTagSave(r,s,f,g,v),v=a||v,a!==!1&&v&&(o.removeDuplicates&&~t.inArray(v,f)&&t(".tag-editor-tag",s).each(function(){t(this).text()==v&&t(this).closest("li").remove()}),f.push(v),n.before('<li><div class="tag-editor-spacer"> '+o.delimiter[0]+'</div><div class="tag-editor-tag">'+l(v)+'</div><div class="tag-editor-delete"><i></i></div></li>'),o.maxTags&&f.length>=o.maxTags)){h=!0;break}e.attr("maxlength",o.maxLength).removeData("old_tag").val(""),h?e.blur():e.focus(),i()}var r=t(this),c=[],s=t("<ul "+(o.clickDelete?'oncontextmenu="return false;" ':"")+'class="tag-editor"></ul>').insertAfter(r);r.addClass("tag-editor-hidden-src").data("options",o).on("focus.tag-editor",function(){s.click()}),s.append('<li style="width:1px"> </li>');var d='<li><div class="tag-editor-spacer"> '+o.delimiter[0]+'</div><div class="tag-editor-tag"></div><div class="tag-editor-delete"><i></i></div></li>';s.click(function(e,i){var a,r,l=99999;if(!window.getSelection||""==getSelection())return o.maxTags&&s.data("tags").length>=o.maxTags?(s.find("input").blur(),!1):(n=!0,t("input:focus",s).blur(),n?(n=!0,t(".placeholder",s).remove(),i&&i.length?r="before":t(".tag-editor-tag",s).each(function(){var n=t(this),o=n.offset(),c=o.left,s=o.top;e.pageY>=s&&e.pageY<=s+n.height()&&(e.pageX<c?(r="before",a=c-e.pageX):(r="after",a=e.pageX-c-n.width()),l>a&&(l=a,i=n))}),"before"==r?t(d).insertBefore(i.closest("li")).find(".tag-editor-tag").click():"after"==r?t(d).insertAfter(i.closest("li")).find(".tag-editor-tag").click():t(d).appendTo(s).find(".tag-editor-tag").click(),!1):!1)}),s.on("click",".tag-editor-delete",function(){if(t(this).prev().hasClass("active"))return t(this).closest("li").find("input").caret(-1),!1;var a=t(this).closest("li"),l=a.find(".tag-editor-tag");return o.beforeTagDelete(r,s,c,l.text())===!1?!1:(l.addClass("deleted").animate({width:0},o.animateDelete,function(){a.remove(),e()}),i(),!1)}),o.clickDelete&&s.on("mousedown",".tag-editor-tag",function(a){if(a.ctrlKey||a.which>1){var l=t(this).closest("li"),n=l.find(".tag-editor-tag");return o.beforeTagDelete(r,s,c,n.text())===!1?!1:(n.addClass("deleted").animate({width:0},o.animateDelete,function(){l.remove(),e()}),i(),!1)}}),s.on("click",".tag-editor-tag",function(e){if(o.clickDelete&&(e.ctrlKey||e.which>1))return!1;if(!t(this).hasClass("active")){var i=t(this).text(),a=Math.abs((t(this).offset().left-e.pageX)/t(this).width()),r=parseInt(i.length*a),n=t(this).html('<input type="text" maxlength="'+o.maxLength+'" value="'+l(i)+'">').addClass("active").find("input");if(n.data("old_tag",i).tagEditorInput().focus().caret(r),o.autocomplete){var c=t.extend({},o.autocomplete),d="select"in c?o.autocomplete.select:"";c.select=function(e,i){d&&d(e,i),setTimeout(function(){s.trigger("click",[t(".active",s).find("input").closest("li").next("li").find(".tag-editor-tag")])},20)},n.autocomplete(c)}}return!1}),s.on("blur","input",function(d){d.stopPropagation();var g=t(this),f=g.data("old_tag"),h=t.trim(g.val().replace(/ +/," ").replace(o.dregex,o.delimiter[0]));if(h){if(h.indexOf(o.delimiter[0])>=0)return void a(g);if(h!=f)if(o.forceLowercase&&(h=h.toLowerCase()),cb_val=o.beforeTagSave(r,s,c,f,h),h=cb_val||h,cb_val===!1){if(f)return g.val(f).focus(),n=!1,void i();try{g.closest("li").remove()}catch(d){}f&&i()}else o.removeDuplicates&&t(".tag-editor-tag:not(.active)",s).each(function(){t(this).text()==h&&t(this).closest("li").remove()})}else{if(f&&o.beforeTagDelete(r,s,c,f)===!1)return g.val(f).focus(),n=!1,void i();try{g.closest("li").remove()}catch(d){}f&&i()}g.parent().html(l(h)).removeClass("active"),h!=f&&i(),e()});var g;s.on("paste","input",function(){t(this).removeAttr("maxlength"),g=t(this),setTimeout(function(){a(g)},30)});var f;s.on("keypress","input",function(e){o.delimiter.indexOf(String.fromCharCode(e.which))>=0&&(f=t(this),setTimeout(function(){a(f)},20))}),s.on("keydown","input",function(e){var i=t(this);if((37==e.which||!o.autocomplete&&38==e.which)&&!i.caret()||8==e.which&&!i.val()){var a=i.closest("li").prev("li").find(".tag-editor-tag");return a.length?a.click().find("input").caret(-1):!i.val()||o.maxTags&&s.data("tags").length>=o.maxTags||t(d).insertBefore(i.closest("li")).find(".tag-editor-tag").click(),!1}if((39==e.which||!o.autocomplete&&40==e.which)&&i.caret()==i.val().length){var l=i.closest("li").next("li").find(".tag-editor-tag");return l.length?l.click().find("input").caret(0):i.val()&&s.click(),!1}if(9==e.which){if(e.shiftKey){var a=i.closest("li").prev("li").find(".tag-editor-tag");if(a.length)a.click().find("input").caret(0);else{if(!i.val()||o.maxTags&&s.data("tags").length>=o.maxTags)return r.attr("disabled","disabled"),void setTimeout(function(){r.removeAttr("disabled")},30);t(d).insertBefore(i.closest("li")).find(".tag-editor-tag").click()}return!1}var l=i.closest("li").next("li").find(".tag-editor-tag");if(l.length)l.click().find("input").caret(0);else{if(!i.val())return;s.click()}return!1}if(!(46!=e.which||t.trim(i.val())&&i.caret()!=i.val().length)){var l=i.closest("li").next("li").find(".tag-editor-tag");return l.length?l.click().find("input").caret(0):i.val()&&s.click(),!1}if(13==e.which)return s.trigger("click",[i.closest("li").next("li").find(".tag-editor-tag")]),o.maxTags&&s.data("tags").length>=o.maxTags&&s.find("input").blur(),!1;if(36!=e.which||i.caret()){if(35==e.which&&i.caret()==i.val().length)s.find(".tag-editor-tag").last().click();else if(27==e.which)return i.val(i.data("old_tag")?i.data("old_tag"):"").blur(),!1}else s.find(".tag-editor-tag").first().click()});for(var h=o.initialTags.length?o.initialTags:r.val().split(o.dregex),u=0;u<h.length&&!(o.maxTags&&u>=o.maxTags);u++){var v=t.trim(h[u].replace(/ +/," "));v&&(o.forceLowercase&&(v=v.toLowerCase()),c.push(v),s.append('<li><div class="tag-editor-spacer"> '+o.delimiter[0]+'</div><div class="tag-editor-tag">'+l(v)+'</div><div class="tag-editor-delete"><i></i></div></li>'))}i(!0),o.sortable&&t.fn.sortable&&s.sortable({distance:5,cancel:".tag-editor-spacer, input",helper:"clone",update:function(){i()}})})},t.fn.tagEditor.defaults={initialTags:[],maxTags:0,maxLength:50,delimiter:",;",placeholder:"",forceLowercase:!0,removeDuplicates:!0,clickDelete:!1,animateDelete:175,sortable:!0,autocomplete:null,onChange:function(){},beforeTagSave:function(){},beforeTagDelete:function(){}}}(jQuery);
|
admin/view/index.php
CHANGED
@@ -1,169 +1,164 @@
|
|
1 |
-
<?php if ( !function_exists( 'add_action' ) ) exit(); ?>
|
2 |
-
|
3 |
-
<div class="wrap slimstat">
|
4 |
-
<h2><?php echo wp_slimstat_admin::$screens_info[ $_GET[ 'page' ] ][ 'title' ] ?></h2>
|
5 |
-
|
6 |
-
<div class="notice slimstat-notice slimstat-tooltip-content" style="background-color:#ffa;border:0;padding:10px"><?php _e( '<strong>AdBlock browser extension detected</strong> - If you see this notice, it means that your browser is not loading our stylesheet and/or Javascript files correctly. This could be caused by an overzealous ad blocker feature enabled in your browser (AdBlock Plus and friends). <a href="https://slimstat.freshdesk.com/support/solutions/articles/12000000414-the-reports-are-not-being-rendered-correctly-or-buttons-do-not-work" target="_blank">Please make sure to add an exception</a> to your configuration and allow the browser to load these assets.', 'wp-slimstat' ); ?></div>
|
7 |
-
|
8 |
-
<form action="<?php echo wp_slimstat_reports::fs_url(); ?>" method="post" id="slimstat-filters-form">
|
9 |
-
<fieldset id="slimstat-filters"><?php
|
10 |
-
$filter_name_html = '<label for="slimstat-filter-name">Filter by</label><select name="f" id="slimstat-filter-name"><option value="" disabled selected>' . __( 'Filter', 'wp-slimstat' ) . '</option>';
|
11 |
-
foreach ( wp_slimstat_db::$columns_names as $a_filter_label => $a_filter_info ) {
|
12 |
-
$filter_name_html .= "<option value='$a_filter_label'>{$a_filter_info[0]}</option>";
|
13 |
-
}
|
14 |
-
$filter_name_html .= '</select>';
|
15 |
-
|
16 |
-
$filter_operator_html = '<label for="slimstat-filter-operator">Filter operator</label><select name="o" id="slimstat-filter-operator">';
|
17 |
-
foreach ( wp_slimstat_db::$operator_names as $a_operator_label => $a_operator_name ) {
|
18 |
-
$filter_operator_html .= "<option value='$a_operator_label'>$a_operator_name</option>";
|
19 |
-
}
|
20 |
-
$filter_operator_html .= '</select>';
|
21 |
-
|
22 |
-
$filter_value_html = '<label for="slimstat-filter-value">Filter value</label><input type="text" class="text" name="v" id="slimstat-filter-value" value="" size="20">';
|
23 |
-
|
24 |
-
if ( wp_slimstat::$settings[ 'enable_sov' ] == 'on' ) {
|
25 |
-
echo $filter_value_html.$filter_operator_html . $filter_name_html;
|
26 |
-
}
|
27 |
-
else {
|
28 |
-
echo $filter_name_html.$filter_operator_html . $filter_value_html;
|
29 |
-
}
|
30 |
-
|
31 |
-
echo '<input type="submit" value="' . __( 'Apply', 'wp-slimstat' ) . '" class="button-secondary">';
|
32 |
-
|
33 |
-
$saved_filters = get_option( 'slimstat_filters', array() );
|
34 |
-
if ( !empty( $saved_filters ) ) {
|
35 |
-
echo '<a href="#" id="slimstat-load-saved-filters" class="button-secondary noslimstat" title="Saved Filters">' . __( 'Load', 'wp-slimstat' ) . '</a>';
|
36 |
-
}
|
37 |
-
?></fieldset><!-- #slimstat-filters -->
|
38 |
-
|
39 |
-
<fieldset id="slimstat-date-filters" class="wp-ui-highlight">
|
40 |
-
<a href="#" class="noslimstat"><?php
|
41 |
-
if ( !empty( wp_slimstat_db::$filters_normalized[ 'date' ][ 'hour' ] ) || !empty( wp_slimstat_db::$filters_normalized[ 'date' ][ 'interval_hours' ] ) ) {
|
42 |
-
echo gmdate( wp_slimstat::$settings[ 'date_format' ] . ' ' . wp_slimstat::$settings[ 'time_format' ], wp_slimstat_db::$filters_normalized['utime']['start']).' - ';
|
43 |
-
|
44 |
-
$end_format = ( date( 'Ymd', wp_slimstat_db::$filters_normalized[ 'utime' ][ 'start' ] ) != date( 'Ymd', wp_slimstat_db::$filters_normalized[ 'utime' ][ 'end' ] ) ) ? wp_slimstat::$settings[ 'date_format' ] . ' ' . wp_slimstat::$settings[ 'time_format' ] : wp_slimstat::$settings[ 'time_format' ];
|
45 |
-
echo gmdate( $end_format, wp_slimstat_db::$filters_normalized[ 'utime' ][ 'end' ] );
|
46 |
-
}
|
47 |
-
else {
|
48 |
-
$start_date = gmdate( wp_slimstat::$settings[ 'date_format' ], wp_slimstat_db::$filters_normalized[ 'utime' ][ 'start' ] );
|
49 |
-
$end_date = gmdate( wp_slimstat::$settings[ 'date_format' ], wp_slimstat_db::$filters_normalized[ 'utime' ][ 'end' ] );
|
50 |
-
|
51 |
-
if ( $start_date == $end_date ) {
|
52 |
-
echo ucwords( $start_date );
|
53 |
-
}
|
54 |
-
else {
|
55 |
-
echo ucwords( $start_date ) . ' – ' . ucwords( $end_date );
|
56 |
-
}
|
57 |
-
}
|
58 |
-
?></a>
|
59 |
-
<div class="dropdown">
|
60 |
-
<div id="slimstat-quick-filters">
|
61 |
-
<a class="slimstat-filter-link noslimstat" href="<?php echo wp_slimstat_reports::fs_url( 'strtotime equals today&&&interval equals -1' ) ?>"><?php _e( 'Today', 'wp-slimstat' ) ?></a>
|
62 |
-
<a class="slimstat-filter-link noslimstat" href="<?php echo wp_slimstat_reports::fs_url( 'strtotime equals yesterday&&&interval equals -1' ) ?>"><?php _e( 'Yesterday', 'wp-slimstat' ) ?></a>
|
63 |
-
<a class="slimstat-filter-link noslimstat" href="<?php echo wp_slimstat_reports::fs_url( 'strtotime equals today&&&interval equals -7' ) ?>"><?php _e( 'Last 7 Days', 'wp-slimstat' ) ?></a>
|
64 |
-
<a class="slimstat-filter-link noslimstat" href="<?php echo wp_slimstat_reports::fs_url( 'strtotime equals today&&&interval equals -30' ) ?>"><?php _e( 'Last 30 Days', 'wp-slimstat' ) ?></a>
|
65 |
-
<a class="slimstat-filter-link noslimstat" href="<?php echo wp_slimstat_reports::fs_url( 'strtotime equals today&&&interval equals -90' ) ?>"><?php _e( 'Last 90 Days', 'wp-slimstat' ) ?></a>
|
66 |
-
<a class="slimstat-filter-link noslimstat" href="<?php echo wp_slimstat_reports::fs_url( 'strtotime equals today&&&interval equals -365' ) ?>"><?php _e( 'Last 365 Days', 'wp-slimstat' ) ?></a>
|
67 |
-
</div>
|
68 |
-
|
69 |
-
<strong><?php _e( 'Date Range', 'wp-slimstat' ) ?></strong>
|
70 |
-
|
71 |
-
<
|
72 |
-
|
73 |
-
|
74 |
-
<
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
<
|
87 |
-
|
88 |
-
|
89 |
-
<input type="
|
90 |
-
<
|
91 |
-
|
92 |
-
|
93 |
-
<
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
<
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
if (
|
136 |
-
wp_slimstat_admin::show_alert_message( sprintf( __( "
|
137 |
-
}
|
138 |
-
|
139 |
-
|
140 |
-
if (
|
141 |
-
|
142 |
-
}
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
wp_slimstat_reports::report_footer();
|
166 |
-
}
|
167 |
-
?></div>
|
168 |
-
</div>
|
169 |
<div id="slimstat-modal-dialog"></div>
|
1 |
+
<?php if ( !function_exists( 'add_action' ) ) exit(); ?>
|
2 |
+
|
3 |
+
<div class="wrap slimstat">
|
4 |
+
<h2><?php echo wp_slimstat_admin::$screens_info[ $_GET[ 'page' ] ][ 'title' ] ?></h2>
|
5 |
+
|
6 |
+
<div class="notice slimstat-notice slimstat-tooltip-content" style="background-color:#ffa;border:0;padding:10px"><?php _e( '<strong>AdBlock browser extension detected</strong> - If you see this notice, it means that your browser is not loading our stylesheet and/or Javascript files correctly. This could be caused by an overzealous ad blocker feature enabled in your browser (AdBlock Plus and friends). <a href="https://slimstat.freshdesk.com/support/solutions/articles/12000000414-the-reports-are-not-being-rendered-correctly-or-buttons-do-not-work" target="_blank">Please make sure to add an exception</a> to your configuration and allow the browser to load these assets.', 'wp-slimstat' ); ?></div>
|
7 |
+
|
8 |
+
<form action="<?php echo wp_slimstat_reports::fs_url(); ?>" method="post" id="slimstat-filters-form">
|
9 |
+
<fieldset id="slimstat-filters"><?php
|
10 |
+
$filter_name_html = '<label for="slimstat-filter-name">Filter by</label><select name="f" id="slimstat-filter-name"><option value="" disabled selected>' . __( 'Filter', 'wp-slimstat' ) . '</option>';
|
11 |
+
foreach ( wp_slimstat_db::$columns_names as $a_filter_label => $a_filter_info ) {
|
12 |
+
$filter_name_html .= "<option value='$a_filter_label'>{$a_filter_info[0]}</option>";
|
13 |
+
}
|
14 |
+
$filter_name_html .= '</select>';
|
15 |
+
|
16 |
+
$filter_operator_html = '<label for="slimstat-filter-operator">Filter operator</label><select name="o" id="slimstat-filter-operator">';
|
17 |
+
foreach ( wp_slimstat_db::$operator_names as $a_operator_label => $a_operator_name ) {
|
18 |
+
$filter_operator_html .= "<option value='$a_operator_label'>$a_operator_name</option>";
|
19 |
+
}
|
20 |
+
$filter_operator_html .= '</select>';
|
21 |
+
|
22 |
+
$filter_value_html = '<label for="slimstat-filter-value">Filter value</label><input type="text" class="text" name="v" id="slimstat-filter-value" value="" size="20">';
|
23 |
+
|
24 |
+
if ( wp_slimstat::$settings[ 'enable_sov' ] == 'on' ) {
|
25 |
+
echo $filter_value_html.$filter_operator_html . $filter_name_html;
|
26 |
+
}
|
27 |
+
else {
|
28 |
+
echo $filter_name_html.$filter_operator_html . $filter_value_html;
|
29 |
+
}
|
30 |
+
|
31 |
+
echo '<input type="submit" value="' . __( 'Apply', 'wp-slimstat' ) . '" class="button-secondary">';
|
32 |
+
|
33 |
+
$saved_filters = get_option( 'slimstat_filters', array() );
|
34 |
+
if ( !empty( $saved_filters ) ) {
|
35 |
+
echo '<a href="#" id="slimstat-load-saved-filters" class="button-secondary noslimstat" title="Saved Filters">' . __( 'Load', 'wp-slimstat' ) . '</a>';
|
36 |
+
}
|
37 |
+
?></fieldset><!-- #slimstat-filters -->
|
38 |
+
|
39 |
+
<fieldset id="slimstat-date-filters" class="wp-ui-highlight">
|
40 |
+
<a href="#" class="noslimstat"><?php
|
41 |
+
if ( !empty( wp_slimstat_db::$filters_normalized[ 'date' ][ 'hour' ] ) || !empty( wp_slimstat_db::$filters_normalized[ 'date' ][ 'interval_hours' ] ) ) {
|
42 |
+
echo gmdate( wp_slimstat::$settings[ 'date_format' ] . ' ' . wp_slimstat::$settings[ 'time_format' ], wp_slimstat_db::$filters_normalized['utime']['start']).' - ';
|
43 |
+
|
44 |
+
$end_format = ( date( 'Ymd', wp_slimstat_db::$filters_normalized[ 'utime' ][ 'start' ] ) != date( 'Ymd', wp_slimstat_db::$filters_normalized[ 'utime' ][ 'end' ] ) ) ? wp_slimstat::$settings[ 'date_format' ] . ' ' . wp_slimstat::$settings[ 'time_format' ] : wp_slimstat::$settings[ 'time_format' ];
|
45 |
+
echo gmdate( $end_format, wp_slimstat_db::$filters_normalized[ 'utime' ][ 'end' ] );
|
46 |
+
}
|
47 |
+
else {
|
48 |
+
$start_date = gmdate( wp_slimstat::$settings[ 'date_format' ], wp_slimstat_db::$filters_normalized[ 'utime' ][ 'start' ] );
|
49 |
+
$end_date = gmdate( wp_slimstat::$settings[ 'date_format' ], wp_slimstat_db::$filters_normalized[ 'utime' ][ 'end' ] );
|
50 |
+
|
51 |
+
if ( $start_date == $end_date ) {
|
52 |
+
echo ucwords( $start_date );
|
53 |
+
}
|
54 |
+
else {
|
55 |
+
echo ucwords( $start_date ) . ' – ' . ucwords( $end_date );
|
56 |
+
}
|
57 |
+
}
|
58 |
+
?></a>
|
59 |
+
<div class="dropdown">
|
60 |
+
<div id="slimstat-quick-filters">
|
61 |
+
<a class="slimstat-filter-link noslimstat" href="<?php echo wp_slimstat_reports::fs_url( 'strtotime equals today&&&interval equals -1' ) ?>"><?php _e( 'Today', 'wp-slimstat' ) ?></a>
|
62 |
+
<a class="slimstat-filter-link noslimstat" href="<?php echo wp_slimstat_reports::fs_url( 'strtotime equals yesterday&&&interval equals -1' ) ?>"><?php _e( 'Yesterday', 'wp-slimstat' ) ?></a>
|
63 |
+
<a class="slimstat-filter-link noslimstat" href="<?php echo wp_slimstat_reports::fs_url( 'strtotime equals today&&&interval equals -7' ) ?>"><?php _e( 'Last 7 Days', 'wp-slimstat' ) ?></a>
|
64 |
+
<a class="slimstat-filter-link noslimstat" href="<?php echo wp_slimstat_reports::fs_url( 'strtotime equals today&&&interval equals -30' ) ?>"><?php _e( 'Last 30 Days', 'wp-slimstat' ) ?></a>
|
65 |
+
<a class="slimstat-filter-link noslimstat" href="<?php echo wp_slimstat_reports::fs_url( 'strtotime equals today&&&interval equals -90' ) ?>"><?php _e( 'Last 90 Days', 'wp-slimstat' ) ?></a>
|
66 |
+
<a class="slimstat-filter-link noslimstat" href="<?php echo wp_slimstat_reports::fs_url( 'strtotime equals today&&&interval equals -365' ) ?>"><?php _e( 'Last 365 Days', 'wp-slimstat' ) ?></a>
|
67 |
+
</div>
|
68 |
+
|
69 |
+
<strong><?php _e( 'Date Range', 'wp-slimstat' ) ?></strong>
|
70 |
+
|
71 |
+
<label for="slimstat-filter-hour">Hour</label>
|
72 |
+
<input type="text" name="hour" id="slimstat-filter-hour" placeholder="<?php _e('Hour','wp-slimstat') ?>" class="short" value="">
|
73 |
+
|
74 |
+
<label for="slimstat-filter-day">Day</label>
|
75 |
+
<input type="text" name="day" id="slimstat-filter-day" placeholder="<?php _e( 'Day', 'wp-slimstat' ) ?>" class="short" value="">
|
76 |
+
|
77 |
+
<label for="slimstat-filter-month">Month</label>
|
78 |
+
<select name="month" id="slimstat-filter-month">
|
79 |
+
<option value=""><?php _e( 'Month', 'wp-slimstat' ) ?></option><?php
|
80 |
+
for ( $i = 1; $i <= 12; $i++ ) {
|
81 |
+
echo "<option value='$i'>" . $GLOBALS[ 'wp_locale' ]->get_month( $i ) . "</option>";
|
82 |
+
}
|
83 |
+
?>
|
84 |
+
</select>
|
85 |
+
|
86 |
+
<label for="slimstat-filter-year">Year</label>
|
87 |
+
<input type="text" name="year" id="slimstat-filter-year" placeholder="<?php _e('Year','wp-slimstat') ?>" class="short" value="">
|
88 |
+
|
89 |
+
<input type="hidden" class="slimstat-filter-date" name="slimstat-filter-date" value=""/>
|
90 |
+
<br/>
|
91 |
+
|
92 |
+
<label for="slimstat-filter-interval">Days in interval</label>
|
93 |
+
<input type="text" name="interval" id="slimstat-filter-interval" placeholder="<?php _e('± days', 'wp-slimstat') ?>" class="short" value="" title="<?php _e( 'To define an interval, enter the number of days (negative to go back in time).', 'wp-slimstat' ) ?>">
|
94 |
+
|
95 |
+
<label for="slimstat-filter-interval_hours">Hours in interval</label>
|
96 |
+
<input type="text" name="interval_hours" id="slimstat-filter-interval_hours" placeholder="<?php _e('± hours', 'wp-slimstat') ?>" class="short" value="">
|
97 |
+
|
98 |
+
<input type="submit" value="<?php _e( 'Apply', 'wp-slimstat' ) ?>" class="button button-primary noslimstat right">
|
99 |
+
|
100 |
+
<?php
|
101 |
+
wp_slimstat::toggle_date_i18n_filters( false );
|
102 |
+
|
103 |
+
if ( wp_slimstat_db::$filters_normalized[ 'date' ][ 'day' ] != intval( date_i18n( 'j' ) ) ||
|
104 |
+
wp_slimstat_db::$filters_normalized[ 'date' ][ 'month' ] != intval( date_i18n( 'n' ) ) ||
|
105 |
+
wp_slimstat_db::$filters_normalized[ 'date' ][ 'year' ] != intval( date_i18n( 'Y' ) ) ||
|
106 |
+
( wp_slimstat_db::$filters_normalized[ 'date' ][ 'interval' ] != - abs( wp_slimstat::$settings[ 'posts_column_day_interval' ] ) && wp_slimstat_db::$filters_normalized[ 'date' ][ 'interval' ] != - intval( date_i18n( 'j' ) ) + 1 ) ) {
|
107 |
+
echo '<a class="slimstat-filter-link button button-secondary noslimstat" data-reset-filters="true" href="' . wp_slimstat_reports::fs_url() . '">' . __( 'Reset Filters', 'wp-slimstat' ) . '</a>';
|
108 |
+
}
|
109 |
+
?>
|
110 |
+
</div>
|
111 |
+
</fieldset><!-- .slimstat-date-filters -->
|
112 |
+
|
113 |
+
<?php foreach( wp_slimstat_db::$filters_normalized[ 'columns' ] as $a_key => $a_details ): ?>
|
114 |
+
<input type="hidden" name="fs[<?php echo $a_key ?>]" class="slimstat-post-filter" value="<?php echo htmlspecialchars($a_details[0].' '.$a_details[1]) ?>"/>
|
115 |
+
<?php endforeach ?>
|
116 |
+
|
117 |
+
<?php foreach ( wp_slimstat_db::$filters_normalized[ 'date' ] as $a_key => $a_value ) : if ( !empty( $a_value ) ): ?>
|
118 |
+
<input type="hidden" name="fs[<?php echo $a_key ?>]" class="slimstat-post-filter" value="equals <?php echo htmlspecialchars( $a_value ) ?>"/>
|
119 |
+
<?php endif; endforeach; ?>
|
120 |
+
|
121 |
+
<?php foreach( wp_slimstat_db::$filters_normalized[ 'misc' ] as $a_key => $a_value ): if ( !empty( $a_value ) ): ?>
|
122 |
+
<input type="hidden" name="fs[<?php echo $a_key ?>]" class="slimstat-post-filter" value="equals <?php echo htmlspecialchars( $a_value ) ?>"/>
|
123 |
+
<?php endif; endforeach; ?>
|
124 |
+
</form>
|
125 |
+
<?php
|
126 |
+
if ( !file_exists( wp_slimstat::$maxmind_path ) && ( empty( wp_slimstat::$settings[ 'no_maxmind_warning' ] ) || wp_slimstat::$settings[ 'no_maxmind_warning' ] != 'on' ) ) {
|
127 |
+
wp_slimstat_admin::show_alert_message( sprintf( __( "<a href='%s' class='noslimstat'>Install MaxMind's GeoLite DB</a> to determine your visitors' country of origin.", 'wp-slimstat' ), self::$config_url . '6#wp-slimstat-external-data-files' ) . '<a id="slimstat-hide-geolite-notice" class="slimstat-font-cancel slimstat-float-right noslimstat" title="Hide this notice" href="#"></a>', 'wp-ui-text-notification below-h2' );
|
128 |
+
}
|
129 |
+
|
130 |
+
if ( !file_exists( slim_browser::$browscap_autoload_path ) && ( empty( wp_slimstat::$settings[ 'no_browscap_warning' ] ) || wp_slimstat::$settings[ 'no_browscap_warning' ] != 'on' ) ) {
|
131 |
+
wp_slimstat_admin::show_alert_message( sprintf( __( "Install the Browscap <a href='%s' class='noslimstat'>User Agent Database</a> to accurately determine your visitors' browser and operating system.", 'wp-slimstat' ), self::$config_url . '6#wp-slimstat-external-data-files' ) . '<a id="slimstat-hide-browscap-notice" class="slimstat-font-cancel slimstat-float-right noslimstat" title="Hide this notice" href="#"></a>', 'wp-ui-text-notification below-h2' );
|
132 |
+
}
|
133 |
+
|
134 |
+
// Path to wp-content folder, used to detect caching plugins via advanced-cache.php
|
135 |
+
if ( file_exists( dirname( dirname( dirname( dirname( plugin_dir_path( __FILE__ ) ) ) ) ) . '/advanced-cache.php' ) && ( empty( wp_slimstat::$settings[ 'no_caching_warning' ] ) || wp_slimstat::$settings[ 'no_caching_warning' ] != 'on' ) && ( empty( wp_slimstat::$settings[ 'javascript_mode' ] ) || wp_slimstat::$settings[ 'javascript_mode' ] != 'on' ) ) {
|
136 |
+
wp_slimstat_admin::show_alert_message( sprintf( __( "A caching plugin might be enabled on your website. Please <a href='%s' target='_blank' class='noslimstat'>make sure to configure</a> Slimstat Analytics accordingly, to get accurate information.", 'wp-slimstat' ), 'https://slimstat.freshdesk.com/support/solutions/articles/5000528524-i-am-using-w3-total-cache-or-wp-super-cache-hypercache-etc-and-it-looks-like-slimstat-is-not-tra' ) . '<a id="slimstat-hide-caching-notice" class="slimstat-font-cancel slimstat-float-right" title="Hide this notice" href="#"></a>', 'wp-ui-text-notification below-h2' );
|
137 |
+
}
|
138 |
+
|
139 |
+
$filters_html = wp_slimstat_reports::get_filters_html( wp_slimstat_db::$filters_normalized[ 'columns' ] );
|
140 |
+
if ( !empty( $filters_html ) ) {
|
141 |
+
echo "<div id='slimstat-current-filters'>$filters_html</div>";
|
142 |
+
}
|
143 |
+
?>
|
144 |
+
|
145 |
+
<div class="meta-box-sortables">
|
146 |
+
<form method="get" action=""><input type="hidden" id="meta-box-order-nonce" name="meta-box-order-nonce" value="<?php echo wp_create_nonce('meta-box-order') ?>" /></form><?php
|
147 |
+
|
148 |
+
foreach( wp_slimstat_reports::$reports_info as $a_report_id => $a_report_info ) {
|
149 |
+
if ( !is_array( $a_report_info[ 'classes' ] ) ) {
|
150 |
+
continue;
|
151 |
+
}
|
152 |
+
|
153 |
+
wp_slimstat_reports::report_header( $a_report_id );
|
154 |
+
|
155 |
+
// Third party reports can add their own methods via the callback parameter
|
156 |
+
if ( !in_array( 'hidden', $a_report_info[ 'classes' ] ) ) {
|
157 |
+
wp_slimstat_reports::callback_wrapper( array( 'id' => $a_report_id ) );
|
158 |
+
}
|
159 |
+
|
160 |
+
wp_slimstat_reports::report_footer();
|
161 |
+
}
|
162 |
+
?></div>
|
163 |
+
</div>
|
|
|
|
|
|
|
|
|
|
|
164 |
<div id="slimstat-modal-dialog"></div>
|
admin/view/right-now.php
CHANGED
@@ -1,297 +1,297 @@
|
|
1 |
-
<?php
|
2 |
-
// Avoid direct access to this piece of code
|
3 |
-
if ( !function_exists( 'add_action' ) ) {
|
4 |
-
exit(0);
|
5 |
-
}
|
6 |
-
|
7 |
-
if ( wp_slimstat::$settings[ 'async_load' ] == 'on' && ( !defined( 'DOING_AJAX' ) || !DOING_AJAX ) ) {
|
8 |
-
return '';
|
9 |
-
}
|
10 |
-
|
11 |
-
$is_dashboard = empty( $_REQUEST[ 'page' ] ) || $_REQUEST[ 'page' ] != 'slimview1';
|
12 |
-
|
13 |
-
// Available icons
|
14 |
-
$supported_browser_icons = array('Android','Anonymouse','Baiduspider','BlackBerry','BingBot','CFNetwork','Chrome','Chromium','Default Browser','Edge','Exabot/BiggerBetter','FacebookExternalHit','FeedBurner','Feedfetcher-Google','Firefox','Internet Archive','Googlebot','Google Bot','Google Feedfetcher','Google Web Preview','IE','IEMobile','iPad','iPhone','iPod Touch','Maxthon','Mediapartners-Google','Microsoft-WebDAV','msnbot','Mozilla','NewsGatorOnline','Netscape','Nokia','Opera','Opera Mini','Opera Mobi','Pingdom','Python','PycURL','Safari','W3C_Validator','WordPress','Yahoo! Slurp','YandexBot');
|
15 |
-
$supported_os_icons = array('android','blackberry os','cellos','chromeos','ios','iphone osx','java','linux','macosx','rim os','symbianos','win7','win8','win8.1','win10','winphone7','winphone7.5','winphone8','winphone8.1','winvista','winxp','unknown');
|
16 |
-
$supported_browser_types = array(__('Human','wp-slimstat'),__('Bot/Crawler','wp-slimstat'),__('Mobile Device','wp-slimstat'),__('Syndication Reader','wp-slimstat'));
|
17 |
-
|
18 |
-
$plugin_url = plugins_url('', dirname(__FILE__));
|
19 |
-
|
20 |
-
// Get the data
|
21 |
-
wp_slimstat_db::$debug_message = '';
|
22 |
-
$all_results = wp_slimstat_db::get_recent( wp_slimstat_reports::$reports_info[ 'slim_p7_02' ][ 'callback_args' ] );
|
23 |
-
$results = array_slice(
|
24 |
-
$all_results,
|
25 |
-
wp_slimstat_db::$filters_normalized[ 'misc' ][ 'start_from' ],
|
26 |
-
wp_slimstat::$settings[ 'number_results_raw_data' ]
|
27 |
-
);
|
28 |
-
|
29 |
-
$count_all_results = count( $all_results );
|
30 |
-
$count_page_results = count( $results );
|
31 |
-
|
32 |
-
// Echo the debug message
|
33 |
-
echo wp_slimstat_db::$debug_message;
|
34 |
-
|
35 |
-
// Return the results if we are not echoing them (export, email, etc)
|
36 |
-
if ( isset( $_args[ 'echo' ] ) && $_args[ 'echo' ] === false ) {
|
37 |
-
|
38 |
-
// Massage the data before returning it
|
39 |
-
if ( wp_slimstat::$settings[ 'convert_ip_addresses' ] == 'on' ) {
|
40 |
-
for ( $i = 0; $i < $count_page_results; $i++ ) {
|
41 |
-
$gethostbyaddr = gethostbyaddr( $results[ $i ][ 'ip' ] );
|
42 |
-
if ( $gethostbyaddr != $host_by_ip && !empty( $gethostbyaddr ) ) {
|
43 |
-
$results[ $i ][ 'ip' ] .= ', ' . $gethostbyaddr;
|
44 |
-
}
|
45 |
-
}
|
46 |
-
}
|
47 |
-
|
48 |
-
return $results;
|
49 |
-
}
|
50 |
-
|
51 |
-
if ($count_page_results == 0){
|
52 |
-
echo '<p class="nodata">'.__('No data to display','wp-slimstat').'</p>';
|
53 |
-
}
|
54 |
-
else {
|
55 |
-
|
56 |
-
// Pagination
|
57 |
-
echo wp_slimstat_reports::report_pagination( $count_page_results, $count_all_results, true, wp_slimstat::$settings[ 'number_results_raw_data' ] );
|
58 |
-
|
59 |
-
// Show delete button? (only those who can access the settings can see it)
|
60 |
-
$current_user_can_delete = ( current_user_can( wp_slimstat::$settings[ 'capability_can_admin' ] ) && !is_network_admin() );
|
61 |
-
$delete_row = '';
|
62 |
-
|
63 |
-
// Loop through the results
|
64 |
-
for ( $i=0; $i < $count_page_results; $i++ ) {
|
65 |
-
$host_by_ip = $results[ $i ][ 'ip' ];
|
66 |
-
if ( wp_slimstat::$settings[ 'convert_ip_addresses' ] == 'on' ) {
|
67 |
-
$gethostbyaddr = gethostbyaddr( $results[ $i ][ 'ip' ] );
|
68 |
-
if ( $gethostbyaddr != $host_by_ip && !empty( $gethostbyaddr ) ) {
|
69 |
-
$host_by_ip .= ', ' . $gethostbyaddr;
|
70 |
-
}
|
71 |
-
}
|
72 |
-
|
73 |
-
$date_time = "<i class='spaced slimstat-font-clock' title='".__( 'Date and Time', 'wp-slimstat' )."'></i> " . date_i18n( wp_slimstat::$settings[ 'date_format' ] . ' ' . wp_slimstat::$settings[ 'time_format' ], $results[ $i ][ 'dt' ], true );
|
74 |
-
|
75 |
-
// Print visit header?
|
76 |
-
if ( $i == 0 || $results[ $i - 1 ][ 'visit_id' ] != $results[ $i ][ 'visit_id' ] || $results[ $i - 1 ][ 'ip' ] != $results[ $i ][ 'ip' ] || $results[ $i - 1 ][ 'browser' ] != $results[ $i ][ 'browser' ] || $results[ $i - 1 ][ 'platform' ] != $results[ $i ][ 'platform' ] || $results[ $i - 1 ][ 'username' ] != $results[ $i ][ 'username' ] ) {
|
77 |
-
|
78 |
-
// Color-coded headers
|
79 |
-
$highlight_row = !empty($results[$i]['searchterms'])?' is-search-engine':(($results[$i]['browser_type'] != 1)?' is-direct':'');
|
80 |
-
|
81 |
-
// Country
|
82 |
-
$country_filtered = '';
|
83 |
-
if ( !empty( $results[ $i ][ 'country' ] ) && $results[ $i ][ 'country' ] != 'xx' ) {
|
84 |
-
$country_filtered = "<a class='slimstat-filter-link inline-icon' href='" . wp_slimstat_reports::fs_url( 'country equals ' . $results[ $i ][ 'country' ] ) . "'><img class='slimstat-tooltip-trigger' src='$plugin_url/images/flags/{$results[$i]['country']}.png' width='16' height='16' title='" . __( 'c-' . $results[ $i ][ 'country' ], 'wp-slimstat' ) . "'></a>";
|
85 |
-
}
|
86 |
-
|
87 |
-
// City, if tracked
|
88 |
-
$city_filtered = '';
|
89 |
-
if ( !empty( $results[ $i ][ 'city' ] ) ) {
|
90 |
-
$city_filtered = "<a class='slimstat-filter-link' href='" . wp_slimstat_reports::fs_url( 'city equals ' . $results[ $i ][ 'city' ] ) . "'>{$results[ $i ][ 'city' ]}</a>";
|
91 |
-
}
|
92 |
-
|
93 |
-
// Browser
|
94 |
-
if ($results[$i]['browser_version'] == 0) $results[$i]['browser_version'] = '';
|
95 |
-
$browser_title = ( wp_slimstat::$settings[ 'show_complete_user_agent_tooltip' ] != 'on' ) ? "{$results[ $i ][ 'browser' ]} {$results[ $i ][ 'browser_version' ]}" : $results[ $i ][ 'user_agent' ];
|
96 |
-
$browser_icon = $plugin_url.'/images/browsers/other-browsers-and-os.png';
|
97 |
-
if (in_array($results[$i]['browser'], $supported_browser_icons)){
|
98 |
-
$browser_icon = $plugin_url.'/images/browsers/'.sanitize_title($results[$i]['browser']).'.png';
|
99 |
-
}
|
100 |
-
$browser_filtered = "<a class='slimstat-filter-link inline-icon' href='".wp_slimstat_reports::fs_url('browser equals '.$results[$i]['browser'])."'><img class='slimstat-tooltip-trigger' src='$browser_icon' width='16' height='16' title='{$browser_title}'></a>";
|
101 |
-
|
102 |
-
// Platform
|
103 |
-
$platform_icon = $plugin_url.'/images/browsers/other-browsers-and-os.png';
|
104 |
-
if (in_array(strtolower($results[$i]['platform']), $supported_os_icons)){
|
105 |
-
$platform_icon = $plugin_url.'/images/platforms/'.sanitize_title($results[$i]['platform']).'.png';
|
106 |
-
}
|
107 |
-
$platform_filtered = "<a class='slimstat-filter-link inline-icon' href='".wp_slimstat_reports::fs_url('platform equals '.$results[$i]['platform'])."'><img class='slimstat-tooltip-trigger' src='$platform_icon' width='16' height='16' title='" . __( $results[ $i ][ 'platform' ], 'wp-slimstat' ) . "'></a>";
|
108 |
-
|
109 |
-
// Browser Type
|
110 |
-
$browser_type_filtered = '';
|
111 |
-
if ($results[$i]['browser_type'] != 0){
|
112 |
-
$browser_type_filtered = "<a class='slimstat-filter-link inline-icon' href='".wp_slimstat_reports::fs_url('browser_type equals '.$results[$i]['browser_type'])."'><img class='slimstat-tooltip-trigger' src='$plugin_url/images/browsers/type{$results[$i]['browser_type']}.png' width='16' height='16' title='{$supported_browser_types[$results[$i]['browser_type']]}'></a>";
|
113 |
-
}
|
114 |
-
|
115 |
-
// IP Address and user
|
116 |
-
if (empty($results[$i]['username'])){
|
117 |
-
$ip_address = "<a class='slimstat-filter-link' href='".wp_slimstat_reports::fs_url('ip equals '.$results[$i]['ip'])."'>$host_by_ip</a>";
|
118 |
-
}
|
119 |
-
else{
|
120 |
-
$display_user_name = $results[ $i ][ 'username' ];
|
121 |
-
if ( wp_slimstat::$settings[ 'show_display_name' ] == 'on' && strpos( $results[ $i ][ 'notes' ], 'user:' ) !== false ) {
|
122 |
-
$display_real_name = get_user_by('login', $results[$i]['username']);
|
123 |
-
if (is_object($display_real_name)) $display_user_name = $display_real_name->display_name;
|
124 |
-
}
|
125 |
-
$ip_address = "<a class='slimstat-filter-link' href='".wp_slimstat_reports::fs_url('username equals '.$results[$i]['username'])."'>{$display_user_name}</a>";
|
126 |
-
$ip_address .= " <a class='slimstat-filter-link' href='".wp_slimstat_reports::fs_url('ip equals '.$results[$i]['ip'])."'>($host_by_ip)</a>";
|
127 |
-
$highlight_row = (strpos( $results[$i]['notes'], 'user:') !== false)?' is-known-user':' is-known-visitor';
|
128 |
-
|
129 |
-
}
|
130 |
-
|
131 |
-
$whois_pin = '';
|
132 |
-
if ( is_admin() && !empty( wp_slimstat::$settings[ 'ip_lookup_service' ] ) && !wp_slimstat::is_local_ip_address( $results[ $i ][ 'ip' ] ) ) {
|
133 |
-
$whois_pin = "<a class='slimstat-font-location-1 whois' href='" . wp_slimstat::$settings[ 'ip_lookup_service' ] . "{$results[ $i ][ 'ip' ]}' target='_blank' title='WHOIS: {$results[ $i ][ 'ip' ]}'></a>";
|
134 |
-
}
|
135 |
-
|
136 |
-
// Originating IP Address
|
137 |
-
$other_ip_address = intval( $results[ $i ][ 'other_ip' ] );
|
138 |
-
if ( !empty( $other_ip_address ) ) {
|
139 |
-
$other_ip_address = "<a class='slimstat-filter-link' href='" . wp_slimstat_reports::fs_url( 'other_ip equals '. $results[ $i ][ 'other_ip' ] ) . "'>(" . __( 'Originating IP', 'wp-slimstat' ) . ": {$results[$i]['other_ip']})</a>";
|
140 |
-
}
|
141 |
-
else {
|
142 |
-
$other_ip_address = '';
|
143 |
-
}
|
144 |
-
|
145 |
-
// Plugins
|
146 |
-
$plugins = '';
|
147 |
-
if (!empty($results[$i]['plugins'])){
|
148 |
-
$results[$i]['plugins'] = explode(',', $results[$i]['plugins']);
|
149 |
-
foreach($results[$i]['plugins'] as $a_plugin){
|
150 |
-
$a_plugin = trim($a_plugin);
|
151 |
-
$plugins .= "<a class='slimstat-filter-link inline-icon' href='" . wp_slimstat_reports::fs_url( 'plugins contains ' . $a_plugin ) . "'><img class='slimstat-tooltip-trigger' src='$plugin_url/images/plugins/$a_plugin.png' width='16' height='16' title='" . __( $a_plugin, 'wp-slimstat' ) . "'></a> ";
|
152 |
-
}
|
153 |
-
}
|
154 |
-
|
155 |
-
// Screen Resolution
|
156 |
-
$screen_resolution = '';
|
157 |
-
if ( !empty( $results[ $i ][ 'screen_width' ] ) && !empty( $results[ $i ][ 'screen_height' ] ) ) {
|
158 |
-
$screen_resolution = "<span class='pageview-screenres'>{$results[ $i ][ 'screen_width' ]}x{$results[ $i ][ 'screen_height' ]}</span>";
|
159 |
-
}
|
160 |
-
|
161 |
-
$row_output = "<p class='header$highlight_row'>$browser_filtered $platform_filtered $browser_type_filtered $country_filtered $whois_pin $city_filtered $ip_address $other_ip_address <span class='plugins'>$plugins</span> $screen_resolution</p>";
|
162 |
-
|
163 |
-
// Strip all the filter links, if this information is shown on the frontend
|
164 |
-
if ( !is_admin() ) {
|
165 |
-
$row_output = preg_replace('/<a (.*?)>(.*?)<\/a>/', "\\2", $row_output);
|
166 |
-
}
|
167 |
-
|
168 |
-
echo $row_output;
|
169 |
-
}
|
170 |
-
|
171 |
-
// Permalink: find post title, if available
|
172 |
-
$parse_url = parse_url(get_site_url(empty($results[$i]['blog_id'])?1:$results[$i]['blog_id']));
|
173 |
-
$base_host = $parse_url['host'];
|
174 |
-
$base_url = '';
|
175 |
-
|
176 |
-
if ( !empty( $results[ $i ][ 'resource' ] ) ) {
|
177 |
-
if (!empty($results[$i]['blog_id'])){
|
178 |
-
$base_url = $parse_url['scheme'].'://'.$base_host;
|
179 |
-
}
|
180 |
-
$results[$i]['resource'] = "<a class='slimstat-font-logout' target='_blank' title='".htmlentities(__('Open this URL in a new window','wp-slimstat'), ENT_QUOTES, 'UTF-8')."' href='".$base_url.htmlentities($results[$i]['resource'], ENT_QUOTES, 'UTF-8')."'></a> $base_url<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>';
|
181 |
-
}
|
182 |
-
else {
|
183 |
-
if ( !empty( $results[$i][ 'notes' ] ) ) {
|
184 |
-
$exploded_notes = explode( ';', $results[$i][ 'notes' ] );
|
185 |
-
foreach ( $exploded_notes as $a_note ) {
|
186 |
-
if ( strpos( $a_note, 'results:') !== false ) {
|
187 |
-
$search_terms_info = $results[ $i ][ 'searchterms' ] . ' (' . $a_note . ')';
|
188 |
-
break;
|
189 |
-
}
|
190 |
-
}
|
191 |
-
}
|
192 |
-
$results[$i]['resource'] = __('Local search results page','wp-slimstat');
|
193 |
-
}
|
194 |
-
|
195 |
-
if ( empty( $search_terms_info ) ) {
|
196 |
-
$search_terms_info = wp_slimstat_reports::get_search_terms_info( $results[ $i ][ 'searchterms' ], $results[ $i ][ 'referer' ] );
|
197 |
-
}
|
198 |
-
|
199 |
-
// Search Terms, with link to original SERP, and Outbound Resource
|
200 |
-
if ( !empty( $search_terms_info ) ) {
|
201 |
-
$results[$i]['searchterms'] = "<i class='spaced slimstat-font-search' title='" . __( 'Search Terms', 'wp-slimstat' ) . "'></i> $search_terms_info";
|
202 |
-
}
|
203 |
-
else {
|
204 |
-
$results[$i]['searchterms'] = '';
|
205 |
-
}
|
206 |
-
|
207 |
-
// Let's reset this variable for the next item
|
208 |
-
$search_terms_info = '';
|
209 |
-
|
210 |
-
// Server Latency and Page Speed
|
211 |
-
$performance = '';
|
212 |
-
if ( !$is_dashboard && ( !empty( $results[ $i ][ 'server_latency' ] ) || !empty( $results[ $i ][ 'page_performance' ] ) ) ) {
|
213 |
-
$performance = "<i class='slimstat-font-gauge spaced' title='".__('Server Latency and Page Speed in milliseconds','wp-slimstat')."'></i> ".__('SL','wp-slimstat').": {$results[$i]['server_latency']} / ".__('PS','wp-slimstat').": {$results[$i]['page_performance']}";
|
214 |
-
}
|
215 |
-
|
216 |
-
// Time on page
|
217 |
-
$time_on_page = '';
|
218 |
-
if ( !$is_dashboard && !empty( $results[ $i ][ 'dt_out' ] ) ) {
|
219 |
-
$duration = $results[ $i ][ 'dt_out' ] - $results[ $i ][ 'dt' ];
|
220 |
-
$time_on_page = "<i class='slimstat-font-stopwatch spaced' title='" . __( 'Time spent on this page', 'wp-slimstat' ) . "'></i> " . date( ( $duration > 3599 ? 'H:i:s' : 'i:s' ), $duration );
|
221 |
-
}
|
222 |
-
|
223 |
-
// Pageview Notes
|
224 |
-
$notes = '';
|
225 |
-
if ( is_admin() && !empty( $results[ $i ][ 'notes' ] ) ) {
|
226 |
-
$notes = str_replace(array(';', ':'), array('<br/>', ': '), $results[$i]['notes']);
|
227 |
-
$notes = "<i class='slimstat-font-edit slimstat-tooltip-trigger'><b class='slimstat-tooltip-content'>{$notes}</b></i>";
|
228 |
-
}
|
229 |
-
|
230 |
-
// Avoid XSS attacks through the referer URL
|
231 |
-
$results[ $i ] [ 'referer' ] = str_replace( array( '<', '>', '%22', '%27', '\'', '"', '%3C', '%3E' ), array( '<', '>', '', '', '', '', '<', '>' ), urldecode( $results[ $i ] [ 'referer' ] ) );
|
232 |
-
|
233 |
-
$login_logout = '';
|
234 |
-
if ( !$is_dashboard ) {
|
235 |
-
$domain = parse_url( $results[ $i ] [ 'referer' ] );
|
236 |
-
$domain = !empty( $domain[ 'host' ] ) ? $domain[ 'host' ] : __( 'Invalid Referrer', 'wp-slimstat' );
|
237 |
-
$results[$i][ 'referer' ] = (!empty($results[$i]['referer']) && empty($results[$i]['searchterms']))?"<a class='spaced slimstat-font-login' target='_blank' title='".htmlentities(__('Open this referrer in a new window','wp-slimstat'), ENT_QUOTES, 'UTF-8')."' href='{$results[$i]['referer']}'></a> $domain":'';
|
238 |
-
$results[$i][ 'content_type' ] = !empty($results[$i]['content_type'])?"<i class='spaced slimstat-font-doc' title='".__('Content Type','wp-slimstat')."'></i> <a class='slimstat-filter-link' href='".wp_slimstat_reports::fs_url('content_type equals '.$results[$i]['content_type'])."'>{$results[$i]['content_type']}</a> ":'';
|
239 |
-
|
240 |
-
// The Outbound Links field might contain more than one link
|
241 |
-
if ( !empty( $results[ $i ][ 'outbound_resource' ] ) ) {
|
242 |
-
$exploded_outbound_resources = explode( ';;;', $results[ $i ][ 'outbound_resource' ] );
|
243 |
-
$results[$i][ 'outbound_resource' ] = '';
|
244 |
-
foreach ( $exploded_outbound_resources as $a_resource ) {
|
245 |
-
$results[ $i ][ 'outbound_resource' ] .= "<a class='inline-icon spaced slimstat-font-logout' target='_blank' title='".htmlentities( __( 'Open this outbound link in a new window', 'wp-slimstat' ), ENT_QUOTES, 'UTF-8' ) . "' href='{$a_resource}'></a> {$a_resource}";
|
246 |
-
}
|
247 |
-
}
|
248 |
-
else {
|
249 |
-
$results[$i][ 'outbound_resource' ] = '';
|
250 |
-
}
|
251 |
-
|
252 |
-
if ( $current_user_can_delete ){
|
253 |
-
$delete_row = "<a class='slimstat-delete-entry slimstat-font-cancel' data-pageview-id='{$results[$i]['id']}' title='".htmlentities(__('Delete this entry from the database','wp-slimstat'), ENT_QUOTES, 'UTF-8')."' href='#'></a>";
|
254 |
-
}
|
255 |
-
|
256 |
-
// Login / Logout Event
|
257 |
-
$login_logout = '';
|
258 |
-
if ( strpos( $results[ $i ][ 'notes' ], 'loggedin:' ) !== false ) {
|
259 |
-
$exploded_notes = explode( ';', $results[ $i ][ 'notes' ] );
|
260 |
-
foreach ( $exploded_notes as $a_note ) {
|
261 |
-
if ( strpos( $a_note, 'loggedin:' ) === false ) {
|
262 |
-
continue;
|
263 |
-
}
|
264 |
-
|
265 |
-
$login_logout .= "<i class='slimstat-font-user-plus spaced' title='" . __( 'User Logged In', 'wp-slimstat' ) . "'></i> " . str_replace( 'loggedin:', '', $a_note );
|
266 |
-
}
|
267 |
-
}
|
268 |
-
if ( strpos( $results[ $i ][ 'notes' ], 'loggedout:' ) !== false ) {
|
269 |
-
$exploded_notes = explode( ';', $results[ $i ][ 'notes' ] );
|
270 |
-
foreach ( $exploded_notes as $a_note ) {
|
271 |
-
if ( strpos( $a_note, 'loggedout:' ) === false ) {
|
272 |
-
continue;
|
273 |
-
}
|
274 |
-
|
275 |
-
$login_logout .= "<i class='slimstat-font-user-times spaced' title='" . __( 'User Logged Out', 'wp-slimstat' ) . "'></i> " . str_replace( 'loggedout:', '', $a_note );
|
276 |
-
}
|
277 |
-
}
|
278 |
-
}
|
279 |
-
else {
|
280 |
-
$results[$i]['referer'] = $results[$i][ 'outbound_resource' ] = $results[$i][ 'content_type' ] = '';
|
281 |
-
}
|
282 |
-
|
283 |
-
$row_output = "<p>{$results[$i]['resource']} <span class='details'>$time_on_page $login_logout {$results[$i]['searchterms']} {$results[$i]['referer']} {$results[$i]['outbound_resource']} {$results[$i]['content_type']} $performance $date_time {$notes} {$delete_row}</span></p>";
|
284 |
-
|
285 |
-
// Strip all the filter links, if this information is shown on the frontend
|
286 |
-
if ( !is_admin() ) {
|
287 |
-
$row_output = preg_replace('/<a (.*?)>(.*?)<\/a>/', "\\2", $row_output);
|
288 |
-
}
|
289 |
-
|
290 |
-
echo $row_output;
|
291 |
-
}
|
292 |
-
|
293 |
-
// Pagination
|
294 |
-
if ( $count_page_results > 20 ) {
|
295 |
-
echo wp_slimstat_reports::report_pagination( $count_page_results, $count_all_results, true, wp_slimstat::$settings[ 'number_results_raw_data' ] );
|
296 |
-
}
|
297 |
-
}
|
1 |
+
<?php
|
2 |
+
// Avoid direct access to this piece of code
|
3 |
+
if ( !function_exists( 'add_action' ) ) {
|
4 |
+
exit(0);
|
5 |
+
}
|
6 |
+
|
7 |
+
if ( wp_slimstat::$settings[ 'async_load' ] == 'on' && ( !defined( 'DOING_AJAX' ) || !DOING_AJAX ) ) {
|
8 |
+
return '';
|
9 |
+
}
|
10 |
+
|
11 |
+
$is_dashboard = empty( $_REQUEST[ 'page' ] ) || $_REQUEST[ 'page' ] != 'slimview1';
|
12 |
+
|
13 |
+
// Available icons
|
14 |
+
$supported_browser_icons = array('Android','Anonymouse','Baiduspider','BlackBerry','BingBot','CFNetwork','Chrome','Chromium','Default Browser','Edge','Exabot/BiggerBetter','FacebookExternalHit','FeedBurner','Feedfetcher-Google','Firefox','Internet Archive','Googlebot','Google Bot','Google Feedfetcher','Google Web Preview','IE','IEMobile','iPad','iPhone','iPod Touch','Maxthon','Mediapartners-Google','Microsoft-WebDAV','msnbot','Mozilla','NewsGatorOnline','Netscape','Nokia','Opera','Opera Mini','Opera Mobi','Pingdom','Python','PycURL','Safari','W3C_Validator','WordPress','Yahoo! Slurp','YandexBot');
|
15 |
+
$supported_os_icons = array('android','blackberry os','cellos','chromeos','ios','iphone osx','java','linux','macosx','rim os','symbianos','win7','win8','win8.1','win10','winphone7','winphone7.5','winphone8','winphone8.1','winvista','winxp','unknown');
|
16 |
+
$supported_browser_types = array(__('Human','wp-slimstat'),__('Bot/Crawler','wp-slimstat'),__('Mobile Device','wp-slimstat'),__('Syndication Reader','wp-slimstat'));
|
17 |
+
|
18 |
+
$plugin_url = plugins_url('', dirname(__FILE__));
|
19 |
+
|
20 |
+
// Get the data
|
21 |
+
wp_slimstat_db::$debug_message = '';
|
22 |
+
$all_results = wp_slimstat_db::get_recent( wp_slimstat_reports::$reports_info[ 'slim_p7_02' ][ 'callback_args' ] );
|
23 |
+
$results = array_slice(
|
24 |
+
$all_results,
|
25 |
+
wp_slimstat_db::$filters_normalized[ 'misc' ][ 'start_from' ],
|
26 |
+
wp_slimstat::$settings[ 'number_results_raw_data' ]
|
27 |
+
);
|
28 |
+
|
29 |
+
$count_all_results = count( $all_results );
|
30 |
+
$count_page_results = count( $results );
|
31 |
+
|
32 |
+
// Echo the debug message
|
33 |
+
echo wp_slimstat_db::$debug_message;
|
34 |
+
|
35 |
+
// Return the results if we are not echoing them (export, email, etc)
|
36 |
+
if ( isset( $_args[ 'echo' ] ) && $_args[ 'echo' ] === false ) {
|
37 |
+
|
38 |
+
// Massage the data before returning it
|
39 |
+
if ( wp_slimstat::$settings[ 'convert_ip_addresses' ] == 'on' ) {
|
40 |
+
for ( $i = 0; $i < $count_page_results; $i++ ) {
|
41 |
+
$gethostbyaddr = gethostbyaddr( $results[ $i ][ 'ip' ] );
|
42 |
+
if ( $gethostbyaddr != $host_by_ip && !empty( $gethostbyaddr ) ) {
|
43 |
+
$results[ $i ][ 'ip' ] .= ', ' . $gethostbyaddr;
|
44 |
+
}
|
45 |
+
}
|
46 |
+
}
|
47 |
+
|
48 |
+
return $results;
|
49 |
+
}
|
50 |
+
|
51 |
+
if ($count_page_results == 0){
|
52 |
+
echo '<p class="nodata">'.__('No data to display','wp-slimstat').'</p>';
|
53 |
+
}
|
54 |
+
else {
|
55 |
+
|
56 |
+
// Pagination
|
57 |
+
echo wp_slimstat_reports::report_pagination( $count_page_results, $count_all_results, true, wp_slimstat::$settings[ 'number_results_raw_data' ] );
|
58 |
+
|
59 |
+
// Show delete button? (only those who can access the settings can see it)
|
60 |
+
$current_user_can_delete = ( current_user_can( wp_slimstat::$settings[ 'capability_can_admin' ] ) && !is_network_admin() );
|
61 |
+
$delete_row = '';
|
62 |
+
|
63 |
+
// Loop through the results
|
64 |
+
for ( $i=0; $i < $count_page_results; $i++ ) {
|
65 |
+
$host_by_ip = $results[ $i ][ 'ip' ];
|
66 |
+
if ( wp_slimstat::$settings[ 'convert_ip_addresses' ] == 'on' ) {
|
67 |
+
$gethostbyaddr = gethostbyaddr( $results[ $i ][ 'ip' ] );
|
68 |
+
if ( $gethostbyaddr != $host_by_ip && !empty( $gethostbyaddr ) ) {
|
69 |
+
$host_by_ip .= ', ' . $gethostbyaddr;
|
70 |
+
}
|
71 |
+
}
|
72 |
+
|
73 |
+
$date_time = "<i class='spaced slimstat-font-clock slimstat-tooltip-trigger' title='".__( 'Date and Time', 'wp-slimstat' )."'></i> " . date_i18n( wp_slimstat::$settings[ 'date_format' ] . ' ' . wp_slimstat::$settings[ 'time_format' ], $results[ $i ][ 'dt' ], true );
|
74 |
+
|
75 |
+
// Print visit header?
|
76 |
+
if ( $i == 0 || $results[ $i - 1 ][ 'visit_id' ] != $results[ $i ][ 'visit_id' ] || $results[ $i - 1 ][ 'ip' ] != $results[ $i ][ 'ip' ] || $results[ $i - 1 ][ 'browser' ] != $results[ $i ][ 'browser' ] || $results[ $i - 1 ][ 'platform' ] != $results[ $i ][ 'platform' ] || $results[ $i - 1 ][ 'username' ] != $results[ $i ][ 'username' ] ) {
|
77 |
+
|
78 |
+
// Color-coded headers
|
79 |
+
$highlight_row = !empty($results[$i]['searchterms'])?' is-search-engine':(($results[$i]['browser_type'] != 1)?' is-direct':'');
|
80 |
+
|
81 |
+
// Country
|
82 |
+
$country_filtered = '';
|
83 |
+
if ( !empty( $results[ $i ][ 'country' ] ) && $results[ $i ][ 'country' ] != 'xx' ) {
|
84 |
+
$country_filtered = "<a class='slimstat-filter-link inline-icon' href='" . wp_slimstat_reports::fs_url( 'country equals ' . $results[ $i ][ 'country' ] ) . "'><img class='slimstat-tooltip-trigger' src='$plugin_url/images/flags/{$results[$i]['country']}.png' width='16' height='16' title='" . __( 'c-' . $results[ $i ][ 'country' ], 'wp-slimstat' ) . "'></a>";
|
85 |
+
}
|
86 |
+
|
87 |
+
// City, if tracked
|
88 |
+
$city_filtered = '';
|
89 |
+
if ( !empty( $results[ $i ][ 'city' ] ) ) {
|
90 |
+
$city_filtered = "<a class='slimstat-filter-link' href='" . wp_slimstat_reports::fs_url( 'city equals ' . $results[ $i ][ 'city' ] ) . "'>{$results[ $i ][ 'city' ]}</a>";
|
91 |
+
}
|
92 |
+
|
93 |
+
// Browser
|
94 |
+
if ($results[$i]['browser_version'] == 0) $results[$i]['browser_version'] = '';
|
95 |
+
$browser_title = ( wp_slimstat::$settings[ 'show_complete_user_agent_tooltip' ] != 'on' ) ? "{$results[ $i ][ 'browser' ]} {$results[ $i ][ 'browser_version' ]}" : $results[ $i ][ 'user_agent' ];
|
96 |
+
$browser_icon = $plugin_url.'/images/browsers/other-browsers-and-os.png';
|
97 |
+
if (in_array($results[$i]['browser'], $supported_browser_icons)){
|
98 |
+
$browser_icon = $plugin_url.'/images/browsers/'.sanitize_title($results[$i]['browser']).'.png';
|
99 |
+
}
|
100 |
+
$browser_filtered = "<a class='slimstat-filter-link inline-icon' href='".wp_slimstat_reports::fs_url('browser equals '.$results[$i]['browser'])."'><img class='slimstat-tooltip-trigger' src='$browser_icon' width='16' height='16' title='{$browser_title}'></a>";
|
101 |
+
|
102 |
+
// Platform
|
103 |
+
$platform_icon = $plugin_url.'/images/browsers/other-browsers-and-os.png';
|
104 |
+
if (in_array(strtolower($results[$i]['platform']), $supported_os_icons)){
|
105 |
+
$platform_icon = $plugin_url.'/images/platforms/'.sanitize_title($results[$i]['platform']).'.png';
|
106 |
+
}
|
107 |
+
$platform_filtered = "<a class='slimstat-filter-link inline-icon' href='".wp_slimstat_reports::fs_url('platform equals '.$results[$i]['platform'])."'><img class='slimstat-tooltip-trigger' src='$platform_icon' width='16' height='16' title='" . __( $results[ $i ][ 'platform' ], 'wp-slimstat' ) . "'></a>";
|
108 |
+
|
109 |
+
// Browser Type
|
110 |
+
$browser_type_filtered = '';
|
111 |
+
if ($results[$i]['browser_type'] != 0){
|
112 |
+
$browser_type_filtered = "<a class='slimstat-filter-link inline-icon' href='".wp_slimstat_reports::fs_url('browser_type equals '.$results[$i]['browser_type'])."'><img class='slimstat-tooltip-trigger' src='$plugin_url/images/browsers/type{$results[$i]['browser_type']}.png' width='16' height='16' title='{$supported_browser_types[$results[$i]['browser_type']]}'></a>";
|
113 |
+
}
|
114 |
+
|
115 |
+
// IP Address and user
|
116 |
+
if (empty($results[$i]['username'])){
|
117 |
+
$ip_address = "<a class='slimstat-filter-link' href='".wp_slimstat_reports::fs_url('ip equals '.$results[$i]['ip'])."'>$host_by_ip</a>";
|
118 |
+
}
|
119 |
+
else{
|
120 |
+
$display_user_name = $results[ $i ][ 'username' ];
|
121 |
+
if ( wp_slimstat::$settings[ 'show_display_name' ] == 'on' && strpos( $results[ $i ][ 'notes' ], 'user:' ) !== false ) {
|
122 |
+
$display_real_name = get_user_by('login', $results[$i]['username']);
|
123 |
+
if (is_object($display_real_name)) $display_user_name = $display_real_name->display_name;
|
124 |
+
}
|
125 |
+
$ip_address = "<a class='slimstat-filter-link' href='".wp_slimstat_reports::fs_url('username equals '.$results[$i]['username'])."'>{$display_user_name}</a>";
|
126 |
+
$ip_address .= " <a class='slimstat-filter-link' href='".wp_slimstat_reports::fs_url('ip equals '.$results[$i]['ip'])."'>($host_by_ip)</a>";
|
127 |
+
$highlight_row = (strpos( $results[$i]['notes'], 'user:') !== false)?' is-known-user':' is-known-visitor';
|
128 |
+
|
129 |
+
}
|
130 |
+
|
131 |
+
$whois_pin = '';
|
132 |
+
if ( is_admin() && !empty( wp_slimstat::$settings[ 'ip_lookup_service' ] ) && !wp_slimstat::is_local_ip_address( $results[ $i ][ 'ip' ] ) ) {
|
133 |
+
$whois_pin = "<a class='slimstat-font-location-1 whois' href='" . wp_slimstat::$settings[ 'ip_lookup_service' ] . "{$results[ $i ][ 'ip' ]}' target='_blank' title='WHOIS: {$results[ $i ][ 'ip' ]}'></a>";
|
134 |
+
}
|
135 |
+
|
136 |
+
// Originating IP Address
|
137 |
+
$other_ip_address = intval( $results[ $i ][ 'other_ip' ] );
|
138 |
+
if ( !empty( $other_ip_address ) ) {
|
139 |
+
$other_ip_address = "<a class='slimstat-filter-link' href='" . wp_slimstat_reports::fs_url( 'other_ip equals '. $results[ $i ][ 'other_ip' ] ) . "'>(" . __( 'Originating IP', 'wp-slimstat' ) . ": {$results[$i]['other_ip']})</a>";
|
140 |
+
}
|
141 |
+
else {
|
142 |
+
$other_ip_address = '';
|
143 |
+
}
|
144 |
+
|
145 |
+
// Plugins
|
146 |
+
$plugins = '';
|
147 |
+
if (!empty($results[$i]['plugins'])){
|
148 |
+
$results[$i]['plugins'] = explode(',', $results[$i]['plugins']);
|
149 |
+
foreach($results[$i]['plugins'] as $a_plugin){
|
150 |
+
$a_plugin = trim($a_plugin);
|
151 |
+
$plugins .= "<a class='slimstat-filter-link inline-icon' href='" . wp_slimstat_reports::fs_url( 'plugins contains ' . $a_plugin ) . "'><img class='slimstat-tooltip-trigger' src='$plugin_url/images/plugins/$a_plugin.png' width='16' height='16' title='" . __( $a_plugin, 'wp-slimstat' ) . "'></a> ";
|
152 |
+
}
|
153 |
+
}
|
154 |
+
|
155 |
+
// Screen Resolution
|
156 |
+
$screen_resolution = '';
|
157 |
+
if ( !empty( $results[ $i ][ 'screen_width' ] ) && !empty( $results[ $i ][ 'screen_height' ] ) ) {
|
158 |
+
$screen_resolution = "<span class='pageview-screenres'>{$results[ $i ][ 'screen_width' ]}x{$results[ $i ][ 'screen_height' ]}</span>";
|
159 |
+
}
|
160 |
+
|
161 |
+
$row_output = "<p class='header$highlight_row'>$browser_filtered $platform_filtered $browser_type_filtered $country_filtered $whois_pin $city_filtered $ip_address $other_ip_address <span class='plugins'>$plugins</span> $screen_resolution</p>";
|
162 |
+
|
163 |
+
// Strip all the filter links, if this information is shown on the frontend
|
164 |
+
if ( !is_admin() ) {
|
165 |
+
$row_output = preg_replace('/<a (.*?)>(.*?)<\/a>/', "\\2", $row_output);
|
166 |
+
}
|
167 |
+
|
168 |
+
echo $row_output;
|
169 |
+
}
|
170 |
+
|
171 |
+
// Permalink: find post title, if available
|
172 |
+
$parse_url = parse_url(get_site_url(empty($results[$i]['blog_id'])?1:$results[$i]['blog_id']));
|
173 |
+
$base_host = $parse_url['host'];
|
174 |
+
$base_url = '';
|
175 |
+
|
176 |
+
if ( !empty( $results[ $i ][ 'resource' ] ) ) {
|
177 |
+
if (!empty($results[$i]['blog_id'])){
|
178 |
+
$base_url = $parse_url['scheme'].'://'.$base_host;
|
179 |
+
}
|
180 |
+
$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='".$base_url.htmlentities($results[$i]['resource'], ENT_QUOTES, 'UTF-8')."'></a> $base_url<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>';
|
181 |
+
}
|
182 |
+
else {
|
183 |
+
if ( !empty( $results[$i][ 'notes' ] ) ) {
|
184 |
+
$exploded_notes = explode( ';', $results[$i][ 'notes' ] );
|
185 |
+
foreach ( $exploded_notes as $a_note ) {
|
186 |
+
if ( strpos( $a_note, 'results:') !== false ) {
|
187 |
+
$search_terms_info = $results[ $i ][ 'searchterms' ] . ' (' . $a_note . ')';
|
188 |
+
break;
|
189 |
+
}
|
190 |
+
}
|
191 |
+
}
|
192 |
+
$results[$i]['resource'] = __('Local search results page','wp-slimstat');
|
193 |
+
}
|
194 |
+
|
195 |
+
if ( empty( $search_terms_info ) ) {
|
196 |
+
$search_terms_info = wp_slimstat_reports::get_search_terms_info( $results[ $i ][ 'searchterms' ], $results[ $i ][ 'referer' ] );
|
197 |
+
}
|
198 |
+
|
199 |
+
// Search Terms, with link to original SERP, and Outbound Resource
|
200 |
+
if ( !empty( $search_terms_info ) ) {
|
201 |
+
$results[$i]['searchterms'] = "<i class='spaced slimstat-font-search' title='" . __( 'Search Terms', 'wp-slimstat' ) . "'></i> $search_terms_info";
|
202 |
+
}
|
203 |
+
else {
|
204 |
+
$results[$i]['searchterms'] = '';
|
205 |
+
}
|
206 |
+
|
207 |
+
// Let's reset this variable for the next item
|
208 |
+
$search_terms_info = '';
|
209 |
+
|
210 |
+
// Server Latency and Page Speed
|
211 |
+
$performance = '';
|
212 |
+
if ( !$is_dashboard && ( !empty( $results[ $i ][ 'server_latency' ] ) || !empty( $results[ $i ][ 'page_performance' ] ) ) ) {
|
213 |
+
$performance = "<i class='slimstat-font-gauge spaced slimstat-tooltip-trigger' title='".__('Server Latency and Page Speed in milliseconds','wp-slimstat')."'></i> ".__('SL','wp-slimstat').": {$results[$i]['server_latency']} / ".__('PS','wp-slimstat').": {$results[$i]['page_performance']}";
|
214 |
+
}
|
215 |
+
|
216 |
+
// Time on page
|
217 |
+
$time_on_page = '';
|
218 |
+
if ( !$is_dashboard && !empty( $results[ $i ][ 'dt_out' ] ) ) {
|
219 |
+
$duration = $results[ $i ][ 'dt_out' ] - $results[ $i ][ 'dt' ];
|
220 |
+
$time_on_page = "<i class='slimstat-font-stopwatch spaced slimstat-tooltip-trigger' title='" . __( 'Time spent on this page', 'wp-slimstat' ) . "'></i> " . date( ( $duration > 3599 ? 'H:i:s' : 'i:s' ), $duration );
|
221 |
+
}
|
222 |
+
|
223 |
+
// Pageview Notes
|
224 |
+
$notes = '';
|
225 |
+
if ( is_admin() && !empty( $results[ $i ][ 'notes' ] ) ) {
|
226 |
+
$notes = str_replace(array(';', ':'), array('<br/>', ': '), $results[$i]['notes']);
|
227 |
+
$notes = "<i class='slimstat-font-edit slimstat-tooltip-trigger'><b class='slimstat-tooltip-content'>{$notes}</b></i>";
|
228 |
+
}
|
229 |
+
|
230 |
+
// Avoid XSS attacks through the referer URL
|
231 |
+
$results[ $i ] [ 'referer' ] = str_replace( array( '<', '>', '%22', '%27', '\'', '"', '%3C', '%3E' ), array( '<', '>', '', '', '', '', '<', '>' ), urldecode( $results[ $i ] [ 'referer' ] ) );
|
232 |
+
|
233 |
+
$login_logout = '';
|
234 |
+
if ( !$is_dashboard ) {
|
235 |
+
$domain = parse_url( $results[ $i ] [ 'referer' ] );
|
236 |
+
$domain = !empty( $domain[ 'host' ] ) ? $domain[ 'host' ] : __( 'Invalid Referrer', 'wp-slimstat' );
|
237 |
+
$results[$i][ 'referer' ] = (!empty($results[$i]['referer']) && empty($results[$i]['searchterms']))?"<a class='spaced slimstat-font-login slimstat-tooltip-trigger' target='_blank' title='".htmlentities(__('Open this referrer in a new window','wp-slimstat'), ENT_QUOTES, 'UTF-8')."' href='{$results[$i]['referer']}'></a> $domain":'';
|
238 |
+
$results[$i][ 'content_type' ] = !empty($results[$i]['content_type'])?"<i class='spaced slimstat-font-doc slimstat-tooltip-trigger' title='".__('Content Type','wp-slimstat')."'></i> <a class='slimstat-filter-link' href='".wp_slimstat_reports::fs_url('content_type equals '.$results[$i]['content_type'])."'>{$results[$i]['content_type']}</a> ":'';
|
239 |
+
|
240 |
+
// The Outbound Links field might contain more than one link
|
241 |
+
if ( !empty( $results[ $i ][ 'outbound_resource' ] ) ) {
|
242 |
+
$exploded_outbound_resources = explode( ';;;', $results[ $i ][ 'outbound_resource' ] );
|
243 |
+
$results[$i][ 'outbound_resource' ] = '';
|
244 |
+
foreach ( $exploded_outbound_resources as $a_resource ) {
|
245 |
+
$results[ $i ][ 'outbound_resource' ] .= "<a class='inline-icon spaced slimstat-font-logout slimstat-tooltip-trigger' target='_blank' title='".htmlentities( __( 'Open this outbound link in a new window', 'wp-slimstat' ), ENT_QUOTES, 'UTF-8' ) . "' href='{$a_resource}'></a> {$a_resource}";
|
246 |
+
}
|
247 |
+
}
|
248 |
+
else {
|
249 |
+
$results[$i][ 'outbound_resource' ] = '';
|
250 |
+
}
|
251 |
+
|
252 |
+
if ( $current_user_can_delete ){
|
253 |
+
$delete_row = "<a class='slimstat-delete-entry slimstat-font-cancel slimstat-tooltip-trigger' data-pageview-id='{$results[$i]['id']}' title='".htmlentities(__('Delete this entry from the database','wp-slimstat'), ENT_QUOTES, 'UTF-8')."' href='#'></a>";
|
254 |
+
}
|
255 |
+
|
256 |
+
// Login / Logout Event
|
257 |
+
$login_logout = '';
|
258 |
+
if ( strpos( $results[ $i ][ 'notes' ], 'loggedin:' ) !== false ) {
|
259 |
+
$exploded_notes = explode( ';', $results[ $i ][ 'notes' ] );
|
260 |
+
foreach ( $exploded_notes as $a_note ) {
|
261 |
+
if ( strpos( $a_note, 'loggedin:' ) === false ) {
|
262 |
+
continue;
|
263 |
+
}
|
264 |
+
|
265 |
+
$login_logout .= "<i class='slimstat-font-user-plus spaced slimstat-tooltip-trigger' title='" . __( 'User Logged In', 'wp-slimstat' ) . "'></i> " . str_replace( 'loggedin:', '', $a_note );
|
266 |
+
}
|
267 |
+
}
|
268 |
+
if ( strpos( $results[ $i ][ 'notes' ], 'loggedout:' ) !== false ) {
|
269 |
+
$exploded_notes = explode( ';', $results[ $i ][ 'notes' ] );
|
270 |
+
foreach ( $exploded_notes as $a_note ) {
|
271 |
+
if ( strpos( $a_note, 'loggedout:' ) === false ) {
|
272 |
+
continue;
|
273 |
+
}
|
274 |
+
|
275 |
+
$login_logout .= "<i class='slimstat-font-user-times spaced slimstat-tooltip-trigger' title='" . __( 'User Logged Out', 'wp-slimstat' ) . "'></i> " . str_replace( 'loggedout:', '', $a_note );
|
276 |
+
}
|
277 |
+
}
|
278 |
+
}
|
279 |
+
else {
|
280 |
+
$results[$i]['referer'] = $results[$i][ 'outbound_resource' ] = $results[$i][ 'content_type' ] = '';
|
281 |
+
}
|
282 |
+
|
283 |
+
$row_output = "<p>{$results[$i]['resource']} <span class='details'>$time_on_page $login_logout {$results[$i]['searchterms']} {$results[$i]['referer']} {$results[$i]['outbound_resource']} {$results[$i]['content_type']} $performance $date_time {$notes} {$delete_row}</span></p>";
|
284 |
+
|
285 |
+
// Strip all the filter links, if this information is shown on the frontend
|
286 |
+
if ( !is_admin() ) {
|
287 |
+
$row_output = preg_replace('/<a (.*?)>(.*?)<\/a>/', "\\2", $row_output);
|
288 |
+
}
|
289 |
+
|
290 |
+
echo $row_output;
|
291 |
+
}
|
292 |
+
|
293 |
+
// Pagination
|
294 |
+
if ( $count_page_results > 20 ) {
|
295 |
+
echo wp_slimstat_reports::report_pagination( $count_page_results, $count_all_results, true, wp_slimstat::$settings[ 'number_results_raw_data' ] );
|
296 |
+
}
|
297 |
+
}
|
admin/view/wp-slimstat-db.php
CHANGED
@@ -1,1099 +1,1007 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
// Let's define the main class with all the methods that we need
|
4 |
-
class wp_slimstat_db {
|
5 |
-
// Filters
|
6 |
-
public static $columns_names = array();
|
7 |
-
public static $operator_names = array();
|
8 |
-
public static $filters_normalized = array();
|
9 |
-
|
10 |
-
// Number and date formats
|
11 |
-
public static $formats = array( 'decimal' => ',', 'thousand' => '.' );
|
12 |
-
|
13 |
-
// Structure that maps filters to SQL information (table names, clauses, lookup tables, etc)
|
14 |
-
public static $sql_where = array( 'columns' => '', 'time_range' => '' );
|
15 |
-
|
16 |
-
// Filters that are not visible in the dropdown
|
17 |
-
public static $all_columns_names = array();
|
18 |
-
|
19 |
-
// Debug message
|
20 |
-
public static $debug_message = '';
|
21 |
-
|
22 |
-
/*
|
23 |
-
* Sets the filters and other structures needed to store the data retrieved from the DB
|
24 |
-
*/
|
25 |
-
public static function init( $_filters = '' ) {
|
26 |
-
// Decimal and thousand separators
|
27 |
-
if ( wp_slimstat::$settings[ 'use_european_separators' ] == 'no' ){
|
28 |
-
self::$formats[ 'decimal' ] = '.';
|
29 |
-
self::$formats[ 'thousand' ] = ',';
|
30 |
-
}
|
31 |
-
|
32 |
-
// List of supported filters and their friendly names
|
33 |
-
self::$columns_names = array(
|
34 |
-
'browser' => array( __( 'Browser', 'wp-slimstat' ), 'varchar' ),
|
35 |
-
'country' => array( __( 'Country Code', 'wp-slimstat' ), 'varchar' ),
|
36 |
-
'ip' => array( __( 'IP Address', 'wp-slimstat' ), 'varchar' ),
|
37 |
-
'searchterms' => array( __( 'Search Terms', 'wp-slimstat' ), 'varchar' ),
|
38 |
-
'language' => array( __( 'Language Code', 'wp-slimstat' ), 'varchar' ),
|
39 |
-
'platform' => array( __( 'Operating System', 'wp-slimstat' ), 'varchar' ),
|
40 |
-
'resource' => array( __( 'Permalink', 'wp-slimstat' ), 'varchar' ),
|
41 |
-
'referer' => array( __( 'Referer', 'wp-slimstat' ), 'varchar' ),
|
42 |
-
'username' => array( __( 'Visitor\'s Username', 'wp-slimstat' ), 'varchar' ),
|
43 |
-
'outbound_resource' => array( __( 'Outbound Link', 'wp-slimstat' ), 'varchar' ),
|
44 |
-
'page_performance' => array( __( 'Page Speed', 'wp-slimstat' ), 'int' ),
|
45 |
-
'no_filter_selected_2' => array( '', 'none' ),
|
46 |
-
'no_filter_selected_3' => array( __( '-- Advanced filters --', 'wp-slimstat' ), 'none' ),
|
47 |
-
'plugins' => array( __( 'Browser Capabilities', 'wp-slimstat' ), 'varchar' ),
|
48 |
-
'browser_version' => array( __( 'Browser Version', 'wp-slimstat' ), 'varchar' ),
|
49 |
-
'browser_type' => array( __( 'Browser Type', 'wp-slimstat' ), 'int' ),
|
50 |
-
'user_agent' => array( __( 'User Agent', 'wp-slimstat' ), 'varchar' ),
|
51 |
-
'city' => array( __( 'City', 'wp-slimstat' ), 'varchar' ),
|
52 |
-
'location' => array( __( 'Coordinates', 'wp-slimstat' ), 'varchar' ),
|
53 |
-
'notes' => array( __( 'Annotations', 'wp-slimstat' ), 'varchar' ),
|
54 |
-
'server_latency' => array( __( 'Server Latency', 'wp-slimstat' ), 'int' ),
|
55 |
-
'author' => array( __( 'Post Author', 'wp-slimstat' ), 'varchar' ),
|
56 |
-
'category' => array( __( 'Post Category ID', 'wp-slimstat' ), 'varchar' ),
|
57 |
-
'other_ip' => array( __( 'Originating IP', 'wp-slimstat' ), 'varchar' ),
|
58 |
-
'content_type' => array( __( 'Resource Content Type', 'wp-slimstat' ), 'varchar' ),
|
59 |
-
'content_id' => array( __( 'Resource ID', 'wp-slimstat' ), 'int' ),
|
60 |
-
'screen_width' => array( __( 'Screen Width', 'wp-slimstat' ), 'int' ),
|
61 |
-
'screen_height' => array( __( 'Screen Height', 'wp-slimstat' ), 'int' ),
|
62 |
-
'resolution' => array( __( 'Viewport Size', 'wp-slimstat' ), 'varchar' ),
|
63 |
-
'visit_id' => array( __( 'Visit ID', 'wp-slimstat' ), 'int' )
|
64 |
-
);
|
65 |
-
|
66 |
-
if ( wp_slimstat::$settings[ 'geolocation_country' ] == 'on' ) {
|
67 |
-
unset( self::$columns_names[ 'city' ] );
|
68 |
-
unset( self::$columns_names[ 'location' ] );
|
69 |
-
}
|
70 |
-
|
71 |
-
// List of supported filters and their friendly names
|
72 |
-
self::$operator_names = array(
|
73 |
-
'equals' => __( 'equals', 'wp-slimstat' ),
|
74 |
-
'is_not_equal_to' => __( 'is not equal to', 'wp-slimstat' ),
|
75 |
-
'contains' => __( 'contains', 'wp-slimstat' ),
|
76 |
-
'includes_in_set' => __( 'is included in', 'wp-slimstat' ),
|
77 |
-
'does_not_contain' => __( 'does not contain', 'wp-slimstat' ),
|
78 |
-
'starts_with' => __( 'starts with', 'wp-slimstat' ),
|
79 |
-
'ends_with' => __( 'ends with', 'wp-slimstat' ),
|
80 |
-
'sounds_like' => __( 'sounds like', 'wp-slimstat' ),
|
81 |
-
'is_greater_than' => __( 'is greater than', 'wp-slimstat' ),
|
82 |
-
'is_less_than' => __( 'is less than', 'wp-slimstat' ),
|
83 |
-
'between' => __( 'is between (x,y)', 'wp-slimstat' ),
|
84 |
-
'matches' => __( 'matches', 'wp-slimstat' ),
|
85 |
-
'does_not_match' => __( 'does not match', 'wp-slimstat' ),
|
86 |
-
'is_empty' => __( 'is empty', 'wp-slimstat' ),
|
87 |
-
'is_not_empty' => __( 'is not empty', 'wp-slimstat' ),
|
88 |
-
);
|
89 |
-
|
90 |
-
// The following filters will not be displayed in the dropdown
|
91 |
-
self::$all_columns_names = array_merge( array(
|
92 |
-
|
93 |
-
// Date and Time
|
94 |
-
'
|
95 |
-
'
|
96 |
-
'
|
97 |
-
'
|
98 |
-
'
|
99 |
-
'
|
100 |
-
'
|
101 |
-
'
|
102 |
-
|
103 |
-
|
104 |
-
'
|
105 |
-
|
106 |
-
|
107 |
-
'
|
108 |
-
'
|
109 |
-
'
|
110 |
-
'
|
111 |
-
'
|
112 |
-
'
|
113 |
-
'
|
114 |
-
|
115 |
-
|
116 |
-
'
|
117 |
-
|
118 |
-
|
119 |
-
'
|
120 |
-
|
121 |
-
'
|
122 |
-
'
|
123 |
-
|
124 |
-
|
125 |
-
'
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
//
|
132 |
-
|
133 |
-
|
134 |
-
// Filters
|
135 |
-
$
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
$filters_raw =
|
173 |
-
}
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
//
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
}
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
}
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
$_where = "$_where
|
250 |
-
}
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
$
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
return $
|
363 |
-
}
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
$
|
408 |
-
|
409 |
-
$
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
case '
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
}
|
465 |
-
break
|
466 |
-
|
467 |
-
|
468 |
-
$
|
469 |
-
break;
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
$
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
$
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
$
|
569 |
-
$
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
$
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
$
|
740 |
-
$
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
//
|
789 |
-
$
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
$
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
$
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
return self::
|
886 |
-
SELECT
|
887 |
-
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
$
|
901 |
-
$
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
$
|
907 |
-
}
|
908 |
-
|
909 |
-
if ( $
|
910 |
-
$
|
911 |
-
}
|
912 |
-
else {
|
913 |
-
$
|
914 |
-
}
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
$
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
$from = "{$GLOBALS['wpdb']->prefix}slim_events te";
|
942 |
-
$where = wp_slimstat_db::get_combined_where( 'te.type > 1', 'notes' );
|
943 |
-
}
|
944 |
-
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
$mixed_outbound_resources
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
-
|
982 |
-
|
983 |
-
$
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
|
990 |
-
|
991 |
-
return
|
992 |
-
|
993 |
-
|
994 |
-
|
995 |
-
|
996 |
-
|
997 |
-
|
998 |
-
|
999 |
-
|
1000 |
-
|
1001 |
-
|
1002 |
-
|
1003 |
-
|
1004 |
-
|
1005 |
-
|
1006 |
-
|
1007 |
-
|
1008 |
-
$_use_date_filters = !empty( $_column[ 'use_date_filters' ] ) ? $_column[ 'use_date_filters' ] : true;
|
1009 |
-
$_as_column = !empty( $_column[ 'as_column' ] ) ? $_column[ 'as_column' ] : '';
|
1010 |
-
$_outer_select_column = !empty( $_column[ 'outer_select_column' ] ) ? $_column[ 'outer_select_column' ] : '';
|
1011 |
-
$_aggr_function = !empty( $_column[ 'aggr_function' ] ) ? $_column[ 'aggr_function' ] : '';
|
1012 |
-
$_column = $_column[ 'columns' ];
|
1013 |
-
}
|
1014 |
-
|
1015 |
-
if ( !empty( $_as_column ) ) {
|
1016 |
-
$_column = "$_column AS $_as_column";
|
1017 |
-
}
|
1018 |
-
else {
|
1019 |
-
$_as_column = $_column;
|
1020 |
-
}
|
1021 |
-
|
1022 |
-
$_where = self::get_combined_where( $_where, $_column );
|
1023 |
-
|
1024 |
-
return self::get_results( "
|
1025 |
-
SELECT $_outer_select_column, ts1.aggrid as $_column, COUNT(*) counthits
|
1026 |
-
FROM (
|
1027 |
-
SELECT $_column, $_aggr_function(id) aggrid
|
1028 |
-
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
1029 |
-
WHERE $_where
|
1030 |
-
GROUP BY $_column
|
1031 |
-
) AS ts1 JOIN {$GLOBALS['wpdb']->prefix}slim_stats t1 ON ts1.aggrid = t1.id
|
1032 |
-
GROUP BY $_outer_select_column
|
1033 |
-
ORDER BY counthits DESC
|
1034 |
-
LIMIT 0, " . self::$filters_normalized[ 'misc' ][ 'limit_results' ],
|
1035 |
-
$_outer_select_column,
|
1036 |
-
'counthits DESC',
|
1037 |
-
$_outer_select_column,
|
1038 |
-
"$_aggr_function(aggrid), SUM(counthits)" );
|
1039 |
-
}
|
1040 |
-
|
1041 |
-
public static function get_top_events() {
|
1042 |
-
if ( empty( self::$filters_normalized[ 'columns' ] ) ) {
|
1043 |
-
$from = "{$GLOBALS['wpdb']->prefix}slim_events te";
|
1044 |
-
$where = wp_slimstat_db::get_combined_where( 'te.type > 1', 'notes' );
|
1045 |
-
}
|
1046 |
-
else {
|
1047 |
-
$from = "{$GLOBALS['wpdb']->prefix}slim_events te INNER JOIN {$GLOBALS['wpdb']->prefix}slim_stats t1 ON te.id = t1.id";
|
1048 |
-
$where = wp_slimstat_db::get_combined_where( 'te.type > 1', 'notes', true, 't1' );
|
1049 |
-
}
|
1050 |
-
|
1051 |
-
return self::get_results( "
|
1052 |
-
SELECT te.notes, te.type, COUNT(*) counthits
|
1053 |
-
FROM $from
|
1054 |
-
WHERE $where
|
1055 |
-
GROUP BY te.notes, te.type
|
1056 |
-
ORDER BY counthits DESC"
|
1057 |
-
);
|
1058 |
-
}
|
1059 |
-
|
1060 |
-
public static function get_top_outbound() {
|
1061 |
-
$mixed_outbound_resources = self::get_recent( 'outbound_resource' );
|
1062 |
-
$clean_outbound_resources = array();
|
1063 |
-
|
1064 |
-
foreach ( $mixed_outbound_resources as $a_mixed_resource ) {
|
1065 |
-
$exploded_resources = explode( ';;;', $a_mixed_resource[ 'outbound_resource' ] );
|
1066 |
-
foreach ( $exploded_resources as $a_exploded_resource ) {
|
1067 |
-
$clean_outbound_resources[] = $a_exploded_resource;
|
1068 |
-
}
|
1069 |
-
}
|
1070 |
-
|
1071 |
-
$clean_outbound_resources = array_count_values( $clean_outbound_resources );
|
1072 |
-
arsort( $clean_outbound_resources );
|
1073 |
-
|
1074 |
-
$sorted_outbound_resources = array();
|
1075 |
-
foreach ( $clean_outbound_resources as $a_resource => $a_count ) {
|
1076 |
-
$sorted_outbound_resources[] = array(
|
1077 |
-
'outbound_resource' => $a_resource,
|
1078 |
-
'counthits' => $a_count
|
1079 |
-
);
|
1080 |
-
}
|
1081 |
-
|
1082 |
-
return $sorted_outbound_resources;
|
1083 |
-
}
|
1084 |
-
|
1085 |
-
protected static function array_column( $input = array(), $columns = array() ) {
|
1086 |
-
$output = array();
|
1087 |
-
|
1088 |
-
foreach ( $input as $a_key => $a_row ) {
|
1089 |
-
foreach ( $columns as $a_column ) {
|
1090 |
-
$a_column = trim( $a_column );
|
1091 |
-
if ( $a_row[ $a_column ] != NULL ) {
|
1092 |
-
$output[ $a_key ][ $a_column ] = $a_row[ $a_column ];
|
1093 |
-
}
|
1094 |
-
}
|
1095 |
-
}
|
1096 |
-
|
1097 |
-
return $output;
|
1098 |
-
}
|
1099 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Let's define the main class with all the methods that we need
|
4 |
+
class wp_slimstat_db {
|
5 |
+
// Filters
|
6 |
+
public static $columns_names = array();
|
7 |
+
public static $operator_names = array();
|
8 |
+
public static $filters_normalized = array();
|
9 |
+
|
10 |
+
// Number and date formats
|
11 |
+
public static $formats = array( 'decimal' => ',', 'thousand' => '.' );
|
12 |
+
|
13 |
+
// Structure that maps filters to SQL information (table names, clauses, lookup tables, etc)
|
14 |
+
public static $sql_where = array( 'columns' => '', 'time_range' => '' );
|
15 |
+
|
16 |
+
// Filters that are not visible in the dropdown
|
17 |
+
public static $all_columns_names = array();
|
18 |
+
|
19 |
+
// Debug message
|
20 |
+
public static $debug_message = '';
|
21 |
+
|
22 |
+
/*
|
23 |
+
* Sets the filters and other structures needed to store the data retrieved from the DB
|
24 |
+
*/
|
25 |
+
public static function init( $_filters = '' ) {
|
26 |
+
// Decimal and thousand separators
|
27 |
+
if ( wp_slimstat::$settings[ 'use_european_separators' ] == 'no' ){
|
28 |
+
self::$formats[ 'decimal' ] = '.';
|
29 |
+
self::$formats[ 'thousand' ] = ',';
|
30 |
+
}
|
31 |
+
|
32 |
+
// List of supported filters and their friendly names
|
33 |
+
self::$columns_names = array(
|
34 |
+
'browser' => array( __( 'Browser', 'wp-slimstat' ), 'varchar' ),
|
35 |
+
'country' => array( __( 'Country Code', 'wp-slimstat' ), 'varchar' ),
|
36 |
+
'ip' => array( __( 'IP Address', 'wp-slimstat' ), 'varchar' ),
|
37 |
+
'searchterms' => array( __( 'Search Terms', 'wp-slimstat' ), 'varchar' ),
|
38 |
+
'language' => array( __( 'Language Code', 'wp-slimstat' ), 'varchar' ),
|
39 |
+
'platform' => array( __( 'Operating System', 'wp-slimstat' ), 'varchar' ),
|
40 |
+
'resource' => array( __( 'Permalink', 'wp-slimstat' ), 'varchar' ),
|
41 |
+
'referer' => array( __( 'Referer', 'wp-slimstat' ), 'varchar' ),
|
42 |
+
'username' => array( __( 'Visitor\'s Username', 'wp-slimstat' ), 'varchar' ),
|
43 |
+
'outbound_resource' => array( __( 'Outbound Link', 'wp-slimstat' ), 'varchar' ),
|
44 |
+
'page_performance' => array( __( 'Page Speed', 'wp-slimstat' ), 'int' ),
|
45 |
+
'no_filter_selected_2' => array( '', 'none' ),
|
46 |
+
'no_filter_selected_3' => array( __( '-- Advanced filters --', 'wp-slimstat' ), 'none' ),
|
47 |
+
'plugins' => array( __( 'Browser Capabilities', 'wp-slimstat' ), 'varchar' ),
|
48 |
+
'browser_version' => array( __( 'Browser Version', 'wp-slimstat' ), 'varchar' ),
|
49 |
+
'browser_type' => array( __( 'Browser Type', 'wp-slimstat' ), 'int' ),
|
50 |
+
'user_agent' => array( __( 'User Agent', 'wp-slimstat' ), 'varchar' ),
|
51 |
+
'city' => array( __( 'City', 'wp-slimstat' ), 'varchar' ),
|
52 |
+
'location' => array( __( 'Coordinates', 'wp-slimstat' ), 'varchar' ),
|
53 |
+
'notes' => array( __( 'Annotations', 'wp-slimstat' ), 'varchar' ),
|
54 |
+
'server_latency' => array( __( 'Server Latency', 'wp-slimstat' ), 'int' ),
|
55 |
+
'author' => array( __( 'Post Author', 'wp-slimstat' ), 'varchar' ),
|
56 |
+
'category' => array( __( 'Post Category ID', 'wp-slimstat' ), 'varchar' ),
|
57 |
+
'other_ip' => array( __( 'Originating IP', 'wp-slimstat' ), 'varchar' ),
|
58 |
+
'content_type' => array( __( 'Resource Content Type', 'wp-slimstat' ), 'varchar' ),
|
59 |
+
'content_id' => array( __( 'Resource ID', 'wp-slimstat' ), 'int' ),
|
60 |
+
'screen_width' => array( __( 'Screen Width', 'wp-slimstat' ), 'int' ),
|
61 |
+
'screen_height' => array( __( 'Screen Height', 'wp-slimstat' ), 'int' ),
|
62 |
+
'resolution' => array( __( 'Viewport Size', 'wp-slimstat' ), 'varchar' ),
|
63 |
+
'visit_id' => array( __( 'Visit ID', 'wp-slimstat' ), 'int' )
|
64 |
+
);
|
65 |
+
|
66 |
+
if ( wp_slimstat::$settings[ 'geolocation_country' ] == 'on' ) {
|
67 |
+
unset( self::$columns_names[ 'city' ] );
|
68 |
+
unset( self::$columns_names[ 'location' ] );
|
69 |
+
}
|
70 |
+
|
71 |
+
// List of supported filters and their friendly names
|
72 |
+
self::$operator_names = array(
|
73 |
+
'equals' => __( 'equals', 'wp-slimstat' ),
|
74 |
+
'is_not_equal_to' => __( 'is not equal to', 'wp-slimstat' ),
|
75 |
+
'contains' => __( 'contains', 'wp-slimstat' ),
|
76 |
+
'includes_in_set' => __( 'is included in', 'wp-slimstat' ),
|
77 |
+
'does_not_contain' => __( 'does not contain', 'wp-slimstat' ),
|
78 |
+
'starts_with' => __( 'starts with', 'wp-slimstat' ),
|
79 |
+
'ends_with' => __( 'ends with', 'wp-slimstat' ),
|
80 |
+
'sounds_like' => __( 'sounds like', 'wp-slimstat' ),
|
81 |
+
'is_greater_than' => __( 'is greater than', 'wp-slimstat' ),
|
82 |
+
'is_less_than' => __( 'is less than', 'wp-slimstat' ),
|
83 |
+
'between' => __( 'is between (x,y)', 'wp-slimstat' ),
|
84 |
+
'matches' => __( 'matches', 'wp-slimstat' ),
|
85 |
+
'does_not_match' => __( 'does not match', 'wp-slimstat' ),
|
86 |
+
'is_empty' => __( 'is empty', 'wp-slimstat' ),
|
87 |
+
'is_not_empty' => __( 'is not empty', 'wp-slimstat' ),
|
88 |
+
);
|
89 |
+
|
90 |
+
// The following filters will not be displayed in the dropdown
|
91 |
+
self::$all_columns_names = array_merge( array(
|
92 |
+
|
93 |
+
// Date and Time
|
94 |
+
'hour' => array( __( 'Hour', 'wp-slimstat' ), 'int' ),
|
95 |
+
'day' => array( __( 'Day', 'wp-slimstat' ), 'int' ),
|
96 |
+
'month' => array( __( 'Month', 'wp-slimstat' ), 'int' ),
|
97 |
+
'year' => array( __( 'Year', 'wp-slimstat' ), 'int' ),
|
98 |
+
'interval' => array( __( 'days', 'wp-slimstat' ), 'int' ),
|
99 |
+
'interval_hours' => array( __( 'hours', 'wp-slimstat' ), 'int' ),
|
100 |
+
'dt' => array( __( 'Timestamp', 'wp-slimstat' ), 'int' ),
|
101 |
+
'dt_out' => array( __( 'Exit Timestamp', 'wp-slimstat' ), 'int' ),
|
102 |
+
|
103 |
+
// Other columns
|
104 |
+
'language_calculated' => array( __( 'Language', 'wp-slimstat' ), 'varchar' ),
|
105 |
+
'platform_calculated' => array( __( 'Operating System', 'wp-slimstat' ), 'varchar' ),
|
106 |
+
'resource_calculated' => array( __( 'Permalink', 'wp-slimstat' ), 'varchar' ),
|
107 |
+
'referer_calculated' => array( __( 'Referer', 'wp-slimstat' ), 'varchar' ),
|
108 |
+
'metric' => array( __( 'Metric', 'wp-slimstat' ), 'varchar' ),
|
109 |
+
'value' => array( __( 'Value', 'wp-slimstat' ), 'varchar' ),
|
110 |
+
'counthits' => array( __( 'Hits', 'wp-slimstat' ), 'int' ),
|
111 |
+
'percentage' => array( __( 'Percentage', 'wp-slimstat' ), 'int' ),
|
112 |
+
'tooltip' => array( __( 'Notes', 'wp-slimstat' ), 'varchar' ),
|
113 |
+
'details' => array( __( 'Notes', 'wp-slimstat' ), 'varchar' ),
|
114 |
+
|
115 |
+
// Events
|
116 |
+
'event_id' => array( __( 'Event ID', 'wp-slimstat' ), 'int' ),
|
117 |
+
'type' => array( __( 'Type', 'wp-slimstat' ), 'int' ),
|
118 |
+
'event_description' => array( __( 'Event Description', 'wp-slimstat' ), 'varchar' ),
|
119 |
+
'position' => array( __( 'Event Coordinates', 'wp-slimstat' ), 'int' ),
|
120 |
+
|
121 |
+
'limit_results' => array( __( 'Max Results', 'wp-slimstat' ), 'int' ),
|
122 |
+
'start_from' => array( __( 'Offset', 'wp-slimstat' ), 'int' ),
|
123 |
+
|
124 |
+
// Misc Filters
|
125 |
+
'strtotime' => array( 0, 'int' )
|
126 |
+
), self::$columns_names );
|
127 |
+
|
128 |
+
// Allow third party plugins to add even more column names to the array
|
129 |
+
self::$all_columns_names = apply_filters( 'slimstat_column_names', self::$all_columns_names );
|
130 |
+
|
131 |
+
// Filters use the following format: browser equals Firefox&&&country contains gb
|
132 |
+
$filters_array = array();
|
133 |
+
|
134 |
+
// Filters are set via javascript as hidden fields and submitted as a POST request. They override anything passed through the regular input fields
|
135 |
+
if ( !empty( $_POST[ 'fs' ] ) && is_array( $_POST[ 'fs' ] ) ) {
|
136 |
+
foreach( $_POST[ 'fs' ] as $a_request_filter_name => $a_request_filter_value ) {
|
137 |
+
$filters_array[ htmlspecialchars( $a_request_filter_name ) ] = "$a_request_filter_name $a_request_filter_value";
|
138 |
+
}
|
139 |
+
}
|
140 |
+
|
141 |
+
// Date filters (input fields)
|
142 |
+
foreach ( array( 'hour', 'day', 'month', 'year', 'interval', 'interval_hours' ) as $a_date_time_filter_name ) {
|
143 |
+
if ( isset( $_POST[ $a_date_time_filter_name ] ) && strlen( $_POST[ $a_date_time_filter_name ] ) > 0 ) { // here we use isset instead of !empty to handle ZERO as a valid input value
|
144 |
+
$filters_array[ $a_date_time_filter_name ] = "$a_date_time_filter_name equals " . intval( $_POST[ $a_date_time_filter_name ] );
|
145 |
+
}
|
146 |
+
}
|
147 |
+
|
148 |
+
// Fields and drop downs
|
149 |
+
if ( !empty( $_POST[ 'f' ] ) && !empty( $_POST[ 'o' ] ) ) {
|
150 |
+
$filters_array[ htmlspecialchars( $_POST[ 'f' ] ) ] = "{$_POST[ 'f' ]} {$_POST[ 'o' ]} " . ( isset( $_POST[ 'v' ] ) ? $_POST[ 'v' ] : '' );
|
151 |
+
}
|
152 |
+
|
153 |
+
// Filters set via the plugin options
|
154 |
+
if ( wp_slimstat::$settings[ 'restrict_authors_view' ] == 'on' && !current_user_can( 'manage_options' ) && !empty( $GLOBALS[ 'current_user' ]->user_login ) ) {
|
155 |
+
$filters_array[ 'author' ] = 'author equals ' . $GLOBALS[ 'current_user' ]->user_login;
|
156 |
+
}
|
157 |
+
|
158 |
+
if ( !empty( $filters_array ) ) {
|
159 |
+
$filters_raw = implode( '&&&', $filters_array );
|
160 |
+
}
|
161 |
+
|
162 |
+
// Filters are defined as: browser equals Chrome&&&country starts_with en
|
163 |
+
if ( !isset( $filters_raw ) || !is_string( $filters_raw ) ) {
|
164 |
+
$filters_raw = '';
|
165 |
+
}
|
166 |
+
|
167 |
+
if ( !empty( $_filters ) && is_string( $_filters ) ) {
|
168 |
+
if ( !empty( $filters_raw ) ) {
|
169 |
+
$filters_raw = empty( $filters_raw ) ? $_filters : $_filters . '&&&' . $filters_raw;
|
170 |
+
}
|
171 |
+
else {
|
172 |
+
$filters_raw = $_filters;
|
173 |
+
}
|
174 |
+
}
|
175 |
+
|
176 |
+
// Hook for the... filters
|
177 |
+
$filters_raw = apply_filters( 'slimstat_db_pre_filters', $filters_raw );
|
178 |
+
|
179 |
+
// Normalize the filters
|
180 |
+
self::$filters_normalized = self::init_filters( $filters_raw );
|
181 |
+
}
|
182 |
+
// end init
|
183 |
+
|
184 |
+
/**
|
185 |
+
* Builds the array of WHERE clauses to be used later in our SQL queries
|
186 |
+
*/
|
187 |
+
protected static function _get_sql_where( $_filters_normalized = array(), $_slim_stats_table_alias = '' ) {
|
188 |
+
$sql_array = array();
|
189 |
+
|
190 |
+
foreach ( $_filters_normalized as $a_filter_column => $a_filter_data ) {
|
191 |
+
// Add-ons can set their own custom filters, which are ignored here
|
192 |
+
if ( strpos( $a_filter_column, 'addon_' ) !== false ) {
|
193 |
+
continue;
|
194 |
+
}
|
195 |
+
|
196 |
+
$sql_array[] = self::get_single_where_clause( $a_filter_column, $a_filter_data[ 0 ], $a_filter_data[ 1 ], $_slim_stats_table_alias );
|
197 |
+
}
|
198 |
+
|
199 |
+
// Flatten array
|
200 |
+
if ( !empty( $sql_array ) ) {
|
201 |
+
return implode( ' AND ', $sql_array );
|
202 |
+
}
|
203 |
+
|
204 |
+
return '';
|
205 |
+
}
|
206 |
+
|
207 |
+
public static function get_combined_where( $_where = '', $_column = '*', $_use_date_filters = true, $_slim_stats_table_alias = '' ) {
|
208 |
+
$dt_with_alias = 'dt';
|
209 |
+
if ( !empty( $_slim_stats_table_alias ) ) {
|
210 |
+
$dt_with_alias = $_slim_stats_table_alias . '.' . $dt_with_alias;
|
211 |
+
}
|
212 |
+
|
213 |
+
$time_range_condition = '';
|
214 |
+
if ( empty( $_where ) ) {
|
215 |
+
if ( !empty( self::$filters_normalized[ 'columns' ] ) ) {
|
216 |
+
$_where = self::_get_sql_where( self::$filters_normalized[ 'columns' ], $_slim_stats_table_alias );
|
217 |
+
|
218 |
+
if ($_use_date_filters) {
|
219 |
+
$time_range_condition = "$dt_with_alias BETWEEN " . self::$filters_normalized[ 'utime' ][ 'start' ] . ' AND ' . self::$filters_normalized[ 'utime' ][ 'end' ];
|
220 |
+
}
|
221 |
+
}
|
222 |
+
elseif ( $_use_date_filters ) {
|
223 |
+
$time_range_condition = "$dt_with_alias BETWEEN " . self::$filters_normalized[ 'utime' ][ 'start' ] . ' AND ' . self::$filters_normalized[ 'utime' ][ 'end' ];
|
224 |
+
}
|
225 |
+
|
226 |
+
// This could happen if we have custom filters (add-ons, third party tools)
|
227 |
+
if ( empty( $_where ) ) {
|
228 |
+
$_where = '1=1';
|
229 |
+
}
|
230 |
+
}
|
231 |
+
else {
|
232 |
+
if ( $_where != '1=1' && !empty( self::$filters_normalized[ 'columns' ] ) ) {
|
233 |
+
$new_clause = self::_get_sql_where( self::$filters_normalized[ 'columns' ], $_slim_stats_table_alias );
|
234 |
+
|
235 |
+
// This condition could be empty if it's related to a custom column
|
236 |
+
if ( !empty( $new_clause ) ) {
|
237 |
+
$_where .= ' AND ' . $new_clause;
|
238 |
+
}
|
239 |
+
}
|
240 |
+
if ( $_use_date_filters ) {
|
241 |
+
$time_range_condition = "$dt_with_alias BETWEEN " . self::$filters_normalized[ 'utime' ][ 'start' ] . ' AND ' . self::$filters_normalized[ 'utime' ][ 'end' ];
|
242 |
+
}
|
243 |
+
}
|
244 |
+
|
245 |
+
if ( !empty( $_where ) && !empty( $time_range_condition ) ) {
|
246 |
+
$_where = "$_where AND $time_range_condition";
|
247 |
+
}
|
248 |
+
else {
|
249 |
+
$_where = trim( "$_where $time_range_condition" );
|
250 |
+
}
|
251 |
+
|
252 |
+
if ( !empty( $_column ) && !empty( self::$columns_names[ $_column ] ) ) {
|
253 |
+
$_column = str_replace( '_calculated', '', $_column );
|
254 |
+
$column_with_alias = $_column;
|
255 |
+
if ( !empty( $_slim_stats_table_alias ) ) {
|
256 |
+
$column_with_alias = $_slim_stats_table_alias . '.' . $column_with_alias;
|
257 |
+
}
|
258 |
+
|
259 |
+
$filter_empty = "$column_with_alias " . ( ( self::$columns_names[ $_column ] [ 1 ] == 'varchar' ) ? 'IS NULL' : '= 0' );
|
260 |
+
$filter_not_empty = "$column_with_alias " . ( ( self::$columns_names[ $_column ] [ 1 ] == 'varchar' ) ? 'IS NOT NULL' : '<> 0' );
|
261 |
+
|
262 |
+
if ( strpos( $_where, $filter_empty ) === false && strpos( $_where, $filter_not_empty) === false) {
|
263 |
+
$_where = "$filter_not_empty AND $_where";
|
264 |
+
}
|
265 |
+
}
|
266 |
+
|
267 |
+
return $_where;
|
268 |
+
}
|
269 |
+
|
270 |
+
/**
|
271 |
+
* Translates user-friendly operators into SQL conditions
|
272 |
+
*/
|
273 |
+
public static function get_single_where_clause( $_column = 'id', $_operator = 'equals', $_value = '', $_slim_stats_table_alias = '' ) {
|
274 |
+
$filter_empty = ( !empty( self::$columns_names[ $_column ] ) && self::$columns_names[ $_column ] [ 1 ] == 'varchar' ) ? 'IS NULL' : '= 0';
|
275 |
+
$filter_not_empty = ( !empty( self::$columns_names[ $_column ] ) && self::$columns_names[ $_column ] [ 1 ] == 'varchar' ) ? 'IS NOT NULL' : '<> 0';
|
276 |
+
|
277 |
+
$_column = str_replace( '_calculated', '', $_column );
|
278 |
+
|
279 |
+
$column_with_alias = $_column;
|
280 |
+
if ( !empty( $_slim_stats_table_alias ) ) {
|
281 |
+
$column_with_alias = $_slim_stats_table_alias . '.' . $_column;
|
282 |
+
}
|
283 |
+
|
284 |
+
switch( $_column ) {
|
285 |
+
case 'ip':
|
286 |
+
case 'other_ip':
|
287 |
+
$filter_empty = '= "0.0.0.0"';
|
288 |
+
break;
|
289 |
+
default:
|
290 |
+
break;
|
291 |
+
}
|
292 |
+
|
293 |
+
$where = array( '', $_value );
|
294 |
+
switch ( $_operator ) {
|
295 |
+
case 'is_not_equal_to':
|
296 |
+
$where[ 0 ] = "$column_with_alias <> %s";
|
297 |
+
break;
|
298 |
+
|
299 |
+
case 'contains':
|
300 |
+
$where = array( "$column_with_alias LIKE %s", '%'.$_value.'%' );
|
301 |
+
break;
|
302 |
+
|
303 |
+
case 'includes_in_set':
|
304 |
+
case 'included_in_set':
|
305 |
+
$where[ 0 ] = "FIND_IN_SET($column_with_alias, %s) > 0";
|
306 |
+
break;
|
307 |
+
|
308 |
+
case 'does_not_contain':
|
309 |
+
$where = array( "$column_with_alias NOT LIKE %s", '%'.$_value.'%' );
|
310 |
+
break;
|
311 |
+
|
312 |
+
case 'starts_with':
|
313 |
+
$where = array( "$column_with_alias LIKE %s", $_value.'%' );
|
314 |
+
break;
|
315 |
+
|
316 |
+
case 'ends_with':
|
317 |
+
$where = array( "$column_with_alias LIKE %s", '%'.$_value );
|
318 |
+
break;
|
319 |
+
|
320 |
+
case 'sounds_like':
|
321 |
+
$where[ 0 ] = "SOUNDEX($column_with_alias) = SOUNDEX(%s)";
|
322 |
+
break;
|
323 |
+
|
324 |
+
case 'is_empty':
|
325 |
+
$where = array( "$column_with_alias $filter_empty", '' );
|
326 |
+
break;
|
327 |
+
|
328 |
+
case 'is_not_empty':
|
329 |
+
$where = array( "$column_with_alias $filter_not_empty", '' );
|
330 |
+
break;
|
331 |
+
|
332 |
+
case 'is_greater_than':
|
333 |
+
$where[ 0 ] = "$column_with_alias > %d";
|
334 |
+
break;
|
335 |
+
|
336 |
+
case 'is_less_than':
|
337 |
+
$where[ 0 ] = "$column_with_alias < %d";
|
338 |
+
break;
|
339 |
+
|
340 |
+
case 'between':
|
341 |
+
$range = explode( ',', $_value );
|
342 |
+
$where = array( "$column_with_alias BETWEEN %d AND %d", array( $range[ 0 ], $range[ 1 ] ) );
|
343 |
+
break;
|
344 |
+
|
345 |
+
case 'matches':
|
346 |
+
$where[ 0 ] = "$column_with_alias REGEXP %s";
|
347 |
+
break;
|
348 |
+
|
349 |
+
case 'does_not_match':
|
350 |
+
$where[ 0 ] = "$column_with_alias NOT REGEXP %s";
|
351 |
+
break;
|
352 |
+
|
353 |
+
default:
|
354 |
+
$where[ 0 ] = "$column_with_alias = %s";
|
355 |
+
break;
|
356 |
+
}
|
357 |
+
|
358 |
+
if ( isset( $where[ 1 ] ) && $where[ 1 ] != '' ) {
|
359 |
+
return $GLOBALS[ 'wpdb' ]->prepare( $where[ 0 ], $where[ 1 ] );
|
360 |
+
}
|
361 |
+
else {
|
362 |
+
return $where[ 0 ];
|
363 |
+
}
|
364 |
+
}
|
365 |
+
|
366 |
+
public static function get_results( $_sql = '', $_select_no_aggregate_values = '', $_order_by = '', $_group_by = '', $_aggregate_values_add = '' ) {
|
367 |
+
$_sql = apply_filters( 'slimstat_get_results_sql', $_sql, $_select_no_aggregate_values, $_order_by, $_group_by, $_aggregate_values_add );
|
368 |
+
|
369 |
+
if ( wp_slimstat::$settings[ 'show_sql_debug' ] == 'on' ) {
|
370 |
+
self::$debug_message .= "<p class='debug'>$_sql</p>";
|
371 |
+
}
|
372 |
+
|
373 |
+
return wp_slimstat::$wpdb->get_results( $_sql, ARRAY_A );
|
374 |
+
}
|
375 |
+
|
376 |
+
public static function get_var( $_sql = '', $_aggregate_value = '' ) {
|
377 |
+
$_sql = apply_filters( 'slimstat_get_var_sql', $_sql, $_aggregate_value );
|
378 |
+
|
379 |
+
if ( wp_slimstat::$settings[ 'show_sql_debug' ] == 'on' ) {
|
380 |
+
self::$debug_message .= "<p class='debug'>$_sql</p>";
|
381 |
+
}
|
382 |
+
|
383 |
+
return wp_slimstat::$wpdb->get_var( $_sql );
|
384 |
+
}
|
385 |
+
|
386 |
+
public static function parse_filters( $_filters_raw ) {
|
387 |
+
$filters_parsed = array(
|
388 |
+
'columns' => array(),
|
389 |
+
'date' => array()
|
390 |
+
);
|
391 |
+
|
392 |
+
if ( !empty( $_filters_raw ) ) {
|
393 |
+
$matches = explode( '&&&', $_filters_raw );
|
394 |
+
|
395 |
+
foreach( $matches as $idx => $a_match ) {
|
396 |
+
preg_match( '/([^\s]+)\s([^\s]+)\s(.+)?/', urldecode( $a_match ), $a_filter );
|
397 |
+
|
398 |
+
if ( empty( $a_filter ) || ( ( !array_key_exists( $a_filter[ 1 ], self::$all_columns_names ) || strpos( $a_filter[ 1 ], 'no_filter' ) !== false ) && strpos( $a_filter[ 1 ], 'addon_' ) === false ) ) {
|
399 |
+
continue;
|
400 |
+
}
|
401 |
+
|
402 |
+
switch( $a_filter[ 1 ] ) {
|
403 |
+
case 'strtotime':
|
404 |
+
$custom_date = strtotime( $a_filter[ 3 ], date_i18n( 'U' ) );
|
405 |
+
|
406 |
+
$filters_parsed[ 'date' ][ 'hour' ] = intval( date( 'H', $custom_date ) );
|
407 |
+
$filters_parsed[ 'date' ][ 'day' ] = intval( date( 'j', $custom_date ) );
|
408 |
+
$filters_parsed[ 'date' ][ 'month' ] = intval( date( 'n', $custom_date ) );
|
409 |
+
$filters_parsed[ 'date' ][ 'year' ] = intval( date( 'Y', $custom_date ) );
|
410 |
+
break;
|
411 |
+
|
412 |
+
case 'hour':
|
413 |
+
case 'day':
|
414 |
+
case 'month':
|
415 |
+
case 'year':
|
416 |
+
if ( is_numeric( $a_filter[ 3 ] ) ) {
|
417 |
+
$filters_parsed[ 'date' ][ $a_filter[ 1 ] ] = intval( $a_filter[ 3 ] );
|
418 |
+
}
|
419 |
+
else{
|
420 |
+
// Try to apply strtotime to value
|
421 |
+
switch( $a_filter[ 1 ] ) {
|
422 |
+
case 'hour':
|
423 |
+
$filters_parsed[ 'date' ][ 'hour' ] = intval( date( 'H', strtotime( $a_filter[ 3 ], date_i18n( 'U' ) ) ) );
|
424 |
+
break;
|
425 |
+
|
426 |
+
case 'day':
|
427 |
+
$filters_parsed[ 'date' ][ 'day' ] = intval( date( 'j', strtotime( $a_filter[ 3 ], date_i18n( 'U' ) ) ) );
|
428 |
+
break;
|
429 |
+
|
430 |
+
case 'month':
|
431 |
+
$filters_parsed[ 'date' ][ 'month' ] = intval( date( 'n', strtotime( $a_filter[ 3 ], date_i18n( 'U' ) ) ) );
|
432 |
+
break;
|
433 |
+
|
434 |
+
case 'year':
|
435 |
+
$filters_parsed[ 'date' ][ 'year' ] = intval( date( 'Y', strtotime( $a_filter[ 3 ], date_i18n( 'U' ) ) ) );
|
436 |
+
break;
|
437 |
+
|
438 |
+
default:
|
439 |
+
break;
|
440 |
+
}
|
441 |
+
|
442 |
+
if ( $filters_parsed[ 'date' ][ $a_filter[ 1 ] ] === false ) {
|
443 |
+
unset( $filters_parsed[ 'date' ][ $a_filter[ 1 ] ] );
|
444 |
+
}
|
445 |
+
}
|
446 |
+
break;
|
447 |
+
|
448 |
+
case 'interval':
|
449 |
+
case 'interval_hours':
|
450 |
+
$intval_filter = intval( $a_filter[ 3 ] );
|
451 |
+
$filters_parsed[ 'date' ][ $a_filter[ 1 ] ] = $intval_filter;
|
452 |
+
break;
|
453 |
+
|
454 |
+
case 'limit_results':
|
455 |
+
case 'start_from':
|
456 |
+
$filters_parsed[ 'misc' ][ $a_filter[ 1 ] ] = str_replace( '\\', '', htmlspecialchars_decode( $a_filter[ 3 ] ) );
|
457 |
+
break;
|
458 |
+
|
459 |
+
case 'content_id':
|
460 |
+
if ( !empty( $a_filter[ 3 ] ) ) {
|
461 |
+
$content_id = ( $a_filter[ 3 ] == 'current' && !empty( $GLOBALS[ 'post' ]->ID ) ) ? $GLOBALS[ 'post' ]->ID : $a_filter[ 3 ];
|
462 |
+
$filters_parsed[ 'columns' ][ $a_filter[ 1 ] ] = array( $a_filter[ 2 ], $content_id );
|
463 |
+
break;
|
464 |
+
}
|
465 |
+
// no break here: if value IS numeric, go to the default parser here below
|
466 |
+
|
467 |
+
default:
|
468 |
+
$filters_parsed[ 'columns' ][ $a_filter[ 1 ] ] = array( $a_filter[ 2 ], isset( $a_filter[ 3 ] ) ? str_replace( '\\', '', htmlspecialchars_decode( $a_filter[ 3 ] ) ) : '' );
|
469 |
+
break;
|
470 |
+
}
|
471 |
+
}
|
472 |
+
}
|
473 |
+
|
474 |
+
return $filters_parsed;
|
475 |
+
}
|
476 |
+
|
477 |
+
public static function init_filters( $_filters_raw = '' ) {
|
478 |
+
$fn = self::parse_filters( $_filters_raw );
|
479 |
+
|
480 |
+
// Initialize default values
|
481 |
+
if ( empty( $fn[ 'misc' ][ 'limit_results' ] ) ) {
|
482 |
+
$fn[ 'misc' ][ 'limit_results' ] = wp_slimstat::$settings[ 'limit_results' ];
|
483 |
+
}
|
484 |
+
if ( empty( $fn[ 'misc' ][ 'start_from' ] ) ) {
|
485 |
+
$fn[ 'misc' ][ 'start_from' ] = 0;
|
486 |
+
}
|
487 |
+
|
488 |
+
$fn[ 'utime' ] = array(
|
489 |
+
'start' => 0,
|
490 |
+
'end' => 0
|
491 |
+
);
|
492 |
+
|
493 |
+
// Temporarily disable any filters on date_i18n
|
494 |
+
wp_slimstat::toggle_date_i18n_filters( false );
|
495 |
+
|
496 |
+
// Normalize the various date values
|
497 |
+
|
498 |
+
// Intervals
|
499 |
+
// If neither an interval nor interval_hours were specified...
|
500 |
+
if ( !isset( $fn[ 'date' ][ 'interval_hours' ] ) && empty( $fn[ 'date' ][ 'interval' ] ) ) {
|
501 |
+
$fn[ 'date' ][ 'interval_hours' ] = 0;
|
502 |
+
|
503 |
+
// If a day has been specified, then interval = 1 (show only that day)
|
504 |
+
if ( !empty( $fn[ 'date' ][ 'day' ] ) ) {
|
505 |
+
$fn[ 'date' ][ 'interval' ] = -1;
|
506 |
+
}
|
507 |
+
// Show last X days, if the corresponding setting is enabled
|
508 |
+
else if ( empty( wp_slimstat::$settings[ 'use_current_month_timespan' ] ) || wp_slimstat::$settings[ 'use_current_month_timespan' ] != 'on' ) {
|
509 |
+
$fn[ 'date' ][ 'interval' ] = - abs( wp_slimstat::$settings[ 'posts_column_day_interval' ] );
|
510 |
+
}
|
511 |
+
// Otherwise, the interval is the number of days from the beginning of the month (current month view)
|
512 |
+
else {
|
513 |
+
$fn[ 'date' ][ 'interval' ] = - intval( date_i18n( 'j' ) );
|
514 |
+
}
|
515 |
+
}
|
516 |
+
else if ( empty( $fn[ 'date' ][ 'interval_hours' ] ) ) {
|
517 |
+
// interval was set, but not interval_hours
|
518 |
+
$fn[ 'date' ][ 'interval_hours' ] = 0;
|
519 |
+
}
|
520 |
+
else if ( empty( $fn[ 'date' ][ 'interval' ] ) ) {
|
521 |
+
// interval_hours was set, but not interval
|
522 |
+
$fn[ 'date' ][ 'interval' ] = 0;
|
523 |
+
}
|
524 |
+
|
525 |
+
$fn[ 'utime' ][ 'range' ] = $fn[ 'date' ][ 'interval' ] * 86400 + $fn[ 'date' ][ 'interval_hours' ] * 3600;
|
526 |
+
|
527 |
+
// Day
|
528 |
+
if ( empty( $fn[ 'date' ][ 'day' ] ) ) {
|
529 |
+
$fn[ 'date' ][ 'day' ] = intval( date_i18n( 'j' ) );
|
530 |
+
}
|
531 |
+
|
532 |
+
// Month
|
533 |
+
if ( empty( $fn[ 'date' ][ 'month' ] ) ) {
|
534 |
+
$fn[ 'date' ][ 'month' ] = intval( date_i18n( 'n' ) );
|
535 |
+
}
|
536 |
+
|
537 |
+
// Year
|
538 |
+
if ( empty( $fn[ 'date' ][ 'year' ] ) ) {
|
539 |
+
$fn[ 'date' ][ 'year' ] = intval( date_i18n( 'Y' ) );
|
540 |
+
}
|
541 |
+
|
542 |
+
if ( $fn[ 'utime' ][ 'range' ] < 0 ) {
|
543 |
+
$fn[ 'utime' ][ 'end' ] = mktime(
|
544 |
+
!empty( $fn[ 'date' ][ 'hour' ] ) ? $fn[ 'date' ][ 'hour' ] : 23,
|
545 |
+
59,
|
546 |
+
59,
|
547 |
+
$fn[ 'date' ][ 'month' ],
|
548 |
+
$fn[ 'date' ][ 'day' ],
|
549 |
+
$fn[ 'date' ][ 'year' ]
|
550 |
+
);
|
551 |
+
|
552 |
+
// If end is in the future and the level of granularity is hours, set it to now
|
553 |
+
if ( !empty( $fn[ 'date' ][ 'interval_hours' ] ) && $fn[ 'utime' ][ 'end' ] > date_i18n( 'U' ) ) {
|
554 |
+
$fn[ 'utime' ][ 'end' ] = intval( date_i18n( 'U' ) );
|
555 |
+
}
|
556 |
+
|
557 |
+
$fn[ 'utime' ][ 'range' ] = $fn[ 'utime' ][ 'range' ] + 1;
|
558 |
+
$fn[ 'utime' ][ 'start' ] = $fn[ 'utime' ][ 'end' ] + $fn[ 'utime' ][ 'range' ];
|
559 |
+
|
560 |
+
// Store the absolute value for later (chart)
|
561 |
+
$fn[ 'utime' ][ 'range' ] = - $fn[ 'utime' ][ 'range' ];
|
562 |
+
}
|
563 |
+
else {
|
564 |
+
$fn[ 'utime' ][ 'start' ] = mktime(
|
565 |
+
!empty( $fn[ 'date' ][ 'hour' ] ) ? $fn[ 'date' ][ 'hour' ] : 0,
|
566 |
+
0,
|
567 |
+
0,
|
568 |
+
$fn[ 'date' ][ 'month' ],
|
569 |
+
$fn[ 'date' ][ 'day' ],
|
570 |
+
$fn[ 'date' ][ 'year' ]
|
571 |
+
);
|
572 |
+
|
573 |
+
$fn[ 'utime' ][ 'range' ] = $fn[ 'utime' ][ 'range' ] - 1;
|
574 |
+
$fn[ 'utime' ][ 'end' ] = $fn[ 'utime' ][ 'start' ] + $fn[ 'utime' ][ 'range' ];
|
575 |
+
}
|
576 |
+
|
577 |
+
// If end is in the future, set it to now
|
578 |
+
if ( $fn[ 'utime' ][ 'end' ] > date_i18n( 'U' ) ) {
|
579 |
+
$fn[ 'utime' ][ 'end' ] = intval( date_i18n( 'U' ) );
|
580 |
+
}
|
581 |
+
|
582 |
+
// Restore filters on date_i18n
|
583 |
+
wp_slimstat::toggle_date_i18n_filters( true );
|
584 |
+
|
585 |
+
// Apply third-party filters
|
586 |
+
$fn = apply_filters( 'slimstat_db_filters_normalized', $fn, $_filters_raw );
|
587 |
+
|
588 |
+
return $fn;
|
589 |
+
}
|
590 |
+
|
591 |
+
// The following methods retrieve the information from the database
|
592 |
+
|
593 |
+
public static function count_bouncing_pages() {
|
594 |
+
$where = self::get_combined_where( 'visit_id > 0 AND content_type <> "404"', 'resource' );
|
595 |
+
|
596 |
+
return intval( self::get_var( "
|
597 |
+
SELECT COUNT(*) counthits
|
598 |
+
FROM (
|
599 |
+
SELECT resource, visit_id
|
600 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
601 |
+
WHERE $where
|
602 |
+
GROUP BY resource
|
603 |
+
HAVING COUNT(visit_id) = 1
|
604 |
+
) as ts1",
|
605 |
+
'SUM(counthits) AS counthits' ) );
|
606 |
+
}
|
607 |
+
|
608 |
+
public static function count_exit_pages() {
|
609 |
+
$where = self::get_combined_where( 'visit_id > 0', 'resource' );
|
610 |
+
|
611 |
+
return intval( self::get_var( "
|
612 |
+
SELECT COUNT(*) counthits
|
613 |
+
FROM (
|
614 |
+
SELECT resource, dt
|
615 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
616 |
+
WHERE $where
|
617 |
+
GROUP BY resource
|
618 |
+
HAVING dt = MAX(dt)
|
619 |
+
) AS ts1",
|
620 |
+
'SUM(counthits) AS counthits' ) );
|
621 |
+
}
|
622 |
+
|
623 |
+
public static function count_records( $_column = 'id', $_where = '', $_use_date_filters = true ) {
|
624 |
+
$distinct_column = ( $_column != 'id' ) ? "DISTINCT $_column" : $_column;
|
625 |
+
$_where = self::get_combined_where( $_where, $_column, $_use_date_filters );
|
626 |
+
|
627 |
+
return intval( self::get_var( "
|
628 |
+
SELECT COUNT($distinct_column) counthits
|
629 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
630 |
+
WHERE $_where",
|
631 |
+
'SUM(counthits) AS counthits' ) );
|
632 |
+
}
|
633 |
+
|
634 |
+
public static function count_records_having( $_column = 'id', $_where = '', $_having = '' ) {
|
635 |
+
$_where = self::get_combined_where( $_where, $_column );
|
636 |
+
|
637 |
+
return intval( self::get_var( "
|
638 |
+
SELECT COUNT(*) counthits FROM (
|
639 |
+
SELECT $_column
|
640 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
641 |
+
WHERE $_where
|
642 |
+
GROUP BY $_column
|
643 |
+
HAVING $_having
|
644 |
+
) AS ts1",
|
645 |
+
'SUM(counthits) AS counthits' ) );
|
646 |
+
}
|
647 |
+
|
648 |
+
public static function get_data_for_chart( $_args = array() ) {
|
649 |
+
// Determine the chart granularity based on the date range
|
650 |
+
// - Up to 24 hours (86400 seconds): HOURLY
|
651 |
+
// - Up to 120 days (10368000 seconds): DAILY
|
652 |
+
// - Otherwise: MONTHLY
|
653 |
+
$params = array();
|
654 |
+
|
655 |
+
if ( self::$filters_normalized[ 'utime' ][ 'range' ] < 86400 ) {
|
656 |
+
$params[ 'group_by' ] = "DAY(CONVERT_TZ(FROM_UNIXTIME(dt), @@session.time_zone, '+00:00')), HOUR(CONVERT_TZ(FROM_UNIXTIME(dt), @@session.time_zone, '+00:00'))";
|
657 |
+
$params[ 'data_points_label' ] = ( self::$formats[ 'decimal' ] == '.' ) ? 'm/d - h a' : 'd/m - H';
|
658 |
+
$params[ 'data_points_count' ] = ceil( self::$filters_normalized[ 'utime' ][ 'range' ] / 3600 );
|
659 |
+
$params[ 'granularity' ] = 'HOUR';
|
660 |
+
}
|
661 |
+
else if ( self::$filters_normalized[ 'utime' ][ 'range' ] < 10368000 ) {
|
662 |
+
$params[ 'group_by' ] = "MONTH(CONVERT_TZ(FROM_UNIXTIME(dt), @@session.time_zone, '+00:00')), DAY(CONVERT_TZ(FROM_UNIXTIME(dt), @@session.time_zone, '+00:00'))";
|
663 |
+
$params[ 'data_points_label' ] = ( self::$formats[ 'decimal' ] == '.' ) ? 'm/d' : 'd/m';
|
664 |
+
$params[ 'data_points_count' ] = ceil( self::$filters_normalized[ 'utime' ][ 'range' ] / 86400 );
|
665 |
+
$params[ 'granularity' ] = 'DAY';
|
666 |
+
}
|
667 |
+
else {
|
668 |
+
$params[ 'group_by' ] = "YEAR(CONVERT_TZ(FROM_UNIXTIME(dt), @@session.time_zone, '+00:00')), MONTH(CONVERT_TZ(FROM_UNIXTIME(dt), @@session.time_zone, '+00:00'))";
|
669 |
+
$params[ 'data_points_label' ] = 'm/y';
|
670 |
+
$params[ 'data_points_count' ] = self::count_months_between( self::$filters_normalized[ 'utime' ][ 'start' ], self::$filters_normalized[ 'utime' ][ 'end' ] );
|
671 |
+
$params[ 'granularity' ] = 'MONTH';
|
672 |
+
}
|
673 |
+
|
674 |
+
// Calculate the "previous/comparison" time range
|
675 |
+
$params[ 'previous_end' ] = self::$filters_normalized[ 'utime' ][ 'start' ] - 1;
|
676 |
+
$params[ 'previous_start' ] = $params[ 'previous_end' ] - self::$filters_normalized[ 'utime' ][ 'range' ];
|
677 |
+
|
678 |
+
// Build the SQL query
|
679 |
+
if ( empty( $_args[ 'where' ] ) ) {
|
680 |
+
$_args[ 'where' ] = '';
|
681 |
+
}
|
682 |
+
|
683 |
+
$sql = "
|
684 |
+
SELECT MIN(dt) AS dt, {$_args[ 'data1' ]} AS v1, {$_args[ 'data2' ]} AS v2
|
685 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
686 |
+
WHERE " . self::get_combined_where( $_args[ 'where' ], '*', false ) . " AND (dt BETWEEN {$params[ 'previous_start' ]} AND {$params[ 'previous_end' ]} OR dt BETWEEN " . self::$filters_normalized[ 'utime' ][ 'start' ] . ' AND ' . self::$filters_normalized[ 'utime' ][ 'end' ] . ")
|
687 |
+
GROUP BY {$params[ 'group_by' ]}";
|
688 |
+
|
689 |
+
// Get the data
|
690 |
+
$results = self::get_results(
|
691 |
+
$sql,
|
692 |
+
'dt',
|
693 |
+
'',
|
694 |
+
$params[ 'group_by' ], 'SUM(v1) AS v1, SUM(v2) AS v2'
|
695 |
+
);
|
696 |
+
|
697 |
+
$output = array(
|
698 |
+
'keys' => array()
|
699 |
+
);
|
700 |
+
|
701 |
+
// No data? No problem!
|
702 |
+
if ( !is_array( $results ) || empty( $results ) ) {
|
703 |
+
return $output;
|
704 |
+
}
|
705 |
+
|
706 |
+
// Generate the output array (sent to the chart library) by combining all the data collected so far
|
707 |
+
|
708 |
+
// Let's start by initializing all the data points to zero
|
709 |
+
for ( $i = 0; $i < $params[ 'data_points_count' ]; $i++ ) {
|
710 |
+
$v1_label = date( $params[ 'data_points_label' ], strtotime( "+$i {$params[ 'granularity' ]}", self::$filters_normalized[ 'utime' ][ 'start' ] ) );
|
711 |
+
$v3_label = date( $params[ 'data_points_label' ], strtotime( "+$i {$params[ 'granularity' ]}", $params[ 'previous_start' ] ) );
|
712 |
+
|
713 |
+
$output[ 'keys' ][ $v1_label ] = $i;
|
714 |
+
$output[ 'keys' ][ $v3_label ] = $i;
|
715 |
+
|
716 |
+
// This is how AmCharts expects the data to be formatted
|
717 |
+
$output[ $i ][ 'v1_label' ] = $v1_label;
|
718 |
+
$output[ $i ][ 'v3_label' ] = $v3_label;
|
719 |
+
$output[ $i ][ 'v4' ] = $output[ $i ][ 'v3' ] = $output[ $i ][ 'v2' ] = $output[ $i ][ 'v1' ] = 0;
|
720 |
+
}
|
721 |
+
|
722 |
+
|
723 |
+
|
724 |
+
// Now populate all the data points
|
725 |
+
foreach ( $results as $a_result ) {
|
726 |
+
$label = date( $params[ 'data_points_label' ], $a_result[ 'dt' ] );
|
727 |
+
|
728 |
+
// Data out of range?
|
729 |
+
if ( !isset( $output[ 'keys' ][ $label ] ) ) {
|
730 |
+
continue;
|
731 |
+
}
|
732 |
+
|
733 |
+
// Does this value belong to the "current" range?
|
734 |
+
if ( $a_result[ 'dt' ] >= self::$filters_normalized[ 'utime' ][ 'start' ] && $a_result[ 'dt' ] <= self::$filters_normalized[ 'utime' ][ 'end' ] ) {
|
735 |
+
$output[ $output[ 'keys' ][ $label ] ][ 'v1' ] = intval( $a_result[ 'v1' ] );
|
736 |
+
$output[ $output[ 'keys' ][ $label ] ][ 'v2' ] = intval( $a_result[ 'v2' ] );
|
737 |
+
}
|
738 |
+
else {
|
739 |
+
$output[ $output[ 'keys' ][ $label ] ][ 'v3' ] = intval( $a_result[ 'v1' ] );
|
740 |
+
$output[ $output[ 'keys' ][ $label ] ][ 'v4' ] = intval( $a_result[ 'v2' ] );
|
741 |
+
}
|
742 |
+
}
|
743 |
+
|
744 |
+
return $output;
|
745 |
+
}
|
746 |
+
|
747 |
+
public static function get_data_size() {
|
748 |
+
$suffix = 'KB';
|
749 |
+
|
750 |
+
$sql = 'SHOW TABLE STATUS LIKE "'.$GLOBALS[ 'wpdb' ]->prefix.'slim_stats"';
|
751 |
+
$table_details = wp_slimstat::$wpdb->get_row( $sql, 'ARRAY_A', 0 );
|
752 |
+
|
753 |
+
$table_size = ( $table_details[ 'Data_length' ] / 1024 ) + ( $table_details[ 'Index_length' ] / 1024 );
|
754 |
+
|
755 |
+
if ( $table_size > 1024 ) {
|
756 |
+
$table_size /= 1024;
|
757 |
+
$suffix = 'MB';
|
758 |
+
}
|
759 |
+
return number_format( $table_size, 2, self::$formats[ 'decimal' ], self::$formats[ 'thousand' ] ).' '.$suffix;
|
760 |
+
}
|
761 |
+
|
762 |
+
public static function get_max_and_average_pages_per_visit() {
|
763 |
+
$where = self::get_combined_where( 'visit_id > 0' );
|
764 |
+
|
765 |
+
return self::get_results( "
|
766 |
+
SELECT AVG(ts1.counthits) AS avghits, MAX(ts1.counthits) AS maxhits FROM (
|
767 |
+
SELECT count(ip) counthits, visit_id
|
768 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
769 |
+
WHERE $where
|
770 |
+
GROUP BY visit_id
|
771 |
+
) AS ts1",
|
772 |
+
'blog_id',
|
773 |
+
'',
|
774 |
+
'',
|
775 |
+
'AVG(avghits) AS avghits, MAX(maxhits) AS maxhits' );
|
776 |
+
}
|
777 |
+
|
778 |
+
public static function get_oldest_visit() {
|
779 |
+
return self::get_var( "
|
780 |
+
SELECT dt
|
781 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
782 |
+
ORDER BY dt ASC
|
783 |
+
LIMIT 0, 1",
|
784 |
+
'MIN(dt)' );
|
785 |
+
}
|
786 |
+
|
787 |
+
public static function get_recent( $_column = 'id', $_where = '', $_having = '', $_use_date_filters = true, $_as_column = '', $_more_columns = '' ) {
|
788 |
+
// This function can be passed individual arguments, or an array of arguments
|
789 |
+
if ( is_array( $_column ) ) {
|
790 |
+
$_where = !empty( $_column[ 'where' ] ) ? $_column[ 'where' ] : '';
|
791 |
+
$_having = !empty( $_column[ 'having' ] ) ? $_column[ 'having' ] : '';
|
792 |
+
$_use_date_filters = !empty( $_column[ 'use_date_filters' ] ) ? $_column[ 'use_date_filters' ] : true;
|
793 |
+
$_as_column = !empty( $_column[ 'as_column' ] ) ? $_column[ 'as_column' ] : '';
|
794 |
+
$_more_columns = !empty( $_column[ 'more_columns' ] ) ? $_column[ 'more_columns' ] : '';
|
795 |
+
$_column = $_column[ 'columns' ];
|
796 |
+
}
|
797 |
+
|
798 |
+
$columns = $_column;
|
799 |
+
if ( !empty( $_as_column ) ) {
|
800 |
+
$columns = "$_column AS $_as_column";
|
801 |
+
}
|
802 |
+
|
803 |
+
if ( $_column != '*' ) {
|
804 |
+
$columns .= ', ip, dt';
|
805 |
+
}
|
806 |
+
else {
|
807 |
+
$columns = 'id, ip, other_ip, username, country, city, location, referer, resource, searchterms, plugins, notes, visit_id, server_latency, page_performance, browser, browser_version, browser_type, platform, language, user_agent, resolution, screen_width, screen_height, content_type, category, author, content_id, outbound_resource, dt_out, dt';
|
808 |
+
}
|
809 |
+
|
810 |
+
if ( !empty( $_more_columns ) ) {
|
811 |
+
$columns .= ', ' . $_more_columns;
|
812 |
+
}
|
813 |
+
|
814 |
+
$_where = self::get_combined_where( $_where, $_column, $_use_date_filters );
|
815 |
+
|
816 |
+
$results = self::get_results( "
|
817 |
+
SELECT $columns
|
818 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
819 |
+
WHERE $_where
|
820 |
+
ORDER BY dt DESC
|
821 |
+
LIMIT 0, " . self::$filters_normalized[ 'misc' ][ 'limit_results' ],
|
822 |
+
$columns,
|
823 |
+
'dt DESC' );
|
824 |
+
|
825 |
+
if ( $_column != '*' ) {
|
826 |
+
$column_values = array_map( 'unserialize', array_unique( array_map( 'serialize', self::array_column( $results, explode( ',', $_column ) ) ) ) );
|
827 |
+
$results = array_intersect_key( $results, $column_values );
|
828 |
+
}
|
829 |
+
|
830 |
+
return $results;
|
831 |
+
}
|
832 |
+
|
833 |
+
public static function get_recent_events() {
|
834 |
+
if ( empty( self::$filters_normalized[ 'columns' ] ) ) {
|
835 |
+
$from = "{$GLOBALS['wpdb']->prefix}slim_events te";
|
836 |
+
$where = wp_slimstat_db::get_combined_where( 'te.type > 1', 'notes' );
|
837 |
+
}
|
838 |
+
else {
|
839 |
+
$from = "{$GLOBALS['wpdb']->prefix}slim_events te INNER JOIN {$GLOBALS['wpdb']->prefix}slim_stats t1 ON te.id = t1.id";
|
840 |
+
$where = wp_slimstat_db::get_combined_where( 'te.type > 1', 'notes', true, 't1' );
|
841 |
+
}
|
842 |
+
|
843 |
+
return self::get_results( "
|
844 |
+
SELECT *
|
845 |
+
FROM $from
|
846 |
+
WHERE $where
|
847 |
+
ORDER BY te.dt DESC"
|
848 |
+
);
|
849 |
+
}
|
850 |
+
|
851 |
+
public static function get_recent_outbound() {
|
852 |
+
$mixed_outbound_resources = self::get_recent( 'outbound_resource' );
|
853 |
+
$clean_outbound_resources = array();
|
854 |
+
|
855 |
+
foreach ( $mixed_outbound_resources as $a_mixed_resource ) {
|
856 |
+
$exploded_resources = explode( ';;;', $a_mixed_resource[ 'outbound_resource' ] );
|
857 |
+
foreach ( $exploded_resources as $a_exploded_resource ) {
|
858 |
+
$a_mixed_resource[ 'outbound_resource' ] = $a_exploded_resource;
|
859 |
+
$clean_outbound_resources[] = $a_mixed_resource;
|
860 |
+
}
|
861 |
+
}
|
862 |
+
|
863 |
+
return $clean_outbound_resources;
|
864 |
+
}
|
865 |
+
|
866 |
+
public static function get_top( $_column = 'id', $_where = '', $_having = '', $_use_date_filters = true, $_as_column = '' ){
|
867 |
+
// This function can be passed individual arguments, or an array of arguments
|
868 |
+
if ( is_array( $_column ) ) {
|
869 |
+
$_where = !empty( $_column[ 'where' ] ) ? $_column[ 'where' ] : '';
|
870 |
+
$_having = !empty( $_column[ 'having' ] ) ? $_column[ 'having' ] : '';
|
871 |
+
$_use_date_filters = !empty( $_column[ 'use_date_filters' ] ) ? $_column[ 'use_date_filters' ] : true;
|
872 |
+
$_as_column = !empty( $_column[ 'as_column' ] ) ? $_column[ 'as_column' ] : '';
|
873 |
+
$_column = $_column[ 'columns' ];
|
874 |
+
}
|
875 |
+
|
876 |
+
if ( !empty( $_as_column ) ) {
|
877 |
+
$_column = "$_column AS $_as_column";
|
878 |
+
}
|
879 |
+
else {
|
880 |
+
$_as_column = $_column;
|
881 |
+
}
|
882 |
+
|
883 |
+
$_where = self::get_combined_where( $_where, $_as_column, $_use_date_filters );
|
884 |
+
|
885 |
+
return self::get_results( "
|
886 |
+
SELECT $_column, COUNT(*) counthits
|
887 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
888 |
+
WHERE $_where
|
889 |
+
GROUP BY $_as_column $_having
|
890 |
+
ORDER BY counthits DESC
|
891 |
+
LIMIT 0, " . self::$filters_normalized[ 'misc' ][ 'limit_results' ],
|
892 |
+
( ( !empty( $_as_column ) && $_as_column != $_column ) ? $_as_column : $_column ),
|
893 |
+
'counthits DESC',
|
894 |
+
( ( !empty( $_as_column ) && $_as_column != $_column ) ? $_as_column : $_column ),
|
895 |
+
'SUM(counthits) AS counthits' );
|
896 |
+
}
|
897 |
+
|
898 |
+
public static function get_top_aggr( $_column = 'id', $_where = '', $_outer_select_column = '', $_aggr_function = 'MAX' ) {
|
899 |
+
if ( is_array( $_column ) ) {
|
900 |
+
$_where = !empty( $_column[ 'where' ] ) ? $_column[ 'where' ] : '';
|
901 |
+
$_having = !empty( $_column[ 'having' ] ) ? $_column[ 'having' ] : '';
|
902 |
+
$_use_date_filters = !empty( $_column[ 'use_date_filters' ] ) ? $_column[ 'use_date_filters' ] : true;
|
903 |
+
$_as_column = !empty( $_column[ 'as_column' ] ) ? $_column[ 'as_column' ] : '';
|
904 |
+
$_outer_select_column = !empty( $_column[ 'outer_select_column' ] ) ? $_column[ 'outer_select_column' ] : '';
|
905 |
+
$_aggr_function = !empty( $_column[ 'aggr_function' ] ) ? $_column[ 'aggr_function' ] : '';
|
906 |
+
$_column = $_column[ 'columns' ];
|
907 |
+
}
|
908 |
+
|
909 |
+
if ( !empty( $_as_column ) ) {
|
910 |
+
$_column = "$_column AS $_as_column";
|
911 |
+
}
|
912 |
+
else {
|
913 |
+
$_as_column = $_column;
|
914 |
+
}
|
915 |
+
|
916 |
+
$_where = self::get_combined_where( $_where, $_column );
|
917 |
+
|
918 |
+
return self::get_results( "
|
919 |
+
SELECT $_outer_select_column, ts1.aggrid as $_column, COUNT(*) counthits
|
920 |
+
FROM (
|
921 |
+
SELECT $_column, $_aggr_function(id) aggrid
|
922 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
923 |
+
WHERE $_where
|
924 |
+
GROUP BY $_column
|
925 |
+
) AS ts1 JOIN {$GLOBALS['wpdb']->prefix}slim_stats t1 ON ts1.aggrid = t1.id
|
926 |
+
GROUP BY $_outer_select_column
|
927 |
+
ORDER BY counthits DESC
|
928 |
+
LIMIT 0, " . self::$filters_normalized[ 'misc' ][ 'limit_results' ],
|
929 |
+
$_outer_select_column,
|
930 |
+
'counthits DESC',
|
931 |
+
$_outer_select_column,
|
932 |
+
"$_aggr_function(aggrid), SUM(counthits)" );
|
933 |
+
}
|
934 |
+
|
935 |
+
public static function get_top_events() {
|
936 |
+
if ( empty( self::$filters_normalized[ 'columns' ] ) ) {
|
937 |
+
$from = "{$GLOBALS['wpdb']->prefix}slim_events te";
|
938 |
+
$where = wp_slimstat_db::get_combined_where( 'te.type > 1', 'notes' );
|
939 |
+
}
|
940 |
+
else {
|
941 |
+
$from = "{$GLOBALS['wpdb']->prefix}slim_events te INNER JOIN {$GLOBALS['wpdb']->prefix}slim_stats t1 ON te.id = t1.id";
|
942 |
+
$where = wp_slimstat_db::get_combined_where( 'te.type > 1', 'notes', true, 't1' );
|
943 |
+
}
|
944 |
+
|
945 |
+
return self::get_results( "
|
946 |
+
SELECT te.notes, te.type, COUNT(*) counthits
|
947 |
+
FROM $from
|
948 |
+
WHERE $where
|
949 |
+
GROUP BY te.notes, te.type
|
950 |
+
ORDER BY counthits DESC"
|
951 |
+
);
|
952 |
+
}
|
953 |
+
|
954 |
+
public static function get_top_outbound() {
|
955 |
+
$mixed_outbound_resources = self::get_recent( 'outbound_resource' );
|
956 |
+
$clean_outbound_resources = array();
|
957 |
+
|
958 |
+
foreach ( $mixed_outbound_resources as $a_mixed_resource ) {
|
959 |
+
$exploded_resources = explode( ';;;', $a_mixed_resource[ 'outbound_resource' ] );
|
960 |
+
foreach ( $exploded_resources as $a_exploded_resource ) {
|
961 |
+
$clean_outbound_resources[] = $a_exploded_resource;
|
962 |
+
}
|
963 |
+
}
|
964 |
+
|
965 |
+
$clean_outbound_resources = array_count_values( $clean_outbound_resources );
|
966 |
+
arsort( $clean_outbound_resources );
|
967 |
+
|
968 |
+
$sorted_outbound_resources = array();
|
969 |
+
foreach ( $clean_outbound_resources as $a_resource => $a_count ) {
|
970 |
+
$sorted_outbound_resources[] = array(
|
971 |
+
'outbound_resource' => $a_resource,
|
972 |
+
'counthits' => $a_count
|
973 |
+
);
|
974 |
+
}
|
975 |
+
|
976 |
+
return $sorted_outbound_resources;
|
977 |
+
}
|
978 |
+
|
979 |
+
protected static function array_column( $input = array(), $columns = array() ) {
|
980 |
+
$output = array();
|
981 |
+
|
982 |
+
foreach ( $input as $a_key => $a_row ) {
|
983 |
+
foreach ( $columns as $a_column ) {
|
984 |
+
$a_column = trim( $a_column );
|
985 |
+
if ( $a_row[ $a_column ] != NULL ) {
|
986 |
+
$output[ $a_key ][ $a_column ] = $a_row[ $a_column ];
|
987 |
+
}
|
988 |
+
}
|
989 |
+
}
|
990 |
+
|
991 |
+
return $output;
|
992 |
+
}
|
993 |
+
|
994 |
+
protected static function count_months_between( $min_timestamp = 0, $max_timestamp = 0 ) {
|
995 |
+
$i = 0;
|
996 |
+
$min_month = date( 'Ym', $min_timestamp );
|
997 |
+
$max_month = date( 'Ym', $max_timestamp );
|
998 |
+
|
999 |
+
while ( $min_month <= $max_month ) {
|
1000 |
+
$min_timestamp = strtotime( "+1 month", $min_timestamp );
|
1001 |
+
$min_month = date( 'Ym', $min_timestamp );
|
1002 |
+
$i++;
|
1003 |
+
}
|
1004 |
+
|
1005 |
+
return $i;
|
1006 |
+
}
|
1007 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin/view/wp-slimstat-reports.php
CHANGED
@@ -1,2197 +1,2192 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class wp_slimstat_reports {
|
4 |
-
|
5 |
-
// Structures to store all the information about what screens and reports are available
|
6 |
-
public static $reports_info = array();
|
7 |
-
public static $user_reports = array();
|
8 |
-
|
9 |
-
// Useful data for the reports
|
10 |
-
protected static $pageviews = 0;
|
11 |
-
|
12 |
-
/**
|
13 |
-
* Initalize class properties
|
14 |
-
*/
|
15 |
-
public static function init(){
|
16 |
-
|
17 |
-
// Include and initialize the API to interact with the database
|
18 |
-
include_once( 'wp-slimstat-db.php' );
|
19 |
-
wp_slimstat_db::init();
|
20 |
-
|
21 |
-
// Retrieve data that will be used by multiple reports
|
22 |
-
self::$pageviews = wp_slimstat_db::count_records();
|
23 |
-
|
24 |
-
// Define all the reports
|
25 |
-
//
|
26 |
-
// Parameters
|
27 |
-
// - title : report name
|
28 |
-
// - callback : function to use to render the report
|
29 |
-
// - callback_args : parameters to pass to the function
|
30 |
-
// - classes : determine the look and feel of this report ( tall, large, extralarge, full-width, hidden )
|
31 |
-
// - screens : where should the report appear ( slimview1, .., slimview4, dashboard )
|
32 |
-
// - tooltip : contextual help to be displayed on hover
|
33 |
-
|
34 |
-
$chart_tooltip = '<strong>' . __( 'Chart controls', 'wp-slimstat' ) . '</strong><ul><li>' . __( 'Use your mouse wheel to zoom in and out', 'wp-slimstat' ) . '</li><li>' . __( 'While zooming in, drag the chart to move to a different area', 'wp-slimstat' ) . '</li></ul>';
|
35 |
-
|
36 |
-
self::$reports_info = array(
|
37 |
-
'slim_p7_02' => array(
|
38 |
-
'title' => __( 'Visitors Activity', 'wp-slimstat' ),
|
39 |
-
'callback' => array( __CLASS__, 'show_activity_log' ),
|
40 |
-
'callback_args' => array(
|
41 |
-
'type' => 'recent',
|
42 |
-
'columns' => '*',
|
43 |
-
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
44 |
-
),
|
45 |
-
'classes' => array( 'full-width', 'tall' ),
|
46 |
-
'screens' => array( 'slimview1', 'dashboard' ),
|
47 |
-
'tooltip' => __( 'Color codes', 'wp-slimstat' ).'</strong><p><span class="little-color-box is-search-engine"></span> '.__( 'From search result page', 'wp-slimstat' ).'</p><p><span class="little-color-box is-known-visitor"></span> '.__( 'Known Visitor', 'wp-slimstat' ).'</p><p><span class="little-color-box is-known-user"></span> '.__( 'Known Users', 'wp-slimstat' ).'</p><p><span class="little-color-box is-direct"></span> '.__( 'Other Humans', 'wp-slimstat' ).'</p><p><span class="little-color-box"></span> '.__( 'Bot or Crawler', 'wp-slimstat' ).'</p>'
|
48 |
-
),
|
49 |
-
|
50 |
-
'slim_p1_01' => array(
|
51 |
-
'title' => __( 'Pageviews', 'wp-slimstat' ),
|
52 |
-
'callback' => array( __CLASS__, 'show_chart' ),
|
53 |
-
'callback_args' => array(
|
54 |
-
'id' => 'slim_p1_01',
|
55 |
-
'chart_data' => array(
|
56 |
-
'data1' => 'COUNT( ip )',
|
57 |
-
'data2' => 'COUNT( DISTINCT ip )'
|
58 |
-
),
|
59 |
-
'chart_labels' => array(
|
60 |
-
__( 'Pageviews', 'wp-slimstat' ),
|
61 |
-
__( 'Unique IPs', 'wp-slimstat' )
|
62 |
-
)
|
63 |
-
),
|
64 |
-
'classes' => array( 'extralarge', 'chart' ),
|
65 |
-
'screens' => array( 'slimview2', 'dashboard' ),
|
66 |
-
'tooltip' => $chart_tooltip
|
67 |
-
),
|
68 |
-
'slim_p1_02' => array(
|
69 |
-
'title' => __( 'About Slimstat', 'wp-slimstat' ),
|
70 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
71 |
-
'callback_args' => array(
|
72 |
-
'raw' => array( __CLASS__, 'get_about_wpslimstat' )
|
73 |
-
),
|
74 |
-
'classes' => array( 'normal', 'hidden' ),
|
75 |
-
'screens' => array( 'slimview2' )
|
76 |
-
),
|
77 |
-
'slim_p1_03' => array(
|
78 |
-
'title' => __( 'Traffic at a Glance', 'wp-slimstat' ),
|
79 |
-
// 'callback' => array( __CLASS__, 'show_overview_summary' ),
|
80 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
81 |
-
'callback_args' => array(
|
82 |
-
'raw' => array( __CLASS__, 'get_overview_summary' )
|
83 |
-
),
|
84 |
-
'classes' => array( 'normal' ),
|
85 |
-
'screens' => array( 'slimview2', 'dashboard' )
|
86 |
-
),
|
87 |
-
'slim_p1_04' => array(
|
88 |
-
'title' => __( 'Currently Online', 'wp-slimstat' ),
|
89 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
90 |
-
'callback_args' => array(
|
91 |
-
'type' => 'recent',
|
92 |
-
'columns' => 'ip',
|
93 |
-
'where' => 'dt_out > '. ( date_i18n( 'U' ) - 300 ) . ' OR dt > '. ( date_i18n( 'U' ) - 300 ),
|
94 |
-
'use_date_filters' => false,
|
95 |
-
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
96 |
-
),
|
97 |
-
'classes' => array( 'normal' ),
|
98 |
-
'screens' => array( 'slimview2', 'dashboard' )
|
99 |
-
),
|
100 |
-
'slim_p1_06' => array(
|
101 |
-
'title' => __( 'Recent Search Terms', 'wp-slimstat' ),
|
102 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
103 |
-
'callback_args' => array(
|
104 |
-
'type' => 'recent',
|
105 |
-
'columns' => 'searchterms',
|
106 |
-
'where' => 'searchterms <> "_" AND searchterms <> "" AND searchterms IS NOT NULL',
|
107 |
-
'more_columns' => 'referer, resource',
|
108 |
-
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
109 |
-
),
|
110 |
-
'classes' => array( 'normal' ),
|
111 |
-
'screens' => array( 'slimview2', 'slimview5' ),
|
112 |
-
'tooltip' => __( 'Keywords used by your visitors to find your website on a search engine.', 'wp-slimstat' )
|
113 |
-
),
|
114 |
-
'slim_p1_08' => array(
|
115 |
-
'title' => __( 'Top Web Pages', 'wp-slimstat' ),
|
116 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
117 |
-
'callback_args' => array(
|
118 |
-
'type' => 'top',
|
119 |
-
'columns' => 'SUBSTRING_INDEX(resource, "' . ( !get_option( 'permalink_structure' ) ? '&' : '?' ) . '", 1)',
|
120 |
-
'as_column' => 'resource_calculated',
|
121 |
-
'filter_op' => 'contains',
|
122 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
123 |
-
),
|
124 |
-
'classes' => array( 'normal' ),
|
125 |
-
'screens' => array( 'slimview2', 'dashboard' ),
|
126 |
-
'tooltip' => __( 'Here a "page" is not just a WordPress page type, but any webpage on your site, including posts, products, categories, and so on. You can set the corresponding filter where Resource Content Type equals cpt:you_cpt_slug_here to get top web pages for a specific custom post type you have.', 'wp-slimstat' )
|
127 |
-
),
|
128 |
-
'slim_p1_10' => array(
|
129 |
-
'title' => __('Top Referring Domains', 'wp-slimstat'),
|
130 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
131 |
-
'callback_args' => array(
|
132 |
-
'type' => 'top',
|
133 |
-
'columns' => 'REPLACE( SUBSTRING_INDEX( ( SUBSTRING_INDEX( ( SUBSTRING_INDEX( referer, "://", -1 ) ), "/", 1 ) ), ".", -5 ), "www.", "" )',
|
134 |
-
'as_column' => 'referer_calculated',
|
135 |
-
'filter_op' => 'contains',
|
136 |
-
'where' => 'referer NOT LIKE "%' . str_replace( 'www.', '', parse_url( home_url(), PHP_URL_HOST ) ) . '%"',
|
137 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
138 |
-
),
|
139 |
-
'classes' => array( 'normal' ),
|
140 |
-
'screens' => array( 'slimview2', 'slimview5', 'dashboard' )
|
141 |
-
),
|
142 |
-
'slim_p1_11' => array(
|
143 |
-
'title' => __( 'Top Known Visitors', 'wp-slimstat' ),
|
144 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
145 |
-
'callback_args' => array(
|
146 |
-
'type' => 'top',
|
147 |
-
'columns' => 'username',
|
148 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
149 |
-
),
|
150 |
-
'classes' => array( 'normal', 'hidden' ),
|
151 |
-
'screens' => array( 'slimview2', 'dashboard' )
|
152 |
-
),
|
153 |
-
'slim_p1_12' => array(
|
154 |
-
'title' => __( 'Top Search Terms', 'wp-slimstat' ),
|
155 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
156 |
-
'callback_args' => array(
|
157 |
-
'type' => 'top',
|
158 |
-
'columns' => 'searchterms',
|
159 |
-
'where' => 'searchterms <> "_" AND searchterms <> "" AND searchterms IS NOT NULL',
|
160 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
161 |
-
),
|
162 |
-
'classes' => array( 'normal' ),
|
163 |
-
'screens' => array( 'slimview2', 'slimview4', 'slimview5', 'dashboard' )
|
164 |
-
),
|
165 |
-
'slim_p1_13' => array(
|
166 |
-
'title' => __( 'Top Countries', 'wp-slimstat' ),
|
167 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
168 |
-
'callback_args' => array(
|
169 |
-
'type' => 'top',
|
170 |
-
'columns' => 'country',
|
171 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
172 |
-
),
|
173 |
-
'classes' => array( 'normal', 'hidden' ),
|
174 |
-
'screens' => array( 'slimview2', 'slimview3', 'slimview5', 'dashboard' ),
|
175 |
-
'tooltip' => __( 'You can configure Slimstat to ignore a specific Country by setting the corresponding filter under Settings > Slimstat > Filters.', 'wp-slimstat' )
|
176 |
-
),
|
177 |
-
'slim_p1_15' => array(
|
178 |
-
'title' => __( 'Rankings', 'wp-slimstat' ),
|
179 |
-
'callback' => array( __CLASS__, 'show_rankings' ),
|
180 |
-
'callback_args' => array(
|
181 |
-
'id' => 'slim_p1_15'
|
182 |
-
),
|
183 |
-
'classes' => array( 'normal', 'hidden' ),
|
184 |
-
'screens' => array( 'slimview2' ),
|
185 |
-
'tooltip' => __( "Slimstat retrieves live information from Alexa, Facebook and Mozscape, to measures your site's rankings. Values are updated every 12 hours. Please enter your personal access ID in the settings to access your personalized Mozscape data.", 'wp-slimstat' )
|
186 |
-
),
|
187 |
-
'slim_p1_17' => array(
|
188 |
-
'title' => __( 'Top Language Families', 'wp-slimstat' ),
|
189 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
190 |
-
'callback_args' => array(
|
191 |
-
'type' => 'top',
|
192 |
-
'columns' => 'SUBSTRING(language, 1, 2)',
|
193 |
-
'as_column' => 'language_calculated',
|
194 |
-
'filter_op' => 'contains',
|
195 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
196 |
-
),
|
197 |
-
'classes' => array( 'normal', 'hidden' ),
|
198 |
-
'screens' => array( 'slimview3' )
|
199 |
-
),
|
200 |
-
'slim_p1_18' => array(
|
201 |
-
'title' => __( 'Users Currently Online', 'wp-slimstat' ),
|
202 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
203 |
-
'callback_args' => array(
|
204 |
-
'type' => 'recent',
|
205 |
-
'columns' => 'username',
|
206 |
-
'where' => 'dt_out > '. ( date_i18n( 'U' ) - 300 ) . ' OR dt > '. ( date_i18n( 'U' ) - 300 ),
|
207 |
-
'use_date_filters' => false,
|
208 |
-
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
209 |
-
),
|
210 |
-
'classes' => array( 'normal', 'hidden' ),
|
211 |
-
'screens' => array( 'slimview2', 'dashboard' ),
|
212 |
-
'tooltip' => __( 'When visitors leave a comment on your blog, WordPress assigns them a cookie. Slimstat leverages this information to identify returning visitors. Please note that visitors also include registered users.', 'wp-slimstat' )
|
213 |
-
),
|
214 |
-
'slim_p1_19_01' => array( // Chart Reports need to always have a _01 suffix to tell our custom "refresh" code to avoid fading the chart, which apparently doesn't work
|
215 |
-
'title' => __( 'Search Terms', 'wp-slimstat' ),
|
216 |
-
'callback' => array( __CLASS__, 'show_chart' ),
|
217 |
-
'callback_args' => array(
|
218 |
-
'id' => 'slim_p1_19_01',
|
219 |
-
'chart_data' => array(
|
220 |
-
'data1' => 'COUNT( searchterms )',
|
221 |
-
'data2' => 'COUNT( DISTINCT searchterms )',
|
222 |
-
'where' => 'searchterms <> "_" AND searchterms IS NOT NULL AND searchterms <> ""'
|
223 |
-
),
|
224 |
-
'chart_labels' => array(
|
225 |
-
__( 'Search Terms', 'wp-slimstat' ),
|
226 |
-
__( 'Unique Terms', 'wp-slimstat' )
|
227 |
-
)
|
228 |
-
),
|
229 |
-
'classes' => array( 'extralarge', 'chart' ),
|
230 |
-
'screens' => array( 'slimview2' ),
|
231 |
-
'tooltip' => $chart_tooltip
|
232 |
-
),
|
233 |
-
'slim_p1_20' => array(
|
234 |
-
'title' => __('Top Referring URLs', 'wp-slimstat'),
|
235 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
236 |
-
'callback_args' => array(
|
237 |
-
'type' => 'top',
|
238 |
-
'columns' => 'referer',
|
239 |
-
'where' => 'referer NOT LIKE "%' . str_replace( 'www.', '', parse_url( home_url(), PHP_URL_HOST ) ) . '%"',
|
240 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
241 |
-
),
|
242 |
-
'classes' => array( 'normal' ),
|
243 |
-
'screens' => array( 'slimview2', 'slimview5', 'dashboard' )
|
244 |
-
),
|
245 |
-
|
246 |
-
'slim_p2_01' => array(
|
247 |
-
'title' => __( 'Human Visits', 'wp-slimstat' ),
|
248 |
-
'callback' => array( __CLASS__, 'show_chart' ),
|
249 |
-
'callback_args' => array(
|
250 |
-
'id' => 'slim_p2_01',
|
251 |
-
'chart_data' => array(
|
252 |
-
'data1' => 'COUNT( DISTINCT visit_id )',
|
253 |
-
'data2' => 'COUNT( DISTINCT ip )',
|
254 |
-
'where' => '(visit_id > 0 AND browser_type <> 1)'
|
255 |
-
),
|
256 |
-
'chart_labels' => array(
|
257 |
-
__( 'Visits', 'wp-slimstat' ),
|
258 |
-
__( 'Unique IPs', 'wp-slimstat' )
|
259 |
-
)
|
260 |
-
),
|
261 |
-
'classes' => array( 'extralarge', 'chart' ),
|
262 |
-
'screens' => array( 'slimview3' ),
|
263 |
-
'tooltip' => $chart_tooltip
|
264 |
-
),
|
265 |
-
'slim_p2_02' => array(
|
266 |
-
'title' => __( 'Audience Overview', 'wp-slimstat' ),
|
267 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
268 |
-
'callback_args' => array(
|
269 |
-
'raw' => array( __CLASS__, 'get_visitors_summary' )
|
270 |
-
),
|
271 |
-
'classes' => array( 'normal' ),
|
272 |
-
'screens' => array( 'slimview3', 'dashboard' ),
|
273 |
-
'tooltip' => __( 'Where not otherwise specified, the metrics in this report are referred to human visitors.', 'wp-slimstat' )
|
274 |
-
),
|
275 |
-
'slim_p2_03' => array(
|
276 |
-
'title' => __( 'Top Languages', 'wp-slimstat' ),
|
277 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
278 |
-
'callback_args' => array(
|
279 |
-
'type' => 'top',
|
280 |
-
'columns' => 'language',
|
281 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
282 |
-
),
|
283 |
-
'classes' => array( 'normal' ),
|
284 |
-
'screens' => array( 'slimview3' )
|
285 |
-
),
|
286 |
-
'slim_p2_04' => array(
|
287 |
-
'title' => __( 'Top Browsers', 'wp-slimstat' ),
|
288 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
289 |
-
'callback_args' => array(
|
290 |
-
'type' => 'top',
|
291 |
-
'columns' => 'browser, browser_version',
|
292 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
293 |
-
),
|
294 |
-
'classes' => array( 'normal' ),
|
295 |
-
'screens' => array( 'slimview3', 'dashboard' )
|
296 |
-
),
|
297 |
-
'slim_p2_05' => array(
|
298 |
-
'title' => __( 'Top Service Providers', 'wp-slimstat' ),
|
299 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
300 |
-
'callback_args' => array(
|
301 |
-
'type' => 'top',
|
302 |
-
'columns' => 'ip',
|
303 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
304 |
-
),
|
305 |
-
'classes' => array( 'extralarge', 'hidden' ),
|
306 |
-
'screens' => array( 'slimview3' ),
|
307 |
-
'tooltip' => __( 'Internet Service Provider: a company which provides other companies or individuals with access to the Internet. Your DSL or cable internet service is provided to you by your ISP.<br><br>You can ignore specific IP addresses by setting the corresponding filter under Settings > Slimstat > Filters.', 'wp-slimstat' )
|
308 |
-
),
|
309 |
-
'slim_p2_06' => array(
|
310 |
-
'title' => __( 'Top Operating Systems', 'wp-slimstat' ),
|
311 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
312 |
-
'callback_args' => array(
|
313 |
-
'type' => 'top',
|
314 |
-
'columns' => 'platform',
|
315 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
316 |
-
),
|
317 |
-
'classes' => array( 'normal', 'hidden' ),
|
318 |
-
'screens' => array( 'slimview3' ),
|
319 |
-
'tooltip' => __( 'Internet Service Provider: a company which provides other companies or individuals with access to the Internet. Your DSL or cable internet service is provided to you by your ISP.<br><br>You can ignore specific IP addresses by setting the corresponding filter under Settings > Slimstat > Filters.', 'wp-slimstat' )
|
320 |
-
),
|
321 |
-
'slim_p2_07' => array(
|
322 |
-
'title' => __( 'Top Screen Resolutions', 'wp-slimstat' ),
|
323 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
324 |
-
'callback_args' => array(
|
325 |
-
'type' => 'top',
|
326 |
-
'columns' => 'screen_width, screen_height',
|
327 |
-
'where' => 'screen_width <> 0 AND screen_height <> 0',
|
328 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
329 |
-
),
|
330 |
-
'classes' => array( 'normal' ),
|
331 |
-
'screens' => array( 'slimview3', 'dashboard' )
|
332 |
-
),
|
333 |
-
'slim_p2_08' => array(
|
334 |
-
'title' => __( 'Top Viewport Sizes', 'wp-slimstat' ),
|
335 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
336 |
-
'callback_args' => array(
|
337 |
-
'type' => 'top',
|
338 |
-
'columns' => 'resolution',
|
339 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
340 |
-
),
|
341 |
-
'classes' => array( 'normal', 'hidden' ),
|
342 |
-
'screens' => array( 'slimview3' )
|
343 |
-
),
|
344 |
-
'slim_p2_09' => array(
|
345 |
-
'title' => __( 'Browser Capabilities', 'wp-slimstat' ),
|
346 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
347 |
-
'callback_args' => array(
|
348 |
-
'raw' => array( __CLASS__, 'get_plugins' )
|
349 |
-
),
|
350 |
-
'classes' => array( 'normal', 'hidden' ),
|
351 |
-
'screens' => array( 'slimview3' )
|
352 |
-
),
|
353 |
-
'slim_p2_12' => array(
|
354 |
-
'title' => __( 'Visit Duration', 'wp-slimstat' ),
|
355 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
356 |
-
'callback_args' => array(
|
357 |
-
'raw' => array( __CLASS__, 'get_visits_duration' )
|
358 |
-
),
|
359 |
-
'classes' => array( 'normal', 'hidden' ),
|
360 |
-
'screens' => array( 'slimview3' ),
|
361 |
-
'tooltip' => __( 'All values represent the percentages of pageviews within the corresponding time range.', 'wp-slimstat' )
|
362 |
-
),
|
363 |
-
'slim_p2_13' => array(
|
364 |
-
'title' => __( 'Recent Countries', 'wp-slimstat' ),
|
365 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
366 |
-
'callback_args' => array(
|
367 |
-
'type' => 'recent',
|
368 |
-
'columns' => 'country',
|
369 |
-
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
370 |
-
),
|
371 |
-
'classes' => array( 'normal', 'hidden' ),
|
372 |
-
'screens' => array( 'slimview3', 'slimview5' )
|
373 |
-
),
|
374 |
-
'slim_p2_14' => array(
|
375 |
-
'title' => __( 'Recent Viewport Sizes', 'wp-slimstat' ),
|
376 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
377 |
-
'callback_args' => array(
|
378 |
-
'type' => 'recent',
|
379 |
-
'columns' => 'resolution',
|
380 |
-
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
381 |
-
),
|
382 |
-
'classes' => array( 'normal', 'hidden' ),
|
383 |
-
'screens' => array( 'slimview3' )
|
384 |
-
),
|
385 |
-
'slim_p2_15' => array(
|
386 |
-
'title' => __( 'Recent Operating Systems', 'wp-slimstat' ),
|
387 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
388 |
-
'callback_args' => array(
|
389 |
-
'type' => 'recent',
|
390 |
-
'columns' => 'platform',
|
391 |
-
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
392 |
-
),
|
393 |
-
'classes' => array( 'normal', 'hidden' ),
|
394 |
-
'screens' => array( 'slimview3' )
|
395 |
-
),
|
396 |
-
'slim_p2_16' => array(
|
397 |
-
'title' => __( 'Recent Browsers', 'wp-slimstat' ),
|
398 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
399 |
-
'callback_args' => array(
|
400 |
-
'type' => 'recent',
|
401 |
-
'columns' => 'browser, browser_version',
|
402 |
-
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
403 |
-
),
|
404 |
-
'classes' => array( 'normal', 'hidden' ),
|
405 |
-
'screens' => array( 'slimview3' )
|
406 |
-
),
|
407 |
-
'slim_p2_17' => array(
|
408 |
-
'title' => __( 'Recent Languages', 'wp-slimstat' ),
|
409 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
410 |
-
'callback_args' => array(
|
411 |
-
'type' => 'recent',
|
412 |
-
'columns' => 'language',
|
413 |
-
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
414 |
-
),
|
415 |
-
'classes' => array( 'normal', 'hidden' ),
|
416 |
-
'screens' => array( 'slimview3' )
|
417 |
-
),
|
418 |
-
'slim_p2_18' => array(
|
419 |
-
'title' => __( 'Top Browser Families', 'wp-slimstat' ),
|
420 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
421 |
-
'callback_args' => array(
|
422 |
-
'type' => 'top',
|
423 |
-
'columns' => 'browser',
|
424 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
425 |
-
),
|
426 |
-
'classes' => array( 'normal', 'hidden' ),
|
427 |
-
'screens' => array( 'slimview3' ),
|
428 |
-
'tooltip' => __( 'This report shows you what user agent families (no version considered) are popular among your visitors.', 'wp-slimstat' )
|
429 |
-
),
|
430 |
-
'slim_p2_19' => array(
|
431 |
-
'title' => __( 'Top OS Families', 'wp-slimstat' ),
|
432 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
433 |
-
'callback_args' => array(
|
434 |
-
'type' => 'top',
|
435 |
-
'columns' => 'CONCAT("p-", SUBSTRING(platform, 1, 3))',
|
436 |
-
'as_column' => 'platform_calculated',
|
437 |
-
'filter_op' => 'contains',
|
438 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
439 |
-
),
|
440 |
-
'classes' => array( 'normal' ),
|
441 |
-
'screens' => array( 'slimview3' ),
|
442 |
-
'tooltip' => __( 'This report shows you what operating system families (no version considered) are popular among your visitors.', 'wp-slimstat' )
|
443 |
-
),
|
444 |
-
'slim_p2_20' => array(
|
445 |
-
'title' => __( 'Recent Users', 'wp-slimstat' ),
|
446 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
447 |
-
'callback_args' => array(
|
448 |
-
'type' => 'recent',
|
449 |
-
'columns' => 'username',
|
450 |
-
'where' => 'notes LIKE "%user:%"',
|
451 |
-
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
452 |
-
),
|
453 |
-
'classes' => array( 'normal' ),
|
454 |
-
'screens' => array( 'slimview3' )
|
455 |
-
),
|
456 |
-
'slim_p2_21' => array(
|
457 |
-
'title' => __( 'Top Users', 'wp-slimstat' ),
|
458 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
459 |
-
'callback_args' => array(
|
460 |
-
'type' => 'top',
|
461 |
-
'columns' => 'username',
|
462 |
-
'where' => 'notes LIKE "%user:%"',
|
463 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
464 |
-
),
|
465 |
-
'classes' => array( 'normal', 'hidden' ),
|
466 |
-
'screens' => array( 'slimview3', 'dashboard' )
|
467 |
-
),
|
468 |
-
'slim_p2_22_01' => array( // Chart Reports need to always have a _01 suffix to tell our custom "refresh" code to avoid fading the chart, which apparently doesn't work
|
469 |
-
'title' => __( 'Users', 'wp-slimstat' ),
|
470 |
-
'callback' => array( __CLASS__, 'show_chart' ),
|
471 |
-
'callback_args' => array(
|
472 |
-
'id' => 'slim_p2_22_01',
|
473 |
-
'chart_data' => array(
|
474 |
-
'data1' => 'COUNT( username )',
|
475 |
-
'data2' => 'COUNT( DISTINCT username )'
|
476 |
-
),
|
477 |
-
'chart_labels' => array(
|
478 |
-
__( 'Users', 'wp-slimstat' ),
|
479 |
-
__( 'Unique Users', 'wp-slimstat' )
|
480 |
-
)
|
481 |
-
),
|
482 |
-
'classes' => array( 'extralarge', 'chart' ),
|
483 |
-
'screens' => array( 'slimview3' ),
|
484 |
-
'tooltip' => $chart_tooltip
|
485 |
-
),
|
486 |
-
|
487 |
-
'slim_p3_01' => array(
|
488 |
-
'title' => __( 'Traffic Sources', 'wp-slimstat' ),
|
489 |
-
'callback' => array( __CLASS__, 'show_chart' ),
|
490 |
-
'callback_args' => array(
|
491 |
-
'id' => 'slim_p3_01',
|
492 |
-
'chart_data' => array(
|
493 |
-
'data1' => 'COUNT( DISTINCT referer )',
|
494 |
-
'data2' => 'COUNT( DISTINCT ip )',
|
495 |
-
'where' => '(referer IS NOT NULL AND referer NOT LIKE "%' . home_url() . '%")'
|
496 |
-
),
|
497 |
-
'chart_labels' => array(
|
498 |
-
__( 'Domains', 'wp-slimstat' ),
|
499 |
-
__( 'Unique IPs', 'wp-slimstat' )
|
500 |
-
)
|
501 |
-
),
|
502 |
-
'classes' => array( 'extralarge', 'chart' ),
|
503 |
-
'screens' => array( 'slimview5' ),
|
504 |
-
'tooltip' => $chart_tooltip
|
505 |
-
),
|
506 |
-
'slim_p3_02' => array(
|
507 |
-
'title' => __( 'Traffic Summary', 'wp-slimstat' ),
|
508 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
509 |
-
'callback_args' => array(
|
510 |
-
'raw' => array( __CLASS__, 'get_traffic_sources_summary' )
|
511 |
-
),
|
512 |
-
'classes' => array( 'normal' ),
|
513 |
-
'screens' => array( 'slimview5' )
|
514 |
-
),
|
515 |
-
'slim_p3_06' => array(
|
516 |
-
'title' => __( 'Top Referring Search Engines', 'wp-slimstat' ),
|
517 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
518 |
-
'callback_args' => array(
|
519 |
-
'type' => 'top',
|
520 |
-
'columns' => 'REPLACE( SUBSTRING_INDEX( SUBSTRING_INDEX( SUBSTRING_INDEX( referer, "://", -1 ), "/", 1 ), ".", -5 ), "www.", "" )',
|
521 |
-
'as_column' => 'referer_calculated',
|
522 |
-
'filter_op' => 'contains',
|
523 |
-
'where' => 'searchterms IS NOT NULL AND searchterms <> "" AND searchterms <> "_" AND referer NOT LIKE "%' . str_replace( 'www.', '', parse_url( home_url(), PHP_URL_HOST ) ) . '%"',
|
524 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
525 |
-
),
|
526 |
-
'classes' => array( 'normal' ),
|
527 |
-
'screens' => array( 'slimview5', 'dashboard' )
|
528 |
-
),
|
529 |
-
|
530 |
-
'slim_p4_01' => array(
|
531 |
-
'title' => __( 'Recent Outbound Links', 'wp-slimstat' ),
|
532 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
533 |
-
'callback_args' => array(
|
534 |
-
'type' => 'recent',
|
535 |
-
'columns' => 'outbound_resource',
|
536 |
-
'raw' => array( 'wp_slimstat_db', 'get_recent_outbound' )
|
537 |
-
),
|
538 |
-
'classes' => array( 'large' ),
|
539 |
-
'screens' => array( 'slimview4' ),
|
540 |
-
'tooltip' => ''
|
541 |
-
),
|
542 |
-
'slim_p4_02' => array(
|
543 |
-
'title' => __( 'Recent Posts', 'wp-slimstat' ),
|
544 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
545 |
-
'callback_args' => array(
|
546 |
-
'type' => 'recent',
|
547 |
-
'columns' => 'resource',
|
548 |
-
'where' => 'content_type = "post"',
|
549 |
-
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
550 |
-
),
|
551 |
-
'classes' => array( 'normal' ),
|
552 |
-
'screens' => array( 'slimview4' )
|
553 |
-
),
|
554 |
-
'slim_p4_04' => array(
|
555 |
-
'title' => __( 'Recent Feeds', 'wp-slimstat' ),
|
556 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
557 |
-
'callback_args' => array(
|
558 |
-
'type' => 'recent',
|
559 |
-
'columns' => 'resource',
|
560 |
-
'where' => '(resource LIKE "%/feed%" OR resource LIKE "%?feed=>%" OR resource LIKE "%&feed=>%" OR content_type LIKE "%feed%")',
|
561 |
-
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
562 |
-
),
|
563 |
-
'classes' => array( 'normal', 'hidden' ),
|
564 |
-
'screens' => array( 'slimview4' )
|
565 |
-
),
|
566 |
-
'slim_p4_05' => array(
|
567 |
-
'title' => __( 'Recent Pages Not Found', 'wp-slimstat' ),
|
568 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
569 |
-
'callback_args' => array(
|
570 |
-
'type' => 'recent',
|
571 |
-
'columns' => 'resource',
|
572 |
-
'where' => '(resource LIKE "[404]%" OR content_type LIKE "%404%")',
|
573 |
-
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
574 |
-
),
|
575 |
-
'classes' => array( 'normal' ),
|
576 |
-
'screens' => array( 'slimview4' )
|
577 |
-
),
|
578 |
-
'slim_p4_06' => array(
|
579 |
-
'title' => __( 'Recent Internal Searches', 'wp-slimstat' ),
|
580 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
581 |
-
'callback_args' => array(
|
582 |
-
'type' => 'recent',
|
583 |
-
'columns' => 'searchterms',
|
584 |
-
'where' => 'content_type LIKE "%search%" AND searchterms <> "" AND searchterms IS NOT NULL',
|
585 |
-
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
586 |
-
),
|
587 |
-
'classes' => array( 'normal', 'hidden' ),
|
588 |
-
'screens' => array( 'slimview4' ),
|
589 |
-
'tooltip' => __( "Searches performed using WordPress' built-in search functionality.", 'wp-slimstat' )
|
590 |
-
),
|
591 |
-
'slim_p4_07' => array(
|
592 |
-
'title' => __( 'Top Categories', 'wp-slimstat' ),
|
593 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
594 |
-
'callback_args' => array(
|
595 |
-
'type' => 'top',
|
596 |
-
'columns' => 'category',
|
597 |
-
'where' => 'content_type LIKE "%category%"',
|
598 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
599 |
-
),
|
600 |
-
'classes' => array( 'normal' ),
|
601 |
-
'screens' => array( 'slimview4', 'dashboard' )
|
602 |
-
),
|
603 |
-
|
604 |
-
'slim_p4_09' => array(
|
605 |
-
'title' => __( 'Top Downloads', 'wp-slimstat' ),
|
606 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
607 |
-
'callback_args' => array(
|
608 |
-
'type' => 'top',
|
609 |
-
'columns' => 'resource',
|
610 |
-
'where' => 'content_type = "download"',
|
611 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' ),
|
612 |
-
'criteria' => 'swap'
|
613 |
-
),
|
614 |
-
'classes' => array( 'large', 'hidden' ),
|
615 |
-
'screens' => array( 'slimview4' ),
|
616 |
-
'tooltip' => __( 'You can configure Slimstat to track specific file extensions as downloads.', 'wp-slimstat' )
|
617 |
-
),
|
618 |
-
'slim_p4_10' => array(
|
619 |
-
'title' => __( 'Recent Events', 'wp-slimstat' ),
|
620 |
-
'callback' => array( __CLASS__, 'show_events' ),
|
621 |
-
'callback_args' => array(
|
622 |
-
'type' => 'recent',
|
623 |
-
'columns' => 'notes',
|
624 |
-
'raw' => array( 'wp_slimstat_db', 'get_recent_events' )
|
625 |
-
),
|
626 |
-
'classes' => array( 'normal', 'hidden' ),
|
627 |
-
'screens' => array( 'slimview4' ),
|
628 |
-
'tooltip' => __( 'This report lists any <em>event</em> occurred on your website. Please refer to the FAQ for more information on how to use this functionality.', 'wp-slimstat' )
|
629 |
-
),
|
630 |
-
'slim_p4_11' => array(
|
631 |
-
'title' => __( 'Top Posts', 'wp-slimstat' ),
|
632 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
633 |
-
'callback_args' => array(
|
634 |
-
'type' => 'top',
|
635 |
-
'columns' => 'resource',
|
636 |
-
'where' => 'content_type = "post"',
|
637 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
638 |
-
),
|
639 |
-
'classes' => array( 'normal' ),
|
640 |
-
'screens' => array( 'slimview4' )
|
641 |
-
),
|
642 |
-
'slim_p4_12' => array(
|
643 |
-
'title' => __( 'Top Events', 'wp-slimstat' ),
|
644 |
-
'callback' => array( __CLASS__, 'show_events' ),
|
645 |
-
'callback_args' => array(
|
646 |
-
'type' => 'top',
|
647 |
-
'columns' => 'notes',
|
648 |
-
'raw' => array( 'wp_slimstat_db', 'get_top_events' )
|
649 |
-
),
|
650 |
-
'classes' => array( 'normal', 'hidden' ),
|
651 |
-
'screens' => array( 'slimview4' ),
|
652 |
-
'tooltip' => __( 'This report lists any <em>event</em> occurred on your website. Please refer to the FAQ for more information on how to use this functionality.', 'wp-slimstat' )
|
653 |
-
),
|
654 |
-
'slim_p4_13' => array(
|
655 |
-
'title' => __( 'Top Internal Searches', 'wp-slimstat' ),
|
656 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
657 |
-
'callback_args' => array(
|
658 |
-
'type' => 'top',
|
659 |
-
'columns' => 'searchterms',
|
660 |
-
'where' => 'content_type LIKE "%search%" AND searchterms <> "" AND searchterms IS NOT NULL',
|
661 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
662 |
-
),
|
663 |
-
'classes' => array( 'normal', 'hidden' ),
|
664 |
-
'screens' => array( 'slimview4' )
|
665 |
-
),
|
666 |
-
'slim_p4_15' => array(
|
667 |
-
'title' => __( 'Recent Categories', 'wp-slimstat' ),
|
668 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
669 |
-
'callback_args' => array(
|
670 |
-
'type' => 'recent',
|
671 |
-
'columns' => 'resource',
|
672 |
-
'where' => '(content_type = "category" OR content_type = "tag")',
|
673 |
-
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
674 |
-
),
|
675 |
-
'classes' => array( 'normal', 'hidden' ),
|
676 |
-
'screens' => array( 'slimview4' )
|
677 |
-
),
|
678 |
-
'slim_p4_16' => array(
|
679 |
-
'title' => __( 'Top Pages Not Found', 'wp-slimstat' ),
|
680 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
681 |
-
'callback_args' => array(
|
682 |
-
'type' => 'top',
|
683 |
-
'columns' => 'resource',
|
684 |
-
'where' => 'content_type LIKE "%404%"',
|
685 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
686 |
-
),
|
687 |
-
'classes' => array( 'normal' ),
|
688 |
-
'screens' => array( 'slimview4' )
|
689 |
-
),
|
690 |
-
'slim_p4_18' => array(
|
691 |
-
'title' => __( 'Top Authors', 'wp-slimstat' ),
|
692 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
693 |
-
'callback_args' => array(
|
694 |
-
'type' => 'top',
|
695 |
-
'columns' => 'author',
|
696 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
697 |
-
),
|
698 |
-
'classes' => array( 'normal' ),
|
699 |
-
'screens' => array( 'slimview4', 'dashboard' )
|
700 |
-
),
|
701 |
-
'slim_p4_19' => array(
|
702 |
-
'title' => __( 'Top Tags', 'wp-slimstat' ),
|
703 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
704 |
-
'callback_args' => array(
|
705 |
-
'type' => 'top',
|
706 |
-
'columns' => 'category',
|
707 |
-
'where' => '(content_type LIKE "%tag%")',
|
708 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
709 |
-
),
|
710 |
-
'classes' => array( 'normal', 'hidden' ),
|
711 |
-
'screens' => array( 'slimview4' )
|
712 |
-
),
|
713 |
-
'slim_p4_20' => array(
|
714 |
-
'title' => __( 'Recent Downloads', 'wp-slimstat' ),
|
715 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
716 |
-
'callback_args' => array(
|
717 |
-
'type' => 'recent',
|
718 |
-
'columns' => 'resource',
|
719 |
-
'where' => 'content_type = "download"',
|
720 |
-
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
721 |
-
),
|
722 |
-
'classes' => array( 'large', 'hidden' ),
|
723 |
-
'screens' => array( 'slimview4' )
|
724 |
-
),
|
725 |
-
'slim_p4_21' => array(
|
726 |
-
'title' => __( 'Top Outbound Links', 'wp-slimstat' ),
|
727 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
728 |
-
'callback_args' => array(
|
729 |
-
'type' => 'top',
|
730 |
-
'columns' => 'outbound_resource',
|
731 |
-
'raw' => array( 'wp_slimstat_db', 'get_top_outbound' ),
|
732 |
-
'criteria' => 'swap'
|
733 |
-
),
|
734 |
-
'classes' => array( 'normal', 'hidden' ),
|
735 |
-
'screens' => array( 'slimview4', 'dashboard' ),
|
736 |
-
),
|
737 |
-
'slim_p4_22' => array(
|
738 |
-
'title' => __( 'Your Website', 'wp-slimstat' ),
|
739 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
740 |
-
'callback_args' => array(
|
741 |
-
'raw' => array( __CLASS__, 'get_your_blog' )
|
742 |
-
),
|
743 |
-
'classes' => array( 'normal', 'hidden' ),
|
744 |
-
'screens' => array( 'slimview4' ),
|
745 |
-
'tooltip' => __( 'Your content at a glance: posts, comments, pingbacks, etc. Please note that this report is not affected by the filters set here above.', 'wp-slimstat' )
|
746 |
-
),
|
747 |
-
'slim_p4_23' => array(
|
748 |
-
'title' => __( 'Top Bounce Pages', 'wp-slimstat' ),
|
749 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
750 |
-
'callback_args' => array(
|
751 |
-
'type' => 'top',
|
752 |
-
'columns' => 'resource',
|
753 |
-
'where' => 'content_type <> "404"',
|
754 |
-
'having' => 'HAVING COUNT(visit_id) = 1',
|
755 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
756 |
-
),
|
757 |
-
'classes' => array( 'normal', 'hidden' ),
|
758 |
-
'screens' => array( 'slimview4' )
|
759 |
-
),
|
760 |
-
'slim_p4_24' => array(
|
761 |
-
'title' => __( 'Top Exit Pages', 'wp-slimstat' ),
|
762 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
763 |
-
'callback_args' => array(
|
764 |
-
'type' => 'top',
|
765 |
-
'columns' => 'visit_id',
|
766 |
-
'outer_select_column' => 'resource',
|
767 |
-
'aggr_function' => 'MAX',
|
768 |
-
'raw' => array( 'wp_slimstat_db', 'get_top_aggr' )
|
769 |
-
),
|
770 |
-
'classes' => array( 'large', 'hidden' ),
|
771 |
-
'screens' => array( 'slimview4', 'dashboard' )
|
772 |
-
),
|
773 |
-
'slim_p4_25' => array(
|
774 |
-
'title' => __( 'Top Entry Pages', 'wp-slimstat' ),
|
775 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
776 |
-
'callback_args' => array(
|
777 |
-
'type' => 'top',
|
778 |
-
'columns' => 'visit_id',
|
779 |
-
'outer_select_column' => 'resource',
|
780 |
-
'aggr_function' => 'MIN',
|
781 |
-
'raw' => array( 'wp_slimstat_db', 'get_top_aggr' )
|
782 |
-
),
|
783 |
-
'classes' => array( 'large', 'hidden' ),
|
784 |
-
'screens' => array( 'slimview4' )
|
785 |
-
),
|
786 |
-
'slim_p4_26_01' => array( // Chart Reports need to always have a _01 suffix to tell our custom "refresh" code to avoid fading the chart, which apparently doesn't work
|
787 |
-
'title' => __( 'Pages with Outbound Links', 'wp-slimstat' ),
|
788 |
-
'callback' => array( __CLASS__, 'show_chart' ),
|
789 |
-
'callback_args' => array(
|
790 |
-
'id' => 'slim_p4_26_01',
|
791 |
-
'chart_data' => array(
|
792 |
-
'data1' => 'COUNT( outbound_resource )',
|
793 |
-
'data2' => 'COUNT( DISTINCT outbound_resource )'
|
794 |
-
),
|
795 |
-
'chart_labels' => array(
|
796 |
-
__( 'Outbound Links', 'wp-slimstat' ),
|
797 |
-
__( 'Unique Outbound', 'wp-slimstat' )
|
798 |
-
)
|
799 |
-
),
|
800 |
-
'classes' => array( 'extralarge', 'chart' ),
|
801 |
-
'screens' => array( 'slimview4' ),
|
802 |
-
'tooltip' => $chart_tooltip
|
803 |
-
),
|
804 |
-
|
805 |
-
'slim_p6_01' => array(
|
806 |
-
'title' => __( 'World Map', 'wp-slimstat' ),
|
807 |
-
'callback' => array( __CLASS__, 'show_world_map' ),
|
808 |
-
'callback_args' => array(
|
809 |
-
'id' => 'slim_p6_01'
|
810 |
-
),
|
811 |
-
'classes' => array( 'full-width', 'tall' ),
|
812 |
-
'screens' => array( 'slimview6' ),
|
813 |
-
'tooltip' => __( 'Dots on the map represent the most recent pageviews geolocated by City. This feature is only available by enabling the corresponding precision level in the settings.', 'wp-slimstat' )
|
814 |
-
)
|
815 |
-
);
|
816 |
-
|
817 |
-
if ( wp_slimstat::$settings[ 'geolocation_country' ] != 'on' ) {
|
818 |
-
self::$reports_info [ 'slim_p2_23' ] = array(
|
819 |
-
'title' => __( 'Top Cities', 'wp-slimstat' ),
|
820 |
-
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
821 |
-
'callback_args' => array(
|
822 |
-
'type' => 'top',
|
823 |
-
'columns' => 'city',
|
824 |
-
|
825 |
-
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
826 |
-
),
|
827 |
-
'classes' => array( 'normal' ),
|
828 |
-
'screens' => array( 'slimview3' )
|
829 |
-
);
|
830 |
-
}
|
831 |
-
|
832 |
-
// Allow third party tools to manipulate this list here above: please use unique report IDs that don't interfere with built-in ones, if you add your own custom report
|
833 |
-
self::$reports_info = apply_filters( 'slimstat_reports_info', self::$reports_info );
|
834 |
-
|
835 |
-
// Define what reports have been deprecated over time, to remove them from the user's settings
|
836 |
-
$deprecated_reports = array(
|
837 |
-
'slim_p1_05' => 1,
|
838 |
-
'slim_p1_18' => 1,
|
839 |
-
'slim_p2_10' => 1,
|
840 |
-
'slim_p3_03' => 1,
|
841 |
-
'slim_p3_04' => 1,
|
842 |
-
'slim_p3_05' => 1,
|
843 |
-
'slim_p3_08' => 1,
|
844 |
-
'slim_p3_09' => 1,
|
845 |
-
'slim_p3_10' => 1,
|
846 |
-
'slim_p4_08' => 1,
|
847 |
-
'slim_p4_14' => 1,
|
848 |
-
'slim_p4_17' => 1,
|
849 |
-
'slim_getsocial' => 1
|
850 |
-
);
|
851 |
-
|
852 |
-
// Retrieve this user's list of active reports,
|
853 |
-
$current_user = wp_get_current_user();
|
854 |
-
$page_location = ( wp_slimstat::$settings[ 'use_separate_menu' ] == 'on' ) ? 'slimstat' : 'admin';
|
855 |
-
|
856 |
-
// Superadmins can customize the layout at network level, to override per-site settings
|
857 |
-
self::$user_reports = get_user_option( "meta-box-order_slimstat_page_slimlayout-network", 1 );
|
858 |
-
|
859 |
-
// No network-wide settings exist
|
860 |
-
if ( empty( self::$user_reports ) ) {
|
861 |
-
self::$user_reports = get_user_option( "meta-box-order_slimstat_page_slimlayout", $current_user->ID );
|
862 |
-
}
|
863 |
-
|
864 |
-
// Do this only if we are in one of our screens (no dashboard!)
|
865 |
-
if ( is_admin() && !empty( $_REQUEST[ 'page' ] ) && strpos( $_REQUEST[ 'page' ], 'slimview' ) !== false ) {
|
866 |
-
|
867 |
-
// If this list is not empty, we rearrange the order of our reports
|
868 |
-
if ( !empty( self::$user_reports[ $_REQUEST[ 'page' ] ] ) ) {
|
869 |
-
$user_reports_intersect = array_flip( explode( ',', self::$user_reports[ $_REQUEST[ 'page' ] ] ) );
|
870 |
-
self::$reports_info = array_intersect_key( array_merge( $user_reports_intersect, self::$reports_info ), $user_reports_intersect );
|
871 |
-
}
|
872 |
-
else {
|
873 |
-
foreach ( self::$reports_info as $a_report_id => $a_report_info ) {
|
874 |
-
if ( !in_array( $_REQUEST[ 'page' ], $a_report_info[ 'screens' ] ) ) {
|
875 |
-
unset( self::$reports_info[ $a_report_id ] );
|
876 |
-
}
|
877 |
-
}
|
878 |
-
}
|
879 |
-
|
880 |
-
// Remove deprecated reports
|
881 |
-
self::$reports_info = array_diff_key( self::$reports_info, $deprecated_reports );
|
882 |
-
|
883 |
-
$hidden_reports = get_user_option( "metaboxhidden_{$page_location}_page_{$_REQUEST['page']}", $current_user->ID );
|
884 |
-
|
885 |
-
// If this list is not empty, use it instead of the predefined visibility
|
886 |
-
if ( is_array( $hidden_reports ) ) {
|
887 |
-
foreach ( self::$reports_info as $a_report_id => $a_report_info ) {
|
888 |
-
if ( in_array( $a_report_id, $hidden_reports ) ) {
|
889 |
-
if ( is_array( self::$reports_info[ $a_report_id ][ 'classes' ] ) && !in_array( 'hidden', $a_report_info[ 'classes' ] ) ) {
|
890 |
-
self::$reports_info[ $a_report_id ][ 'classes' ][] = 'hidden';
|
891 |
-
}
|
892 |
-
}
|
893 |
-
else if ( is_array( self::$reports_info[ $a_report_id ][ 'classes' ] ) ) {
|
894 |
-
self::$reports_info[ $a_report_id ][ 'classes' ] = array_diff( self::$reports_info[ $a_report_id ][ 'classes' ], array( 'hidden' ) );
|
895 |
-
}
|
896 |
-
}
|
897 |
-
}
|
898 |
-
}
|
899 |
-
// If we are on the WP Dashboard page, all the reports are 'visible': WP will take care of honoring the Screen Options settings for that page
|
900 |
-
else if ( !empty( $_REQUEST['page'] ) && strpos( $_REQUEST['page'], 'slimlayout' ) === false ) {
|
901 |
-
foreach ( self::$reports_info as $a_report_id => $a_report_info ) {
|
902 |
-
if ( is_array( self::$reports_info[ $a_report_id ][ 'classes' ] ) ) {
|
903 |
-
self::$reports_info[ $a_report_id ][ 'classes' ] = array_diff( self::$reports_info[ $a_report_id ][ 'classes' ], array( 'hidden' ) );
|
904 |
-
}
|
905 |
-
}
|
906 |
-
}
|
907 |
-
}
|
908 |
-
// end init
|
909 |
-
|
910 |
-
public static function report_header( $_report_id = '' ) {
|
911 |
-
if ( empty( self::$reports_info[ $_report_id ] ) ) {
|
912 |
-
return false;
|
913 |
-
}
|
914 |
-
|
915 |
-
$header_classes = !empty( self::$reports_info[ $_report_id ][ 'classes' ] ) ? implode( ' ', self::$reports_info[ $_report_id ][ 'classes' ] ) : '';
|
916 |
-
$header_buttons = '';
|
917 |
-
$header_tooltip = '';
|
918 |
-
|
919 |
-
// Don't show the header buttons on the frontend
|
920 |
-
if ( is_admin() ) {
|
921 |
-
// Show the refresh button only if the time range is not in the past
|
922 |
-
if ( wp_slimstat_db::$filters_normalized[ 'utime' ][ 'end' ] >= date_i18n( 'U' ) - 300 ) {
|
923 |
-
$header_buttons = '<a class="noslimstat refresh slimstat-font-arrows-cw" title="'.__('Refresh','wp-slimstat').'" href="'.self::fs_url().'"></a>';
|
924 |
-
}
|
925 |
-
|
926 |
-
// Allow third-party code to add more buttons
|
927 |
-
$header_buttons = apply_filters( 'slimstat_report_header_buttons', $header_buttons, $_report_id );
|
928 |
-
$header_buttons = '<div class="slimstat-header-buttons">' . $header_buttons . '</div>';
|
929 |
-
$header_tooltip = !empty( self::$reports_info[ $_report_id ][ 'tooltip' ] ) ? '<i class="slimstat-tooltip-trigger corner"><span class="slimstat-tooltip-content">' . self::$reports_info[ $_report_id ][ 'tooltip' ] . '</span></i>' : '';
|
930 |
-
}
|
931 |
-
|
932 |
-
echo "<div class='postbox $header_classes' id='$_report_id'>{$header_buttons} <h3 data-report-id='{$_report_id}'>" . self::$reports_info[ $_report_id ][ 'title' ] . " {$header_tooltip}</h3><div class='inside'>";
|
933 |
-
}
|
934 |
-
|
935 |
-
public static function report_footer(){
|
936 |
-
echo '</div></div>';
|
937 |
-
}
|
938 |
-
|
939 |
-
public static function report_pagination( $_count_page_results = 0, $_count_all_results = 0, $_show_refresh_countdown = false, $_results_per_page = -1 ) {
|
940 |
-
if ( !is_admin() ) {
|
941 |
-
return '';
|
942 |
-
}
|
943 |
-
|
944 |
-
$_results_per_page = ( $_results_per_page < 0 ) ? wp_slimstat::$settings[ 'rows_to_show' ] : $_results_per_page;
|
945 |
-
|
946 |
-
$endpoint = min( $_count_all_results, wp_slimstat_db::$filters_normalized[ 'misc' ][ 'start_from' ] + $_results_per_page );
|
947 |
-
$pagination_buttons = '';
|
948 |
-
$direction_prev = is_rtl() ? 'right' : 'left';
|
949 |
-
$direction_next = is_rtl() ? 'left' : 'right';
|
950 |
-
|
951 |
-
if ( $endpoint + $_results_per_page < $_count_all_results && $_count_page_results > 0 ) {
|
952 |
-
$startpoint = $_count_all_results - $_count_all_results % $_results_per_page;
|
953 |
-
if ( $startpoint == $_count_all_results ) {
|
954 |
-
$startpoint -= $_results_per_page;
|
955 |
-
}
|
956 |
-
$pagination_buttons .= '<a class="refresh slimstat-font-angle-double-' . $direction_next . '" href="' . wp_slimstat_reports::fs_url( 'start_from equals ' . $startpoint ) . '"></a> ';
|
957 |
-
}
|
958 |
-
if ($endpoint < $_count_all_results && $_count_page_results > 0){
|
959 |
-
$startpoint = wp_slimstat_db::$filters_normalized['misc']['start_from'] + $_results_per_page;
|
960 |
-
$pagination_buttons .= '<a class="refresh slimstat-font-angle-'.$direction_next.'" href="' . wp_slimstat_reports::fs_url( 'start_from equals ' . $startpoint ) . '"></a> ';
|
961 |
-
}
|
962 |
-
if (wp_slimstat_db::$filters_normalized['misc']['start_from'] > 0){
|
963 |
-
$startpoint = (wp_slimstat_db::$filters_normalized['misc']['start_from'] > $_results_per_page)?wp_slimstat_db::$filters_normalized['misc']['start_from'] - $_results_per_page : 0;
|
964 |
-
$pagination_buttons .= '<a class="refresh slimstat-font-angle-'.$direction_prev.'" href="'.wp_slimstat_reports::fs_url('start_from equals '.$startpoint).'"></a> ';
|
965 |
-
}
|
966 |
-
if (wp_slimstat_db::$filters_normalized['misc']['start_from'] - $_results_per_page > 0){
|
967 |
-
$pagination_buttons .= '<a class="refresh slimstat-font-angle-double-'.$direction_prev.'" href="'.wp_slimstat_reports::fs_url('start_from equals 0').'"></a> ';
|
968 |
-
}
|
969 |
-
|
970 |
-
$pagination = '<p class="pagination">' . sprintf( __( 'Results %s - %s of %s', 'wp-slimstat' ), number_format( wp_slimstat_db::$filters_normalized[ 'misc' ][ 'start_from' ] + 1, 0, '', wp_slimstat_db::$formats[ 'thousand' ] ), number_format( $endpoint, 0, '', wp_slimstat_db::$formats[ 'thousand' ] ), number_format( $_count_all_results, 0, '', wp_slimstat_db::$formats[ 'thousand' ] ) . ( ( $_count_all_results == wp_slimstat::$settings[ 'limit_results' ] ) ? '+' : '') );
|
971 |
-
|
972 |
-
if ( $_show_refresh_countdown && wp_slimstat::$settings[ 'refresh_interval' ] > 0 && wp_slimstat_db::$filters_normalized[ 'utime' ][ 'end' ] >= date_i18n( 'U' ) - 300 ) {
|
973 |
-
$pagination .= ' [' . __( 'Refresh in', 'wp-slimstat' ) . ' <i class="refresh-timer"></i>]';
|
974 |
-
}
|
975 |
-
$pagination .= $pagination_buttons.'</p>';
|
976 |
-
|
977 |
-
return $pagination;
|
978 |
-
}
|
979 |
-
|
980 |
-
public static function callback_wrapper() {
|
981 |
-
$_args = self::_check_args( func_get_args() );
|
982 |
-
call_user_func( $_args[ 'callback' ] , $_args[ 'callback_args' ] );
|
983 |
-
}
|
984 |
-
|
985 |
-
public static function raw_results_to_html( $_args = array() ) {
|
986 |
-
if ( wp_slimstat::$settings[ 'async_load' ] == 'on' && ( !defined( 'DOING_AJAX' ) || !DOING_AJAX ) ) {
|
987 |
-
return '';
|
988 |
-
}
|
989 |
-
|
990 |
-
wp_slimstat_db::$debug_message = '';
|
991 |
-
|
992 |
-
$all_results = call_user_func( $_args[ 'raw' ] , $_args );
|
993 |
-
|
994 |
-
echo wp_slimstat_db::$debug_message;
|
995 |
-
|
996 |
-
// Some reports don't need any kind of pre/post-processing, we just display the data contained in the array
|
997 |
-
if ( empty( $_args[ 'columns' ] ) ) {
|
998 |
-
foreach ( $all_results as $a_result ) {
|
999 |
-
echo '<p>';
|
1000 |
-
|
1001 |
-
if ( !empty( $a_result[ 'tooltip' ] ) ) {
|
1002 |
-
self::inline_help( $a_result[ 'tooltip' ] );
|
1003 |
-
}
|
1004 |
-
|
1005 |
-
echo "{$a_result[ 'metric' ]} <span>{$a_result[ 'value' ]}</span>";
|
1006 |
-
|
1007 |
-
if ( !empty( $a_result[ 'details' ] ) ) {
|
1008 |
-
$is_expanded = ( wp_slimstat::$settings[ 'expand_details' ] == 'on' ) ? ' expanded' : '';
|
1009 |
-
echo "<b class='slimstat-tooltip-content$is_expanded'>{$a_result[ 'details' ]}</b>";
|
1010 |
-
}
|
1011 |
-
|
1012 |
-
echo '</p>';
|
1013 |
-
}
|
1014 |
-
}
|
1015 |
-
else {
|
1016 |
-
$results = array_slice(
|
1017 |
-
$all_results,
|
1018 |
-
wp_slimstat_db::$filters_normalized[ 'misc' ][ 'start_from' ],
|
1019 |
-
wp_slimstat::$settings[ 'rows_to_show' ]
|
1020 |
-
);
|
1021 |
-
|
1022 |
-
// Count the results
|
1023 |
-
$count_page_results = count( $results );
|
1024 |
-
|
1025 |
-
if ($count_page_results == 0){
|
1026 |
-
echo '<p class="nodata">' . __( 'No data to display', 'wp-slimstat' ) . '</p>';
|
1027 |
-
|
1028 |
-
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
1029 |
-
die();
|
1030 |
-
}
|
1031 |
-
else{
|
1032 |
-
return array();
|
1033 |
-
}
|
1034 |
-
}
|
1035 |
-
|
1036 |
-
// Some reports use aliases for column names
|
1037 |
-
if ( !empty( $_args[ 'as_column' ] ) ) {
|
1038 |
-
$_args[ 'columns' ] = $_args[ 'as_column' ];
|
1039 |
-
}
|
1040 |
-
else if ( !empty( $_args[ 'outer_select_column' ] ) ) {
|
1041 |
-
$_args[ 'columns' ] = $_args[ 'outer_select_column' ];
|
1042 |
-
}
|
1043 |
-
|
1044 |
-
// Some reports query more than one column
|
1045 |
-
if ( strpos( $_args[ 'columns' ], ',' ) !== false ) {
|
1046 |
-
$_args[ 'columns' ] = explode( ',', $_args[ 'columns' ] );
|
1047 |
-
$_args[ 'columns' ] = trim( $_args[ 'columns' ][ 0 ] );
|
1048 |
-
}
|
1049 |
-
|
1050 |
-
echo self::report_pagination( $count_page_results, count( $all_results ) );
|
1051 |
-
|
1052 |
-
$is_expanded = ( is_admin() && wp_slimstat::$settings[ 'expand_details' ] == 'on' ) ? ' expanded' : '';
|
1053 |
-
$permalinks_enabled = get_option( 'permalink_structure' );
|
1054 |
-
$column_not_calculated = str_replace( '_calculated', '', $_args[ 'columns' ] );
|
1055 |
-
|
1056 |
-
for($i=0; $i<$count_page_results; $i++){
|
1057 |
-
$row_details = $percentage = '';
|
1058 |
-
$element_pre_value = '';
|
1059 |
-
$element_value = $results[ $i ][ $_args[ 'columns' ] ];
|
1060 |
-
|
1061 |
-
// Some columns require a special pre-treatment
|
1062 |
-
switch ( $column_not_calculated ){
|
1063 |
-
|
1064 |
-
case 'browser':
|
1065 |
-
if ( !empty( $results[ $i ][ 'user_agent' ] ) && wp_slimstat::$settings[ 'show_complete_user_agent_tooltip' ] == 'on' ) {
|
1066 |
-
$element_pre_value = self::inline_help($results[$i]['user_agent'], false);
|
1067 |
-
}
|
1068 |
-
$element_value = $results[$i]['browser'].((isset($results[$i]['browser_version']) && intval($results[$i]['browser_version']) != 0)?' '.$results[$i]['browser_version']:'');
|
1069 |
-
break;
|
1070 |
-
|
1071 |
-
case 'category':
|
1072 |
-
$row_details = __( 'Category ID', 'wp-slimstat' ) . ": {$results[ $i ][ $_args[ 'columns' ] ]}";
|
1073 |
-
$element_value = get_cat_name( $results[ $i ][ $_args[ 'columns' ] ] );
|
1074 |
-
break;
|
1075 |
-
|
1076 |
-
case 'country':
|
1077 |
-
$row_details .= __('Code','wp-slimstat').": {$results[$i]['country']}";
|
1078 |
-
$element_value = __('c-'.$results[$i]['country'], 'wp-slimstat');
|
1079 |
-
break;
|
1080 |
-
|
1081 |
-
case 'ip':
|
1082 |
-
if ( wp_slimstat::$settings[ 'convert_ip_addresses' ] == 'on' ) {
|
1083 |
-
$element_value = gethostbyaddr( $results[ $i ][ $_args[ 'columns' ] ] );
|
1084 |
-
}
|
1085 |
-
else{
|
1086 |
-
$element_value = $results[ $i ][ $_args[ 'columns' ] ];
|
1087 |
-
}
|
1088 |
-
break;
|
1089 |
-
|
1090 |
-
case 'language':
|
1091 |
-
$row_details = __( 'Code', 'wp-slimstat' ) . ": {$results[ $i ][ $_args[ 'columns' ] ]}";
|
1092 |
-
$element_value = __( 'l-' . $results[ $i ][ $_args[ 'columns' ] ], 'wp-slimstat' );
|
1093 |
-
break;
|
1094 |
-
|
1095 |
-
case 'platform':
|
1096 |
-
$row_details = __( 'Code', 'wp-slimstat' ).": {$results[ $i ][ $_args[ 'columns' ] ]}";
|
1097 |
-
$element_value = __( $results[ $i ][ $_args[ 'columns' ] ], 'wp-slimstat' );
|
1098 |
-
$results[ $i ][ $_args[ 'columns' ] ] = str_replace( 'p-', '', $results[ $i ][ $_args[ 'columns' ] ] );
|
1099 |
-
break;
|
1100 |
-
|
1101 |
-
case 'referer':
|
1102 |
-
$element_value = str_replace( array( '<', '>' ), array( '<', '>' ), urldecode( $results[ $i ][ $_args[ 'columns' ] ] ) );
|
1103 |
-
//$element_value = parse_url( $element_value, PHP_URL_HOST );
|
1104 |
-
break;
|
1105 |
-
|
1106 |
-
case 'resource':
|
1107 |
-
$resource_title = self::get_resource_title( $results[ $i ][ $_args[ 'columns' ] ] );
|
1108 |
-
if ( $resource_title != $results[ $i ][ $_args[ 'columns' ] ] ) {
|
1109 |
-
$row_details = __( 'URL', 'wp-slimstat' ) . ': ' . htmlentities( $results[ $i ][ $_args[ 'columns' ] ], ENT_QUOTES, 'UTF-8' );
|
1110 |
-
}
|
1111 |
-
if ( !empty( $_args[ 'where' ] ) && strpos( $_args[ 'where' ], 'download' ) !== false ) {
|
1112 |
-
$clean_extension = pathinfo( strtolower( parse_url( $results[ $i ][ $_args[ 'columns' ] ], PHP_URL_PATH ) ), PATHINFO_EXTENSION );
|
1113 |
-
if ( in_array( $clean_extension, array( 'jpg', 'gif', 'png', 'jpeg', 'bmp' ) ) ) {
|
1114 |
-
$row_details = '<br><img src="' . $results[ $i ][ $_args[ 'columns' ] ] . '" style="width:100px">';
|
1115 |
-
}
|
1116 |
-
}
|
1117 |
-
$element_value = $resource_title;
|
1118 |
-
break;
|
1119 |
-
|
1120 |
-
case 'screen_width':
|
1121 |
-
$element_value = "{$results[ $i ][ $_args[ 'columns' ] ]} x {$results[ $i ][ 'screen_height' ]}";
|
1122 |
-
break;
|
1123 |
-
|
1124 |
-
case 'searchterms':
|
1125 |
-
if ( $_args[ 'type' ] == 'recent' ) {
|
1126 |
-
$domain = parse_url( $results[ $i ][ 'referer' ], PHP_URL_HOST );
|
1127 |
-
|
1128 |
-
$row_details = __( 'Referrer', 'wp-slimstat' ) . ": $domain";
|
1129 |
-
$element_value = self::get_search_terms_info( $results[ $i ][ 'searchterms' ], $results[ $i ][ 'referer' ], true );
|
1130 |
-
}
|
1131 |
-
else{
|
1132 |
-
$element_value = htmlentities( $results[ $i ][ 'searchterms' ], ENT_QUOTES, 'UTF-8' );
|
1133 |
-
}
|
1134 |
-
break;
|
1135 |
-
|
1136 |
-
case 'username':
|
1137 |
-
$element_value = $results[ $i ][ 'username' ];
|
1138 |
-
if ( wp_slimstat::$settings[ 'show_display_name' ] == 'on' ) {
|
1139 |
-
$element_custom_value = get_user_by( 'login', $results[ $i ][ 'username' ] );
|
1140 |
-
if ( is_object( $element_custom_value ) ) {
|
1141 |
-
$element_value = $element_custom_value->display_name;
|
1142 |
-
}
|
1143 |
-
}
|
1144 |
-
break;
|
1145 |
-
|
1146 |
-
case 'visit_id':
|
1147 |
-
$resource_title = self::get_resource_title( $results[ $i ][ 'resource' ] );
|
1148 |
-
if ( $resource_title != $results[ $i ][ 'resource' ] ) {
|
1149 |
-
$row_details = htmlentities( $results[ $i ][ 'resource' ], ENT_QUOTES, 'UTF-8' );
|
1150 |
-
}
|
1151 |
-
$element_value = $resource_title;
|
1152 |
-
break;
|
1153 |
-
default:
|
1154 |
-
}
|
1155 |
-
|
1156 |
-
if ( is_admin() ) {
|
1157 |
-
$element_value = "<a class='slimstat-filter-link' href='" . self::fs_url( $column_not_calculated. ' ' . $_args[ 'filter_op' ] . ' ' . $results[ $i ][ $_args[ 'columns' ] ] ) . "'>$element_value</a>";
|
1158 |
-
}
|
1159 |
-
|
1160 |
-
if ( !empty( $_args['type'] ) && $_args['type'] == 'recent' ) {
|
1161 |
-
$row_details = date_i18n(wp_slimstat::$settings[ 'date_format' ] . ' ' . wp_slimstat::$settings[ 'time_format' ], $results[ $i ][ 'dt' ], true ) . ( !empty( $row_details ) ? '<br>' : '' ) . $row_details;
|
1162 |
-
}
|
1163 |
-
|
1164 |
-
if ( !empty($_args[ 'type' ] ) && $_args[ 'type' ] == 'top' ) {
|
1165 |
-
$percentage_value = ( ( self::$pageviews > 0 ) ? number_format( sprintf( "%01.2f", ( 100 * $results[ $i ][ 'counthits' ] / self::$pageviews ) ), 2, wp_slimstat_db::$formats[ 'decimal' ], wp_slimstat_db::$formats[ 'thousand' ] ) : 0 );
|
1166 |
-
$counthits = number_format( $results[ $i ][ 'counthits' ], 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1167 |
-
|
1168 |
-
if ( !empty( $_args[ 'criteria' ] ) && $_args[ 'criteria' ] == 'swap' ) {
|
1169 |
-
$percentage = ' <span>' . $counthits . '</span>';
|
1170 |
-
$row_details = __('Hits','wp-slimstat') . ': ' . ( ( $column_not_calculated != 'outbound_resource' ) ? $percentage_value . '%' . ( !empty( $row_details ) ? '<br>' : '' ) . $row_details : '' );
|
1171 |
-
}
|
1172 |
-
else {
|
1173 |
-
$percentage = ' <span>' . $percentage_value . '%</span>';
|
1174 |
-
$row_details = __('Hits','wp-slimstat') . ': ' . $counthits . ( !empty( $row_details ) ? '<br>' : '' ) . $row_details;
|
1175 |
-
}
|
1176 |
-
}
|
1177 |
-
|
1178 |
-
// Some columns require a special post-treatment
|
1179 |
-
if ( $_args[ 'columns' ] == 'resource' && strpos( $_args['where'], '404' ) === false ) {
|
1180 |
-
$base_url = '';
|
1181 |
-
if (isset($results[$i]['blog_id'])){
|
1182 |
-
$base_url = parse_url(get_site_url($results[$i]['blog_id']));
|
1183 |
-
$base_url = $base_url['scheme'].'://'.$base_url['host'];
|
1184 |
-
}
|
1185 |
-
$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;
|
1186 |
-
}
|
1187 |
-
|
1188 |
-
if ( $_args[ 'columns' ] == 'referer_calculated' && !empty( $_args[ 'type' ] ) && $_args[ 'type' ] == 'top' ) {
|
1189 |
-
$element_url = 'http://' . htmlentities( $results[ $i ][ 'referer_calculated' ], ENT_QUOTES, 'UTF-8' );
|
1190 |
-
$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;
|
1191 |
-
}
|
1192 |
-
|
1193 |
-
if ( $_args[ 'columns' ] == 'referer' && !empty( $_args[ 'type' ] ) && $_args[ 'type' ] == 'top' ) {
|
1194 |
-
$element_url = htmlentities( $results[ $i ][ 'referer' ], ENT_QUOTES, 'UTF-8' );
|
1195 |
-
$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;
|
1196 |
-
}
|
1197 |
-
|
1198 |
-
if ( is_admin() && !empty( $results[ $i ][ 'ip' ]) && $_args[ 'columns' ] != 'ip' && wp_slimstat::$settings[ 'convert_ip_addresses' ] != 'on' ) {
|
1199 |
-
$row_details .= '<br> IP: <a class="slimstat-filter-link" href="'.self::fs_url( 'ip equals ' . $results[ $i ][ 'ip' ] ) . '">' . $results[ $i ][ 'ip' ] . '</a>' . ( !empty( $results[ $i ][ 'other_ip' ] ) ? ' / ' . $results[ $i ][ 'other_ip' ] : '' ) . '<a title="WHOIS: ' . $results[ $i ][ 'ip' ] . '" class="slimstat-font-location-1 whois" href="' . wp_slimstat::$settings[ 'ip_lookup_service' ] . $results[ $i ][ 'ip' ] . '"></a>';
|
1200 |
-
}
|
1201 |
-
if ( !empty( $row_details ) ) {
|
1202 |
-
$row_details = "<b class='slimstat-tooltip-content$is_expanded'>$row_details</b>";
|
1203 |
-
}
|
1204 |
-
|
1205 |
-
$row_output = "<p class='slimstat-tooltip-trigger'>$element_pre_value$element_value$percentage $row_details</p>";
|
1206 |
-
|
1207 |
-
// Strip all the filter links, if this information is shown on the frontend
|
1208 |
-
if ( !is_admin() ) {
|
1209 |
-
$row_output = preg_replace('/<a (.*?)>(.*?)<\/a>/', "\\2", $row_output);
|
1210 |
-
}
|
1211 |
-
|
1212 |
-
echo $row_output;
|
1213 |
-
}
|
1214 |
-
}
|
1215 |
-
|
1216 |
-
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
1217 |
-
die();
|
1218 |
-
}
|
1219 |
-
}
|
1220 |
-
|
1221 |
-
public static function show_activity_log( $_args = array() ) {
|
1222 |
-
// This function is too long, so it was moved to a separate file
|
1223 |
-
include( WP_PLUGIN_DIR . '/wp-slimstat/admin/view/right-now.php' );
|
1224 |
-
|
1225 |
-
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
1226 |
-
die();
|
1227 |
-
}
|
1228 |
-
}
|
1229 |
-
|
1230 |
-
public static function show_chart( $_args = array() ) {
|
1231 |
-
$
|
1232 |
-
|
1233 |
-
if ( empty( $
|
1234 |
-
|
1235 |
-
|
1236 |
-
|
1237 |
-
|
1238 |
-
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
-
|
1243 |
-
|
1244 |
-
|
1245 |
-
|
1246 |
-
|
1247 |
-
|
1248 |
-
|
1249 |
-
|
1250 |
-
|
1251 |
-
|
1252 |
-
|
1253 |
-
|
1254 |
-
|
1255 |
-
|
1256 |
-
|
1257 |
-
|
1258 |
-
|
1259 |
-
|
1260 |
-
|
1261 |
-
|
1262 |
-
|
1263 |
-
|
1264 |
-
|
1265 |
-
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
1269 |
-
|
1270 |
-
|
1271 |
-
|
1272 |
-
|
1273 |
-
"
|
1274 |
-
|
1275 |
-
|
1276 |
-
"
|
1277 |
-
"
|
1278 |
-
|
1279 |
-
|
1280 |
-
|
1281 |
-
|
1282 |
-
"
|
1283 |
-
|
1284 |
-
|
1285 |
-
|
1286 |
-
|
1287 |
-
|
1288 |
-
"
|
1289 |
-
"
|
1290 |
-
|
1291 |
-
|
1292 |
-
|
1293 |
-
|
1294 |
-
|
1295 |
-
"
|
1296 |
-
|
1297 |
-
|
1298 |
-
|
1299 |
-
|
1300 |
-
|
1301 |
-
|
1302 |
-
|
1303 |
-
|
1304 |
-
|
1305 |
-
|
1306 |
-
|
1307 |
-
|
1308 |
-
"
|
1309 |
-
"
|
1310 |
-
"
|
1311 |
-
"
|
1312 |
-
"
|
1313 |
-
|
1314 |
-
"
|
1315 |
-
"
|
1316 |
-
"
|
1317 |
-
"
|
1318 |
-
"
|
1319 |
-
"
|
1320 |
-
|
1321 |
-
"
|
1322 |
-
"
|
1323 |
-
"
|
1324 |
-
"
|
1325 |
-
"
|
1326 |
-
"
|
1327 |
-
|
1328 |
-
|
1329 |
-
|
1330 |
-
"
|
1331 |
-
"
|
1332 |
-
"
|
1333 |
-
|
1334 |
-
|
1335 |
-
|
1336 |
-
"
|
1337 |
-
"
|
1338 |
-
"
|
1339 |
-
"
|
1340 |
-
"
|
1341 |
-
"
|
1342 |
-
"
|
1343 |
-
|
1344 |
-
"
|
1345 |
-
"
|
1346 |
-
"
|
1347 |
-
"
|
1348 |
-
|
1349 |
-
"
|
1350 |
-
"
|
1351 |
-
"
|
1352 |
-
"
|
1353 |
-
"
|
1354 |
-
"
|
1355 |
-
"
|
1356 |
-
"
|
1357 |
-
|
1358 |
-
|
1359 |
-
|
1360 |
-
|
1361 |
-
|
1362 |
-
|
1363 |
-
|
1364 |
-
|
1365 |
-
|
1366 |
-
|
1367 |
-
|
1368 |
-
|
1369 |
-
|
1370 |
-
|
1371 |
-
|
1372 |
-
|
1373 |
-
|
1374 |
-
|
1375 |
-
|
1376 |
-
|
1377 |
-
$
|
1378 |
-
|
1379 |
-
|
1380 |
-
$results[
|
1381 |
-
|
1382 |
-
$results[
|
1383 |
-
|
1384 |
-
|
1385 |
-
$results[
|
1386 |
-
|
1387 |
-
|
1388 |
-
$results[
|
1389 |
-
|
1390 |
-
|
1391 |
-
$results[
|
1392 |
-
|
1393 |
-
|
1394 |
-
$results[
|
1395 |
-
|
1396 |
-
|
1397 |
-
$results[
|
1398 |
-
|
1399 |
-
$results[
|
1400 |
-
|
1401 |
-
|
1402 |
-
|
1403 |
-
|
1404 |
-
|
1405 |
-
|
1406 |
-
|
1407 |
-
|
1408 |
-
|
1409 |
-
|
1410 |
-
$
|
1411 |
-
|
1412 |
-
|
1413 |
-
$results[
|
1414 |
-
|
1415 |
-
$results[
|
1416 |
-
|
1417 |
-
$results[
|
1418 |
-
|
1419 |
-
|
1420 |
-
$results[
|
1421 |
-
$results[
|
1422 |
-
|
1423 |
-
|
1424 |
-
$results[
|
1425 |
-
$results[
|
1426 |
-
|
1427 |
-
|
1428 |
-
$results[
|
1429 |
-
|
1430 |
-
$results[
|
1431 |
-
|
1432 |
-
|
1433 |
-
$results[
|
1434 |
-
|
1435 |
-
|
1436 |
-
$results
|
1437 |
-
|
1438 |
-
|
1439 |
-
|
1440 |
-
|
1441 |
-
|
1442 |
-
|
1443 |
-
|
1444 |
-
|
1445 |
-
|
1446 |
-
|
1447 |
-
|
1448 |
-
|
1449 |
-
|
1450 |
-
|
1451 |
-
|
1452 |
-
|
1453 |
-
|
1454 |
-
|
1455 |
-
|
1456 |
-
|
1457 |
-
|
1458 |
-
|
1459 |
-
|
1460 |
-
$
|
1461 |
-
|
1462 |
-
|
1463 |
-
|
1464 |
-
|
1465 |
-
|
1466 |
-
|
1467 |
-
|
1468 |
-
|
1469 |
-
|
1470 |
-
|
1471 |
-
|
1472 |
-
$results[
|
1473 |
-
$results[
|
1474 |
-
|
1475 |
-
|
1476 |
-
$results[
|
1477 |
-
$results[
|
1478 |
-
|
1479 |
-
|
1480 |
-
$results[
|
1481 |
-
$results[
|
1482 |
-
|
1483 |
-
|
1484 |
-
$results[
|
1485 |
-
$results[
|
1486 |
-
|
1487 |
-
|
1488 |
-
$results[
|
1489 |
-
|
1490 |
-
$results[
|
1491 |
-
|
1492 |
-
|
1493 |
-
$results[
|
1494 |
-
|
1495 |
-
|
1496 |
-
$results
|
1497 |
-
|
1498 |
-
|
1499 |
-
|
1500 |
-
|
1501 |
-
|
1502 |
-
|
1503 |
-
|
1504 |
-
|
1505 |
-
$
|
1506 |
-
$results =
|
1507 |
-
|
1508 |
-
|
1509 |
-
$
|
1510 |
-
$
|
1511 |
-
$results[
|
1512 |
-
$results[
|
1513 |
-
|
1514 |
-
|
1515 |
-
$
|
1516 |
-
$
|
1517 |
-
$results[
|
1518 |
-
$results[
|
1519 |
-
|
1520 |
-
|
1521 |
-
$
|
1522 |
-
$
|
1523 |
-
$results[
|
1524 |
-
$results[
|
1525 |
-
|
1526 |
-
|
1527 |
-
$
|
1528 |
-
$
|
1529 |
-
$results[
|
1530 |
-
$results[
|
1531 |
-
|
1532 |
-
|
1533 |
-
$
|
1534 |
-
$
|
1535 |
-
$results[
|
1536 |
-
$results[
|
1537 |
-
|
1538 |
-
|
1539 |
-
$
|
1540 |
-
$
|
1541 |
-
$results[
|
1542 |
-
$results[
|
1543 |
-
|
1544 |
-
|
1545 |
-
$
|
1546 |
-
|
1547 |
-
|
1548 |
-
|
1549 |
-
|
1550 |
-
|
1551 |
-
|
1552 |
-
|
1553 |
-
|
1554 |
-
|
1555 |
-
|
1556 |
-
|
1557 |
-
|
1558 |
-
|
1559 |
-
|
1560 |
-
|
1561 |
-
|
1562 |
-
|
1563 |
-
|
1564 |
-
|
1565 |
-
|
1566 |
-
|
1567 |
-
|
1568 |
-
|
1569 |
-
$
|
1570 |
-
|
1571 |
-
|
1572 |
-
|
1573 |
-
|
1574 |
-
$results[
|
1575 |
-
$results[
|
1576 |
-
|
1577 |
-
|
1578 |
-
$results[
|
1579 |
-
$results[
|
1580 |
-
|
1581 |
-
|
1582 |
-
$results[
|
1583 |
-
$results[
|
1584 |
-
|
1585 |
-
|
1586 |
-
$results[
|
1587 |
-
$results[
|
1588 |
-
|
1589 |
-
|
1590 |
-
$results[
|
1591 |
-
$results[
|
1592 |
-
|
1593 |
-
|
1594 |
-
$results[
|
1595 |
-
$results[
|
1596 |
-
|
1597 |
-
|
1598 |
-
$results[
|
1599 |
-
$results[
|
1600 |
-
|
1601 |
-
|
1602 |
-
|
1603 |
-
|
1604 |
-
|
1605 |
-
|
1606 |
-
|
1607 |
-
|
1608 |
-
|
1609 |
-
|
1610 |
-
$
|
1611 |
-
|
1612 |
-
|
1613 |
-
|
1614 |
-
|
1615 |
-
|
1616 |
-
|
1617 |
-
|
1618 |
-
|
1619 |
-
|
1620 |
-
'
|
1621 |
-
0,
|
1622 |
-
__( '
|
1623 |
-
__( '
|
1624 |
-
),
|
1625 |
-
'
|
1626 |
-
0,
|
1627 |
-
__( '
|
1628 |
-
__( '
|
1629 |
-
),
|
1630 |
-
'
|
1631 |
-
0,
|
1632 |
-
__( '
|
1633 |
-
|
1634 |
-
),
|
1635 |
-
'
|
1636 |
-
0,
|
1637 |
-
__( 'Facebook
|
1638 |
-
''
|
1639 |
-
),
|
1640 |
-
'
|
1641 |
-
0,
|
1642 |
-
__( '
|
1643 |
-
__( '
|
1644 |
-
),
|
1645 |
-
'
|
1646 |
-
0,
|
1647 |
-
__( 'Alexa
|
1648 |
-
|
1649 |
-
),
|
1650 |
-
'
|
1651 |
-
0,
|
1652 |
-
__( 'Alexa
|
1653 |
-
''
|
1654 |
-
)
|
1655 |
-
|
1656 |
-
|
1657 |
-
|
1658 |
-
|
1659 |
-
)
|
1660 |
-
|
1661 |
-
|
1662 |
-
|
1663 |
-
$
|
1664 |
-
$
|
1665 |
-
|
1666 |
-
|
1667 |
-
|
1668 |
-
|
1669 |
-
|
1670 |
-
|
1671 |
-
|
1672 |
-
|
1673 |
-
|
1674 |
-
|
1675 |
-
|
1676 |
-
|
1677 |
-
|
1678 |
-
|
1679 |
-
|
1680 |
-
|
1681 |
-
|
1682 |
-
|
1683 |
-
|
1684 |
-
|
1685 |
-
|
1686 |
-
|
1687 |
-
|
1688 |
-
|
1689 |
-
|
1690 |
-
|
1691 |
-
|
1692 |
-
|
1693 |
-
|
1694 |
-
|
1695 |
-
|
1696 |
-
|
1697 |
-
|
1698 |
-
|
1699 |
-
|
1700 |
-
|
1701 |
-
|
1702 |
-
|
1703 |
-
|
1704 |
-
|
1705 |
-
|
1706 |
-
|
1707 |
-
|
1708 |
-
|
1709 |
-
|
1710 |
-
|
1711 |
-
|
1712 |
-
|
1713 |
-
|
1714 |
-
|
1715 |
-
|
1716 |
-
|
1717 |
-
|
1718 |
-
|
1719 |
-
|
1720 |
-
|
1721 |
-
|
1722 |
-
|
1723 |
-
|
1724 |
-
|
1725 |
-
|
1726 |
-
|
1727 |
-
|
1728 |
-
|
1729 |
-
|
1730 |
-
|
1731 |
-
|
1732 |
-
|
1733 |
-
|
1734 |
-
|
1735 |
-
|
1736 |
-
|
1737 |
-
|
1738 |
-
|
1739 |
-
|
1740 |
-
|
1741 |
-
|
1742 |
-
|
1743 |
-
|
1744 |
-
|
1745 |
-
|
1746 |
-
|
1747 |
-
|
1748 |
-
|
1749 |
-
|
1750 |
-
$results[
|
1751 |
-
|
1752 |
-
$results[
|
1753 |
-
|
1754 |
-
|
1755 |
-
$results[
|
1756 |
-
|
1757 |
-
|
1758 |
-
$results[
|
1759 |
-
|
1760 |
-
|
1761 |
-
$results[
|
1762 |
-
|
1763 |
-
|
1764 |
-
$results[
|
1765 |
-
|
1766 |
-
|
1767 |
-
$results[
|
1768 |
-
|
1769 |
-
$results[
|
1770 |
-
|
1771 |
-
|
1772 |
-
$results[
|
1773 |
-
|
1774 |
-
|
1775 |
-
|
1776 |
-
|
1777 |
-
|
1778 |
-
|
1779 |
-
|
1780 |
-
|
1781 |
-
|
1782 |
-
|
1783 |
-
|
1784 |
-
|
1785 |
-
|
1786 |
-
|
1787 |
-
|
1788 |
-
|
1789 |
-
|
1790 |
-
|
1791 |
-
|
1792 |
-
|
1793 |
-
)
|
1794 |
-
|
1795 |
-
|
1796 |
-
|
1797 |
-
|
1798 |
-
|
1799 |
-
|
1800 |
-
|
1801 |
-
|
1802 |
-
|
1803 |
-
|
1804 |
-
|
1805 |
-
|
1806 |
-
|
1807 |
-
|
1808 |
-
|
1809 |
-
|
1810 |
-
|
1811 |
-
|
1812 |
-
|
1813 |
-
|
1814 |
-
|
1815 |
-
|
1816 |
-
|
1817 |
-
|
1818 |
-
|
1819 |
-
|
1820 |
-
|
1821 |
-
|
1822 |
-
|
1823 |
-
|
1824 |
-
|
1825 |
-
|
1826 |
-
|
1827 |
-
|
1828 |
-
|
1829 |
-
|
1830 |
-
|
1831 |
-
|
1832 |
-
|
1833 |
-
|
1834 |
-
|
1835 |
-
|
1836 |
-
|
1837 |
-
|
1838 |
-
|
1839 |
-
|
1840 |
-
|
1841 |
-
|
1842 |
-
|
1843 |
-
|
1844 |
-
$data_points[] = "{zoomLevel:7,type:'circle',title:'{$clean_city_name}<br>{$date_time}',latitude:$latitude,longitude:$longitude}";
|
1845 |
-
|
1846 |
-
|
1847 |
-
|
1848 |
-
|
1849 |
-
$data_areas = array('xx'=>'{id:"XX",balloonText:"'.__('c-xx','wp-slimstat').': 0",value:0,color:"#ededed"}','af'=>'{id:"AF",balloonText:"'.__('c-af','wp-slimstat').': 0",value:0,color:"#ededed"}','ax'=>'{id:"AX",balloonText:"'.__('c-ax','wp-slimstat').': 0",value:0,color:"#ededed"}','al'=>'{id:"AL",balloonText:"'.__('c-al','wp-slimstat').': 0",value:0,color:"#ededed"}','dz'=>'{id:"DZ",balloonText:"'.__('c-dz','wp-slimstat').': 0",value:0,color:"#ededed"}','ad'=>'{id:"AD",balloonText:"'.__('c-ad','wp-slimstat').': 0",value:0,color:"#ededed"}','ao'=>'{id:"AO",balloonText:"'.__('c-ao','wp-slimstat').': 0",value:0,color:"#ededed"}','ai'=>'{id:"AI",balloonText:"'.__('c-ai','wp-slimstat').': 0",value:0,color:"#ededed"}','ag'=>'{id:"AG",balloonText:"'.__('c-ag','wp-slimstat').': 0",value:0,color:"#ededed"}','ar'=>'{id:"AR",balloonText:"'.__('c-ar','wp-slimstat').': 0",value:0,color:"#ededed"}','am'=>'{id:"AM",balloonText:"'.__('c-am','wp-slimstat').': 0",value:0,color:"#ededed"}','aw'=>'{id:"AW",balloonText:"'.__('c-aw','wp-slimstat').': 0",value:0,color:"#ededed"}','au'=>'{id:"AU",balloonText:"'.__('c-au','wp-slimstat').': 0",value:0,color:"#ededed"}','at'=>'{id:"AT",balloonText:"'.__('c-at','wp-slimstat').': 0",value:0,color:"#ededed"}','az'=>'{id:"AZ",balloonText:"'.__('c-az','wp-slimstat').': 0",value:0,color:"#ededed"}','bs'=>'{id:"BS",balloonText:"'.__('c-bs','wp-slimstat').': 0",value:0,color:"#ededed"}','bh'=>'{id:"BH",balloonText:"'.__('c-bh','wp-slimstat').': 0",value:0,color:"#ededed"}','bd'=>'{id:"BD",balloonText:"'.__('c-bd','wp-slimstat').': 0",value:0,color:"#ededed"}','bb'=>'{id:"BB",balloonText:"'.__('c-bb','wp-slimstat').': 0",value:0,color:"#ededed"}','by'=>'{id:"BY",balloonText:"'.__('c-by','wp-slimstat').': 0",value:0,color:"#ededed"}','be'=>'{id:"BE",balloonText:"'.__('c-be','wp-slimstat').': 0",value:0,color:"#ededed"}','bz'=>'{id:"BZ",balloonText:"'.__('c-bz','wp-slimstat').': 0",value:0,color:"#ededed"}','bj'=>'{id:"BJ",balloonText:"'.__('c-bj','wp-slimstat').': 0",value:0,color:"#ededed"}','bm'=>'{id:"BM",balloonText:"'.__('c-bm','wp-slimstat').': 0",value:0,color:"#ededed"}','bt'=>'{id:"BT",balloonText:"'.__('c-bt','wp-slimstat').': 0",value:0,color:"#ededed"}','bo'=>'{id:"BO",balloonText:"'.__('c-bo','wp-slimstat').': 0",value:0,color:"#ededed"}','ba'=>'{id:"BA",balloonText:"'.__('c-ba','wp-slimstat').': 0",value:0,color:"#ededed"}','bw'=>'{id:"BW",balloonText:"'.__('c-bw','wp-slimstat').': 0",value:0,color:"#ededed"}','br'=>'{id:"BR",balloonText:"'.__('c-br','wp-slimstat').': 0",value:0,color:"#ededed"}','bn'=>'{id:"BN",balloonText:"'.__('c-bn','wp-slimstat').': 0",value:0,color:"#ededed"}','bg'=>'{id:"BG",balloonText:"'.__('c-bg','wp-slimstat').': 0",value:0,color:"#ededed"}','bf'=>'{id:"BF",balloonText:"'.__('c-bf','wp-slimstat').': 0",value:0,color:"#ededed"}','bi'=>'{id:"BI",balloonText:"'.__('c-bi','wp-slimstat').': 0",value:0,color:"#ededed"}','kh'=>'{id:"KH",balloonText:"'.__('c-kh','wp-slimstat').': 0",value:0,color:"#ededed"}','cm'=>'{id:"CM",balloonText:"'.__('c-cm','wp-slimstat').': 0",value:0,color:"#ededed"}','ca'=>'{id:"CA",balloonText:"'.__('c-ca','wp-slimstat').': 0",value:0,color:"#ededed"}','cv'=>'{id:"CV",balloonText:"'.__('c-cv','wp-slimstat').': 0",value:0,color:"#ededed"}','ky'=>'{id:"KY",balloonText:"'.__('c-ky','wp-slimstat').': 0",value:0,color:"#ededed"}','cf'=>'{id:"CF",balloonText:"'.__('c-cf','wp-slimstat').': 0",value:0,color:"#ededed"}','td'=>'{id:"TD",balloonText:"'.__('c-td','wp-slimstat').': 0",value:0,color:"#ededed"}','cl'=>'{id:"CL",balloonText:"'.__('c-cl','wp-slimstat').': 0",value:0,color:"#ededed"}','cn'=>'{id:"CN",balloonText:"'.__('c-cn','wp-slimstat').': 0",value:0,color:"#ededed"}','co'=>'{id:"CO",balloonText:"'.__('c-co','wp-slimstat').': 0",value:0,color:"#ededed"}','km'=>'{id:"KM",balloonText:"'.__('c-km','wp-slimstat').': 0",value:0,color:"#ededed"}','cg'=>'{id:"CG",balloonText:"'.__('c-cg','wp-slimstat').': 0",value:0,color:"#ededed"}','cd'=>'{id:"CD",balloonText:"'.__('c-cd','wp-slimstat').': 0",value:0,color:"#ededed"}','cr'=>'{id:"CR",balloonText:"'.__('c-cr','wp-slimstat').': 0",value:0,color:"#ededed"}','ci'=>'{id:"CI",balloonText:"'.__('c-ci','wp-slimstat').': 0",value:0,color:"#ededed"}','hr'=>'{id:"HR",balloonText:"'.__('c-hr','wp-slimstat').': 0",value:0,color:"#ededed"}','cu'=>'{id:"CU",balloonText:"'.__('c-cu','wp-slimstat').': 0",value:0,color:"#ededed"}','cy'=>'{id:"CY",balloonText:"'.__('c-cy','wp-slimstat').': 0",value:0,color:"#ededed"}','cz'=>'{id:"CZ",balloonText:"'.__('c-cz','wp-slimstat').': 0",value:0,color:"#ededed"}','dk'=>'{id:"DK",balloonText:"'.__('c-dk','wp-slimstat').': 0",value:0,color:"#ededed"}','dj'=>'{id:"DJ",balloonText:"'.__('c-dj','wp-slimstat').': 0",value:0,color:"#ededed"}','dm'=>'{id:"DM",balloonText:"'.__('c-dm','wp-slimstat').': 0",value:0,color:"#ededed"}','do'=>'{id:"DO",balloonText:"'.__('c-do','wp-slimstat').': 0",value:0,color:"#ededed"}','ec'=>'{id:"EC",balloonText:"'.__('c-ec','wp-slimstat').': 0",value:0,color:"#ededed"}','eg'=>'{id:"EG",balloonText:"'.__('c-eg','wp-slimstat').': 0",value:0,color:"#ededed"}','sv'=>'{id:"SV",balloonText:"'.__('c-sv','wp-slimstat').': 0",value:0,color:"#ededed"}','gq'=>'{id:"GQ",balloonText:"'.__('c-gq','wp-slimstat').': 0",value:0,color:"#ededed"}','er'=>'{id:"ER",balloonText:"'.__('c-er','wp-slimstat').': 0",value:0,color:"#ededed"}','ee'=>'{id:"EE",balloonText:"'.__('c-ee','wp-slimstat').': 0",value:0,color:"#ededed"}','et'=>'{id:"ET",balloonText:"'.__('c-et','wp-slimstat').': 0",value:0,color:"#ededed"}','fo'=>'{id:"FO",balloonText:"'.__('c-fo','wp-slimstat').': 0",value:0,color:"#ededed"}','fk'=>'{id:"FK",balloonText:"'.__('c-fk','wp-slimstat').': 0",value:0,color:"#ededed"}','fj'=>'{id:"FJ",balloonText:"'.__('c-fj','wp-slimstat').': 0",value:0,color:"#ededed"}','fi'=>'{id:"FI",balloonText:"'.__('c-fi','wp-slimstat').': 0",value:0,color:"#ededed"}','fr'=>'{id:"FR",balloonText:"'.__('c-fr','wp-slimstat').': 0",value:0,color:"#ededed"}','gf'=>'{id:"GF",balloonText:"'.__('c-gf','wp-slimstat').': 0",value:0,color:"#ededed"}','ga'=>'{id:"GA",balloonText:"'.__('c-ga','wp-slimstat').': 0",value:0,color:"#ededed"}','gm'=>'{id:"GM",balloonText:"'.__('c-gm','wp-slimstat').': 0",value:0,color:"#ededed"}','ge'=>'{id:"GE",balloonText:"'.__('c-ge','wp-slimstat').': 0",value:0,color:"#ededed"}','de'=>'{id:"DE",balloonText:"'.__('c-de','wp-slimstat').': 0",value:0,color:"#ededed"}','gh'=>'{id:"GH",balloonText:"'.__('c-gh','wp-slimstat').': 0",value:0,color:"#ededed"}','gr'=>'{id:"GR",balloonText:"'.__('c-gr','wp-slimstat').': 0",value:0,color:"#ededed"}','gl'=>'{id:"GL",balloonText:"'.__('c-gl','wp-slimstat').': 0",value:0,color:"#ededed"}','gd'=>'{id:"GD",balloonText:"'.__('c-gd','wp-slimstat').': 0",value:0,color:"#ededed"}','gp'=>'{id:"GP",balloonText:"'.__('c-gp','wp-slimstat').': 0",value:0,color:"#ededed"}','gt'=>'{id:"GT",balloonText:"'.__('c-gt','wp-slimstat').': 0",value:0,color:"#ededed"}','gn'=>'{id:"GN",balloonText:"'.__('c-gn','wp-slimstat').': 0",value:0,color:"#ededed"}','gw'=>'{id:"GW",balloonText:"'.__('c-gw','wp-slimstat').': 0",value:0,color:"#ededed"}','gy'=>'{id:"GY",balloonText:"'.__('c-gy','wp-slimstat').': 0",value:0,color:"#ededed"}','ht'=>'{id:"HT",balloonText:"'.__('c-ht','wp-slimstat').': 0",value:0,color:"#ededed"}','hn'=>'{id:"HN",balloonText:"'.__('c-hn','wp-slimstat').': 0",value:0,color:"#ededed"}','hk'=>'{id:"HK",balloonText:"'.__('c-hk','wp-slimstat').': 0",value:0,color:"#ededed"}','hu'=>'{id:"HU",balloonText:"'.__('c-hu','wp-slimstat').': 0",value:0,color:"#ededed"}','is'=>'{id:"IS",balloonText:"'.__('c-is','wp-slimstat').': 0",value:0,color:"#ededed"}','in'=>'{id:"IN",balloonText:"'.__('c-in','wp-slimstat').': 0",value:0,color:"#ededed"}','id'=>'{id:"ID",balloonText:"'.__('c-id','wp-slimstat').': 0",value:0,color:"#ededed"}','ir'=>'{id:"IR",balloonText:"'.__('c-ir','wp-slimstat').': 0",value:0,color:"#ededed"}','iq'=>'{id:"IQ",balloonText:"'.__('c-iq','wp-slimstat').': 0",value:0,color:"#ededed"}','ie'=>'{id:"IE",balloonText:"'.__('c-ie','wp-slimstat').': 0",value:0,color:"#ededed"}','il'=>'{id:"IL",balloonText:"'.__('c-il','wp-slimstat').': 0",value:0,color:"#ededed"}','it'=>'{id:"IT",balloonText:"'.__('c-it','wp-slimstat').': 0",value:0,color:"#ededed"}','jm'=>'{id:"JM",balloonText:"'.__('c-jm','wp-slimstat').': 0",value:0,color:"#ededed"}','jp'=>'{id:"JP",balloonText:"'.__('c-jp','wp-slimstat').': 0",value:0,color:"#ededed"}','jo'=>'{id:"JO",balloonText:"'.__('c-jo','wp-slimstat').': 0",value:0,color:"#ededed"}','kz'=>'{id:"KZ",balloonText:"'.__('c-kz','wp-slimstat').': 0",value:0,color:"#ededed"}','ke'=>'{id:"KE",balloonText:"'.__('c-ke','wp-slimstat').': 0",value:0,color:"#ededed"}','nr'=>'{id:"NR",balloonText:"'.__('c-nr','wp-slimstat').': 0",value:0,color:"#ededed"}','kp'=>'{id:"KP",balloonText:"'.__('c-kp','wp-slimstat').': 0",value:0,color:"#ededed"}','kr'=>'{id:"KR",balloonText:"'.__('c-kr','wp-slimstat').': 0",value:0,color:"#ededed"}','kv'=>'{id:"KV",balloonText:"'.__('c-kv','wp-slimstat').': 0",value:0,color:"#ededed"}','kw'=>'{id:"KW",balloonText:"'.__('c-kw','wp-slimstat').': 0",value:0,color:"#ededed"}','kg'=>'{id:"KG",balloonText:"'.__('c-kg','wp-slimstat').': 0",value:0,color:"#ededed"}','la'=>'{id:"LA",balloonText:"'.__('c-la','wp-slimstat').': 0",value:0,color:"#ededed"}','lv'=>'{id:"LV",balloonText:"'.__('c-lv','wp-slimstat').': 0",value:0,color:"#ededed"}','lb'=>'{id:"LB",balloonText:"'.__('c-lb','wp-slimstat').': 0",value:0,color:"#ededed"}','ls'=>'{id:"LS",balloonText:"'.__('c-ls','wp-slimstat').': 0",value:0,color:"#ededed"}','lr'=>'{id:"LR",balloonText:"'.__('c-lr','wp-slimstat').': 0",value:0,color:"#ededed"}','ly'=>'{id:"LY",balloonText:"'.__('c-ly','wp-slimstat').': 0",value:0,color:"#ededed"}','li'=>'{id:"LI",balloonText:"'.__('c-li','wp-slimstat').': 0",value:0,color:"#ededed"}','lt'=>'{id:"LT",balloonText:"'.__('c-lt','wp-slimstat').': 0",value:0,color:"#ededed"}','lu'=>'{id:"LU",balloonText:"'.__('c-lu','wp-slimstat').': 0",value:0,color:"#ededed"}','mk'=>'{id:"MK",balloonText:"'.__('c-mk','wp-slimstat').': 0",value:0,color:"#ededed"}','mg'=>'{id:"MG",balloonText:"'.__('c-mg','wp-slimstat').': 0",value:0,color:"#ededed"}','mw'=>'{id:"MW",balloonText:"'.__('c-mw','wp-slimstat').': 0",value:0,color:"#ededed"}','my'=>'{id:"MY",balloonText:"'.__('c-my','wp-slimstat').': 0",value:0,color:"#ededed"}','ml'=>'{id:"ML",balloonText:"'.__('c-ml','wp-slimstat').': 0",value:0,color:"#ededed"}','mt'=>'{id:"MT",balloonText:"'.__('c-mt','wp-slimstat').': 0",value:0,color:"#ededed"}','mq'=>'{id:"MQ",balloonText:"'.__('c-mq','wp-slimstat').': 0",value:0,color:"#ededed"}','mr'=>'{id:"MR",balloonText:"'.__('c-mr','wp-slimstat').': 0",value:0,color:"#ededed"}','mu'=>'{id:"MU",balloonText:"'.__('c-mu','wp-slimstat').': 0",value:0,color:"#ededed"}','mx'=>'{id:"MX",balloonText:"'.__('c-mx','wp-slimstat').': 0",value:0,color:"#ededed"}','md'=>'{id:"MD",balloonText:"'.__('c-md','wp-slimstat').': 0",value:0,color:"#ededed"}','mn'=>'{id:"MN",balloonText:"'.__('c-mn','wp-slimstat').': 0",value:0,color:"#ededed"}','me'=>'{id:"ME",balloonText:"'.__('c-me','wp-slimstat').': 0",value:0,color:"#ededed"}','ms'=>'{id:"MS",balloonText:"'.__('c-ms','wp-slimstat').': 0",value:0,color:"#ededed"}','ma'=>'{id:"MA",balloonText:"'.__('c-ma','wp-slimstat').': 0",value:0,color:"#ededed"}','mz'=>'{id:"MZ",balloonText:"'.__('c-mz','wp-slimstat').': 0",value:0,color:"#ededed"}','mm'=>'{id:"MM",balloonText:"'.__('c-mm','wp-slimstat').': 0",value:0,color:"#ededed"}','na'=>'{id:"NA",balloonText:"'.__('c-na','wp-slimstat').': 0",value:0,color:"#ededed"}','np'=>'{id:"NP",balloonText:"'.__('c-np','wp-slimstat').': 0",value:0,color:"#ededed"}','nl'=>'{id:"NL",balloonText:"'.__('c-nl','wp-slimstat').': 0",value:0,color:"#ededed"}','nc'=>'{id:"NC",balloonText:"'.__('c-nc','wp-slimstat').': 0",value:0,color:"#ededed"}','nz'=>'{id:"NZ",balloonText:"'.__('c-nz','wp-slimstat').': 0",value:0,color:"#ededed"}','ni'=>'{id:"NI",balloonText:"'.__('c-ni','wp-slimstat').': 0",value:0,color:"#ededed"}','ne'=>'{id:"NE",balloonText:"'.__('c-ne','wp-slimstat').': 0",value:0,color:"#ededed"}','ng'=>'{id:"NG",balloonText:"'.__('c-ng','wp-slimstat').': 0",value:0,color:"#ededed"}','no'=>'{id:"NO",balloonText:"'.__('c-no','wp-slimstat').': 0",value:0,color:"#ededed"}','om'=>'{id:"OM",balloonText:"'.__('c-om','wp-slimstat').': 0",value:0,color:"#ededed"}','pk'=>'{id:"PK",balloonText:"'.__('c-pk','wp-slimstat').': 0",value:0,color:"#ededed"}','pw'=>'{id:"PW",balloonText:"'.__('c-pw','wp-slimstat').': 0",value:0,color:"#ededed"}','ps'=>'{id:"PS",balloonText:"'.__('c-ps','wp-slimstat').': 0",value:0,color:"#ededed"}','pa'=>'{id:"PA",balloonText:"'.__('c-pa','wp-slimstat').': 0",value:0,color:"#ededed"}','pg'=>'{id:"PG",balloonText:"'.__('c-pg','wp-slimstat').': 0",value:0,color:"#ededed"}','py'=>'{id:"PY",balloonText:"'.__('c-py','wp-slimstat').': 0",value:0,color:"#ededed"}','pe'=>'{id:"PE",balloonText:"'.__('c-pe','wp-slimstat').': 0",value:0,color:"#ededed"}','ph'=>'{id:"PH",balloonText:"'.__('c-ph','wp-slimstat').': 0",value:0,color:"#ededed"}','pl'=>'{id:"PL",balloonText:"'.__('c-pl','wp-slimstat').': 0",value:0,color:"#ededed"}','pt'=>'{id:"PT",balloonText:"'.__('c-pt','wp-slimstat').': 0",value:0,color:"#ededed"}','pr'=>'{id:"PR",balloonText:"'.__('c-pr','wp-slimstat').': 0",value:0,color:"#ededed"}','qa'=>'{id:"QA",balloonText:"'.__('c-qa','wp-slimstat').': 0",value:0,color:"#ededed"}','re'=>'{id:"RE",balloonText:"'.__('c-re','wp-slimstat').': 0",value:0,color:"#ededed"}','ro'=>'{id:"RO",balloonText:"'.__('c-ro','wp-slimstat').': 0",value:0,color:"#ededed"}','ru'=>'{id:"RU",balloonText:"'.__('c-ru','wp-slimstat').': 0",value:0,color:"#ededed"}','rw'=>'{id:"RW",balloonText:"'.__('c-rw','wp-slimstat').': 0",value:0,color:"#ededed"}','kn'=>'{id:"KN",balloonText:"'.__('c-kn','wp-slimstat').': 0",value:0,color:"#ededed"}','lc'=>'{id:"LC",balloonText:"'.__('c-lc','wp-slimstat').': 0",value:0,color:"#ededed"}','mf'=>'{id:"MF",balloonText:"'.__('c-mf','wp-slimstat').': 0",value:0,color:"#ededed"}','vc'=>'{id:"VC",balloonText:"'.__('c-vc','wp-slimstat').': 0",value:0,color:"#ededed"}','ws'=>'{id:"WS",balloonText:"'.__('c-ws','wp-slimstat').': 0",value:0,color:"#ededed"}','st'=>'{id:"ST",balloonText:"'.__('c-st','wp-slimstat').': 0",value:0,color:"#ededed"}','sa'=>'{id:"SA",balloonText:"'.__('c-sa','wp-slimstat').': 0",value:0,color:"#ededed"}','sn'=>'{id:"SN",balloonText:"'.__('c-sn','wp-slimstat').': 0",value:0,color:"#ededed"}','rs'=>'{id:"RS",balloonText:"'.__('c-rs','wp-slimstat').': 0",value:0,color:"#ededed"}','sl'=>'{id:"SL",balloonText:"'.__('c-sl','wp-slimstat').': 0",value:0,color:"#ededed"}','sg'=>'{id:"SG",balloonText:"'.__('c-sg','wp-slimstat').': 0",value:0,color:"#ededed"}','sk'=>'{id:"SK",balloonText:"'.__('c-sk','wp-slimstat').': 0",value:0,color:"#ededed"}','si'=>'{id:"SI",balloonText:"'.__('c-si','wp-slimstat').': 0",value:0,color:"#ededed"}','sb'=>'{id:"SB",balloonText:"'.__('c-sb','wp-slimstat').': 0",value:0,color:"#ededed"}','so'=>'{id:"SO",balloonText:"'.__('c-so','wp-slimstat').': 0",value:0,color:"#ededed"}','za'=>'{id:"ZA",balloonText:"'.__('c-za','wp-slimstat').': 0",value:0,color:"#ededed"}','gs'=>'{id:"GS",balloonText:"'.__('c-gs','wp-slimstat').': 0",value:0,color:"#ededed"}','es'=>'{id:"ES",balloonText:"'.__('c-es','wp-slimstat').': 0",value:0,color:"#ededed"}','lk'=>'{id:"LK",balloonText:"'.__('c-lk','wp-slimstat').': 0",value:0,color:"#ededed"}','sc'=>'{id:"SC",balloonText:"'.__('c-sc','wp-slimstat').': 0",value:0,color:"#ededed"}','sd'=>'{id:"SD",balloonText:"'.__('c-sd','wp-slimstat').': 0",value:0,color:"#ededed"}','ss'=>'{id:"SS",balloonText:"'.__('c-ss','wp-slimstat').': 0",value:0,color:"#ededed"}','sr'=>'{id:"SR",balloonText:"'.__('c-sr','wp-slimstat').': 0",value:0,color:"#ededed"}','sj'=>'{id:"SJ",balloonText:"'.__('c-sj','wp-slimstat').': 0",value:0,color:"#ededed"}','sz'=>'{id:"SZ",balloonText:"'.__('c-sz','wp-slimstat').': 0",value:0,color:"#ededed"}','se'=>'{id:"SE",balloonText:"'.__('c-se','wp-slimstat').': 0",value:0,color:"#ededed"}','ch'=>'{id:"CH",balloonText:"'.__('c-ch','wp-slimstat').': 0",value:0,color:"#ededed"}','sy'=>'{id:"SY",balloonText:"'.__('c-sy','wp-slimstat').': 0",value:0,color:"#ededed"}','tw'=>'{id:"TW",balloonText:"'.__('c-tw','wp-slimstat').': 0",value:0,color:"#ededed"}','tj'=>'{id:"TJ",balloonText:"'.__('c-tj','wp-slimstat').': 0",value:0,color:"#ededed"}','tz'=>'{id:"TZ",balloonText:"'.__('c-tz','wp-slimstat').': 0",value:0,color:"#ededed"}','th'=>'{id:"TH",balloonText:"'.__('c-th','wp-slimstat').': 0",value:0,color:"#ededed"}','tl'=>'{id:"TL",balloonText:"'.__('c-tl','wp-slimstat').': 0",value:0,color:"#ededed"}','tg'=>'{id:"TG",balloonText:"'.__('c-tg','wp-slimstat').': 0",value:0,color:"#ededed"}','to'=>'{id:"TO",balloonText:"'.__('c-to','wp-slimstat').': 0",value:0,color:"#ededed"}','tt'=>'{id:"TT",balloonText:"'.__('c-tt','wp-slimstat').': 0",value:0,color:"#ededed"}','tn'=>'{id:"TN",balloonText:"'.__('c-tn','wp-slimstat').': 0",value:0,color:"#ededed"}','tr'=>'{id:"TR",balloonText:"'.__('c-tr','wp-slimstat').': 0",value:0,color:"#ededed"}','tm'=>'{id:"TM",balloonText:"'.__('c-tm','wp-slimstat').': 0",value:0,color:"#ededed"}','tc'=>'{id:"TC",balloonText:"'.__('c-tc','wp-slimstat').': 0",value:0,color:"#ededed"}','ug'=>'{id:"UG",balloonText:"'.__('c-ug','wp-slimstat').': 0",value:0,color:"#ededed"}','ua'=>'{id:"UA",balloonText:"'.__('c-ua','wp-slimstat').': 0",value:0,color:"#ededed"}','ae'=>'{id:"AE",balloonText:"'.__('c-ae','wp-slimstat').': 0",value:0,color:"#ededed"}','gb'=>'{id:"GB",balloonText:"'.__('c-gb','wp-slimstat').': 0",value:0,color:"#ededed"}','us'=>'{id:"US",balloonText:"'.__('c-us','wp-slimstat').': 0",value:0,color:"#ededed"}','uy'=>'{id:"UY",balloonText:"'.__('c-uy','wp-slimstat').': 0",value:0,color:"#ededed"}','uz'=>'{id:"UZ",balloonText:"'.__('c-uz','wp-slimstat').': 0",value:0,color:"#ededed"}','vu'=>'{id:"VU",balloonText:"'.__('c-vu','wp-slimstat').': 0",value:0,color:"#ededed"}','ve'=>'{id:"VE",balloonText:"'.__('c-ve','wp-slimstat').': 0",value:0,color:"#ededed"}','vn'=>'{id:"VN",balloonText:"'.__('c-vn','wp-slimstat').': 0",value:0,color:"#ededed"}','vg'=>'{id:"VG",balloonText:"'.__('c-vg','wp-slimstat').': 0",value:0,color:"#ededed"}','vi'=>'{id:"VI",balloonText:"'.__('c-vi','wp-slimstat').': 0",value:0,color:"#ededed"}','eh'=>'{id:"EH",balloonText:"'.__('c-eh','wp-slimstat').': 0",value:0,color:"#ededed"}','ye'=>'{id:"YE",balloonText:"'.__('c-ye','wp-slimstat').': 0",value:0,color:"#ededed"}','zm'=>'{id:"ZM",balloonText:"'.__('c-zm','wp-slimstat').': 0",value:0,color:"#ededed"}','zw'=>'{id:"ZW",balloonText:"'.__('c-zw','wp-slimstat').': 0",value:0,color:"#ededed"}','gg'=>'{id:"GG",balloonText:"'.__('c-gg','wp-slimstat').': 0",value:0,color:"#ededed"}','je'=>'{id:"JE",balloonText:"'.__('c-je','wp-slimstat').': 0",value:0,color:"#ededed"}','im'=>'{id:"IM",balloonText:"'.__('c-im','wp-slimstat').': 0",value:0,color:"#ededed"}','mv'=>'{id:"MV",balloonText:"'.__('c-mv','wp-slimstat').': 0",value:0,color:"#ededed"}');
|
1850 |
-
|
1851 |
-
|
1852 |
-
|
1853 |
-
|
1854 |
-
|
1855 |
-
|
1856 |
-
}
|
1857 |
-
|
1858 |
-
|
1859 |
-
|
1860 |
-
|
1861 |
-
|
1862 |
-
|
1863 |
-
|
1864 |
-
|
1865 |
-
|
1866 |
-
|
1867 |
-
|
1868 |
-
|
1869 |
-
|
1870 |
-
|
1871 |
-
|
1872 |
-
|
1873 |
-
|
1874 |
-
|
1875 |
-
|
1876 |
-
|
1877 |
-
|
1878 |
-
|
1879 |
-
|
1880 |
-
|
1881 |
-
|
1882 |
-
|
1883 |
-
|
1884 |
-
|
1885 |
-
|
1886 |
-
|
1887 |
-
|
1888 |
-
|
1889 |
-
|
1890 |
-
|
1891 |
-
|
1892 |
-
|
1893 |
-
|
1894 |
-
|
1895 |
-
|
1896 |
-
legend.
|
1897 |
-
|
1898 |
-
|
1899 |
-
|
1900 |
-
|
1901 |
-
|
1902 |
-
|
1903 |
-
|
1904 |
-
|
1905 |
-
|
1906 |
-
|
1907 |
-
|
1908 |
-
|
1909 |
-
|
1910 |
-
|
1911 |
-
|
1912 |
-
|
1913 |
-
|
1914 |
-
|
1915 |
-
|
1916 |
-
|
1917 |
-
|
1918 |
-
|
1919 |
-
|
1920 |
-
|
1921 |
-
|
1922 |
-
|
1923 |
-
|
1924 |
-
|
1925 |
-
|
1926 |
-
|
1927 |
-
|
1928 |
-
|
1929 |
-
|
1930 |
-
|
1931 |
-
|
1932 |
-
|
1933 |
-
|
1934 |
-
|
1935 |
-
|
1936 |
-
|
1937 |
-
map.
|
1938 |
-
map.
|
1939 |
-
|
1940 |
-
|
1941 |
-
map.
|
1942 |
-
|
1943 |
-
|
1944 |
-
|
1945 |
-
|
1946 |
-
|
1947 |
-
|
1948 |
-
|
1949 |
-
|
1950 |
-
|
1951 |
-
|
1952 |
-
|
1953 |
-
|
1954 |
-
|
1955 |
-
|
1956 |
-
|
1957 |
-
|
1958 |
-
|
1959 |
-
|
1960 |
-
|
1961 |
-
|
1962 |
-
|
1963 |
-
|
1964 |
-
|
1965 |
-
|
1966 |
-
|
1967 |
-
|
1968 |
-
|
1969 |
-
|
1970 |
-
|
1971 |
-
|
1972 |
-
$
|
1973 |
-
}
|
1974 |
-
|
1975 |
-
|
1976 |
-
|
1977 |
-
|
1978 |
-
|
1979 |
-
|
1980 |
-
|
1981 |
-
|
1982 |
-
|
1983 |
-
|
1984 |
-
|
1985 |
-
|
1986 |
-
|
1987 |
-
|
1988 |
-
|
1989 |
-
|
1990 |
-
|
1991 |
-
|
1992 |
-
|
1993 |
-
|
1994 |
-
|
1995 |
-
|
1996 |
-
|
1997 |
-
|
1998 |
-
|
1999 |
-
|
2000 |
-
|
2001 |
-
|
2002 |
-
|
2003 |
-
|
2004 |
-
|
2005 |
-
|
2006 |
-
|
2007 |
-
|
2008 |
-
|
2009 |
-
|
2010 |
-
|
2011 |
-
|
2012 |
-
|
2013 |
-
|
2014 |
-
|
2015 |
-
|
2016 |
-
|
2017 |
-
|
2018 |
-
|
2019 |
-
|
2020 |
-
|
2021 |
-
|
2022 |
-
|
2023 |
-
|
2024 |
-
|
2025 |
-
|
2026 |
-
|
2027 |
-
|
2028 |
-
|
2029 |
-
|
2030 |
-
|
2031 |
-
|
2032 |
-
|
2033 |
-
|
2034 |
-
|
2035 |
-
|
2036 |
-
|
2037 |
-
|
2038 |
-
|
2039 |
-
|
2040 |
-
|
2041 |
-
|
2042 |
-
|
2043 |
-
|
2044 |
-
|
2045 |
-
|
2046 |
-
|
2047 |
-
|
2048 |
-
|
2049 |
-
|
2050 |
-
|
2051 |
-
|
2052 |
-
|
2053 |
-
|
2054 |
-
|
2055 |
-
|
2056 |
-
|
2057 |
-
|
2058 |
-
|
2059 |
-
|
2060 |
-
|
2061 |
-
|
2062 |
-
|
2063 |
-
|
2064 |
-
|
2065 |
-
|
2066 |
-
|
2067 |
-
|
2068 |
-
|
2069 |
-
|
2070 |
-
|
2071 |
-
|
2072 |
-
|
2073 |
-
|
2074 |
-
|
2075 |
-
|
2076 |
-
|
2077 |
-
|
2078 |
-
|
2079 |
-
|
2080 |
-
|
2081 |
-
|
2082 |
-
|
2083 |
-
|
2084 |
-
|
2085 |
-
|
2086 |
-
|
2087 |
-
|
2088 |
-
|
2089 |
-
|
2090 |
-
$
|
2091 |
-
|
2092 |
-
|
2093 |
-
|
2094 |
-
|
2095 |
-
|
2096 |
-
|
2097 |
-
|
2098 |
-
|
2099 |
-
|
2100 |
-
|
2101 |
-
|
2102 |
-
|
2103 |
-
|
2104 |
-
|
2105 |
-
|
2106 |
-
|
2107 |
-
|
2108 |
-
|
2109 |
-
|
2110 |
-
|
2111 |
-
|
2112 |
-
|
2113 |
-
|
2114 |
-
|
2115 |
-
|
2116 |
-
|
2117 |
-
|
2118 |
-
|
2119 |
-
|
2120 |
-
|
2121 |
-
|
2122 |
-
|
2123 |
-
|
2124 |
-
|
2125 |
-
|
2126 |
-
|
2127 |
-
|
2128 |
-
|
2129 |
-
|
2130 |
-
|
2131 |
-
|
2132 |
-
|
2133 |
-
|
2134 |
-
|
2135 |
-
|
2136 |
-
|
2137 |
-
|
2138 |
-
|
2139 |
-
|
2140 |
-
|
2141 |
-
|
2142 |
-
|
2143 |
-
|
2144 |
-
|
2145 |
-
|
2146 |
-
|
2147 |
-
|
2148 |
-
|
2149 |
-
|
2150 |
-
|
2151 |
-
|
2152 |
-
|
2153 |
-
|
2154 |
-
|
2155 |
-
$report_id = $
|
2156 |
-
}
|
2157 |
-
|
2158 |
-
//
|
2159 |
-
|
2160 |
-
|
2161 |
-
}
|
2162 |
-
|
2163 |
-
|
2164 |
-
|
2165 |
-
|
2166 |
-
|
2167 |
-
|
2168 |
-
|
2169 |
-
|
2170 |
-
|
2171 |
-
'
|
2172 |
-
|
2173 |
-
|
2174 |
-
|
2175 |
-
|
2176 |
-
|
2177 |
-
|
2178 |
-
|
2179 |
-
|
2180 |
-
|
2181 |
-
|
2182 |
-
'
|
2183 |
-
'
|
2184 |
-
'
|
2185 |
-
'
|
2186 |
-
'
|
2187 |
-
'
|
2188 |
-
|
2189 |
-
|
2190 |
-
|
2191 |
-
|
2192 |
-
|
2193 |
-
), $_args[ 'callback_args' ] );
|
2194 |
-
|
2195 |
-
return $_args;
|
2196 |
-
}
|
2197 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class wp_slimstat_reports {
|
4 |
+
|
5 |
+
// Structures to store all the information about what screens and reports are available
|
6 |
+
public static $reports_info = array();
|
7 |
+
public static $user_reports = array();
|
8 |
+
|
9 |
+
// Useful data for the reports
|
10 |
+
protected static $pageviews = 0;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Initalize class properties
|
14 |
+
*/
|
15 |
+
public static function init(){
|
16 |
+
|
17 |
+
// Include and initialize the API to interact with the database
|
18 |
+
include_once( 'wp-slimstat-db.php' );
|
19 |
+
wp_slimstat_db::init();
|
20 |
+
|
21 |
+
// Retrieve data that will be used by multiple reports
|
22 |
+
self::$pageviews = wp_slimstat_db::count_records();
|
23 |
+
|
24 |
+
// Define all the reports
|
25 |
+
//
|
26 |
+
// Parameters
|
27 |
+
// - title : report name
|
28 |
+
// - callback : function to use to render the report
|
29 |
+
// - callback_args : parameters to pass to the function
|
30 |
+
// - classes : determine the look and feel of this report ( tall, large, extralarge, full-width, hidden )
|
31 |
+
// - screens : where should the report appear ( slimview1, .., slimview4, dashboard )
|
32 |
+
// - tooltip : contextual help to be displayed on hover
|
33 |
+
|
34 |
+
$chart_tooltip = '<strong>' . __( 'Chart controls', 'wp-slimstat' ) . '</strong><ul><li>' . __( 'Use your mouse wheel to zoom in and out', 'wp-slimstat' ) . '</li><li>' . __( 'While zooming in, drag the chart to move to a different area', 'wp-slimstat' ) . '</li></ul>';
|
35 |
+
|
36 |
+
self::$reports_info = array(
|
37 |
+
'slim_p7_02' => array(
|
38 |
+
'title' => __( 'Visitors Activity', 'wp-slimstat' ),
|
39 |
+
'callback' => array( __CLASS__, 'show_activity_log' ),
|
40 |
+
'callback_args' => array(
|
41 |
+
'type' => 'recent',
|
42 |
+
'columns' => '*',
|
43 |
+
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
44 |
+
),
|
45 |
+
'classes' => array( 'full-width', 'tall' ),
|
46 |
+
'screens' => array( 'slimview1', 'dashboard' ),
|
47 |
+
'tooltip' => __( 'Color codes', 'wp-slimstat' ).'</strong><p><span class="little-color-box is-search-engine"></span> '.__( 'From search result page', 'wp-slimstat' ).'</p><p><span class="little-color-box is-known-visitor"></span> '.__( 'Known Visitor', 'wp-slimstat' ).'</p><p><span class="little-color-box is-known-user"></span> '.__( 'Known Users', 'wp-slimstat' ).'</p><p><span class="little-color-box is-direct"></span> '.__( 'Other Humans', 'wp-slimstat' ).'</p><p><span class="little-color-box"></span> '.__( 'Bot or Crawler', 'wp-slimstat' ).'</p>'
|
48 |
+
),
|
49 |
+
|
50 |
+
'slim_p1_01' => array(
|
51 |
+
'title' => __( 'Pageviews', 'wp-slimstat' ),
|
52 |
+
'callback' => array( __CLASS__, 'show_chart' ),
|
53 |
+
'callback_args' => array(
|
54 |
+
'id' => 'slim_p1_01',
|
55 |
+
'chart_data' => array(
|
56 |
+
'data1' => 'COUNT( ip )',
|
57 |
+
'data2' => 'COUNT( DISTINCT ip )'
|
58 |
+
),
|
59 |
+
'chart_labels' => array(
|
60 |
+
__( 'Pageviews', 'wp-slimstat' ),
|
61 |
+
__( 'Unique IPs', 'wp-slimstat' )
|
62 |
+
)
|
63 |
+
),
|
64 |
+
'classes' => array( 'extralarge', 'chart' ),
|
65 |
+
'screens' => array( 'slimview2', 'dashboard' ),
|
66 |
+
'tooltip' => $chart_tooltip
|
67 |
+
),
|
68 |
+
'slim_p1_02' => array(
|
69 |
+
'title' => __( 'About Slimstat', 'wp-slimstat' ),
|
70 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
71 |
+
'callback_args' => array(
|
72 |
+
'raw' => array( __CLASS__, 'get_about_wpslimstat' )
|
73 |
+
),
|
74 |
+
'classes' => array( 'normal', 'hidden' ),
|
75 |
+
'screens' => array( 'slimview2' )
|
76 |
+
),
|
77 |
+
'slim_p1_03' => array(
|
78 |
+
'title' => __( 'Traffic at a Glance', 'wp-slimstat' ),
|
79 |
+
// 'callback' => array( __CLASS__, 'show_overview_summary' ),
|
80 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
81 |
+
'callback_args' => array(
|
82 |
+
'raw' => array( __CLASS__, 'get_overview_summary' )
|
83 |
+
),
|
84 |
+
'classes' => array( 'normal' ),
|
85 |
+
'screens' => array( 'slimview2', 'dashboard' )
|
86 |
+
),
|
87 |
+
'slim_p1_04' => array(
|
88 |
+
'title' => __( 'Currently Online', 'wp-slimstat' ),
|
89 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
90 |
+
'callback_args' => array(
|
91 |
+
'type' => 'recent',
|
92 |
+
'columns' => 'ip',
|
93 |
+
'where' => 'dt_out > '. ( date_i18n( 'U' ) - 300 ) . ' OR dt > '. ( date_i18n( 'U' ) - 300 ),
|
94 |
+
'use_date_filters' => false,
|
95 |
+
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
96 |
+
),
|
97 |
+
'classes' => array( 'normal' ),
|
98 |
+
'screens' => array( 'slimview2', 'dashboard' )
|
99 |
+
),
|
100 |
+
'slim_p1_06' => array(
|
101 |
+
'title' => __( 'Recent Search Terms', 'wp-slimstat' ),
|
102 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
103 |
+
'callback_args' => array(
|
104 |
+
'type' => 'recent',
|
105 |
+
'columns' => 'searchterms',
|
106 |
+
'where' => 'searchterms <> "_" AND searchterms <> "" AND searchterms IS NOT NULL',
|
107 |
+
'more_columns' => 'referer, resource',
|
108 |
+
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
109 |
+
),
|
110 |
+
'classes' => array( 'normal' ),
|
111 |
+
'screens' => array( 'slimview2', 'slimview5' ),
|
112 |
+
'tooltip' => __( 'Keywords used by your visitors to find your website on a search engine.', 'wp-slimstat' )
|
113 |
+
),
|
114 |
+
'slim_p1_08' => array(
|
115 |
+
'title' => __( 'Top Web Pages', 'wp-slimstat' ),
|
116 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
117 |
+
'callback_args' => array(
|
118 |
+
'type' => 'top',
|
119 |
+
'columns' => 'SUBSTRING_INDEX(resource, "' . ( !get_option( 'permalink_structure' ) ? '&' : '?' ) . '", 1)',
|
120 |
+
'as_column' => 'resource_calculated',
|
121 |
+
'filter_op' => 'contains',
|
122 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
123 |
+
),
|
124 |
+
'classes' => array( 'normal' ),
|
125 |
+
'screens' => array( 'slimview2', 'dashboard' ),
|
126 |
+
'tooltip' => __( 'Here a "page" is not just a WordPress page type, but any webpage on your site, including posts, products, categories, and so on. You can set the corresponding filter where Resource Content Type equals cpt:you_cpt_slug_here to get top web pages for a specific custom post type you have.', 'wp-slimstat' )
|
127 |
+
),
|
128 |
+
'slim_p1_10' => array(
|
129 |
+
'title' => __('Top Referring Domains', 'wp-slimstat'),
|
130 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
131 |
+
'callback_args' => array(
|
132 |
+
'type' => 'top',
|
133 |
+
'columns' => 'REPLACE( SUBSTRING_INDEX( ( SUBSTRING_INDEX( ( SUBSTRING_INDEX( referer, "://", -1 ) ), "/", 1 ) ), ".", -5 ), "www.", "" )',
|
134 |
+
'as_column' => 'referer_calculated',
|
135 |
+
'filter_op' => 'contains',
|
136 |
+
'where' => 'referer NOT LIKE "%' . str_replace( 'www.', '', parse_url( home_url(), PHP_URL_HOST ) ) . '%"',
|
137 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
138 |
+
),
|
139 |
+
'classes' => array( 'normal' ),
|
140 |
+
'screens' => array( 'slimview2', 'slimview5', 'dashboard' )
|
141 |
+
),
|
142 |
+
'slim_p1_11' => array(
|
143 |
+
'title' => __( 'Top Known Visitors', 'wp-slimstat' ),
|
144 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
145 |
+
'callback_args' => array(
|
146 |
+
'type' => 'top',
|
147 |
+
'columns' => 'username',
|
148 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
149 |
+
),
|
150 |
+
'classes' => array( 'normal', 'hidden' ),
|
151 |
+
'screens' => array( 'slimview2', 'dashboard' )
|
152 |
+
),
|
153 |
+
'slim_p1_12' => array(
|
154 |
+
'title' => __( 'Top Search Terms', 'wp-slimstat' ),
|
155 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
156 |
+
'callback_args' => array(
|
157 |
+
'type' => 'top',
|
158 |
+
'columns' => 'searchterms',
|
159 |
+
'where' => 'searchterms <> "_" AND searchterms <> "" AND searchterms IS NOT NULL',
|
160 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
161 |
+
),
|
162 |
+
'classes' => array( 'normal' ),
|
163 |
+
'screens' => array( 'slimview2', 'slimview4', 'slimview5', 'dashboard' )
|
164 |
+
),
|
165 |
+
'slim_p1_13' => array(
|
166 |
+
'title' => __( 'Top Countries', 'wp-slimstat' ),
|
167 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
168 |
+
'callback_args' => array(
|
169 |
+
'type' => 'top',
|
170 |
+
'columns' => 'country',
|
171 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
172 |
+
),
|
173 |
+
'classes' => array( 'normal', 'hidden' ),
|
174 |
+
'screens' => array( 'slimview2', 'slimview3', 'slimview5', 'dashboard' ),
|
175 |
+
'tooltip' => __( 'You can configure Slimstat to ignore a specific Country by setting the corresponding filter under Settings > Slimstat > Filters.', 'wp-slimstat' )
|
176 |
+
),
|
177 |
+
'slim_p1_15' => array(
|
178 |
+
'title' => __( 'Rankings', 'wp-slimstat' ),
|
179 |
+
'callback' => array( __CLASS__, 'show_rankings' ),
|
180 |
+
'callback_args' => array(
|
181 |
+
'id' => 'slim_p1_15'
|
182 |
+
),
|
183 |
+
'classes' => array( 'normal', 'hidden' ),
|
184 |
+
'screens' => array( 'slimview2' ),
|
185 |
+
'tooltip' => __( "Slimstat retrieves live information from Alexa, Facebook and Mozscape, to measures your site's rankings. Values are updated every 12 hours. Please enter your personal access ID in the settings to access your personalized Mozscape data.", 'wp-slimstat' )
|
186 |
+
),
|
187 |
+
'slim_p1_17' => array(
|
188 |
+
'title' => __( 'Top Language Families', 'wp-slimstat' ),
|
189 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
190 |
+
'callback_args' => array(
|
191 |
+
'type' => 'top',
|
192 |
+
'columns' => 'SUBSTRING(language, 1, 2)',
|
193 |
+
'as_column' => 'language_calculated',
|
194 |
+
'filter_op' => 'contains',
|
195 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
196 |
+
),
|
197 |
+
'classes' => array( 'normal', 'hidden' ),
|
198 |
+
'screens' => array( 'slimview3' )
|
199 |
+
),
|
200 |
+
'slim_p1_18' => array(
|
201 |
+
'title' => __( 'Users Currently Online', 'wp-slimstat' ),
|
202 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
203 |
+
'callback_args' => array(
|
204 |
+
'type' => 'recent',
|
205 |
+
'columns' => 'username',
|
206 |
+
'where' => 'dt_out > '. ( date_i18n( 'U' ) - 300 ) . ' OR dt > '. ( date_i18n( 'U' ) - 300 ),
|
207 |
+
'use_date_filters' => false,
|
208 |
+
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
209 |
+
),
|
210 |
+
'classes' => array( 'normal', 'hidden' ),
|
211 |
+
'screens' => array( 'slimview2', 'dashboard' ),
|
212 |
+
'tooltip' => __( 'When visitors leave a comment on your blog, WordPress assigns them a cookie. Slimstat leverages this information to identify returning visitors. Please note that visitors also include registered users.', 'wp-slimstat' )
|
213 |
+
),
|
214 |
+
'slim_p1_19_01' => array( // Chart Reports need to always have a _01 suffix to tell our custom "refresh" code to avoid fading the chart, which apparently doesn't work
|
215 |
+
'title' => __( 'Search Terms', 'wp-slimstat' ),
|
216 |
+
'callback' => array( __CLASS__, 'show_chart' ),
|
217 |
+
'callback_args' => array(
|
218 |
+
'id' => 'slim_p1_19_01',
|
219 |
+
'chart_data' => array(
|
220 |
+
'data1' => 'COUNT( searchterms )',
|
221 |
+
'data2' => 'COUNT( DISTINCT searchterms )',
|
222 |
+
'where' => 'searchterms <> "_" AND searchterms IS NOT NULL AND searchterms <> ""'
|
223 |
+
),
|
224 |
+
'chart_labels' => array(
|
225 |
+
__( 'Search Terms', 'wp-slimstat' ),
|
226 |
+
__( 'Unique Terms', 'wp-slimstat' )
|
227 |
+
)
|
228 |
+
),
|
229 |
+
'classes' => array( 'extralarge', 'chart' ),
|
230 |
+
'screens' => array( 'slimview2' ),
|
231 |
+
'tooltip' => $chart_tooltip
|
232 |
+
),
|
233 |
+
'slim_p1_20' => array(
|
234 |
+
'title' => __('Top Referring URLs', 'wp-slimstat'),
|
235 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
236 |
+
'callback_args' => array(
|
237 |
+
'type' => 'top',
|
238 |
+
'columns' => 'referer',
|
239 |
+
'where' => 'referer NOT LIKE "%' . str_replace( 'www.', '', parse_url( home_url(), PHP_URL_HOST ) ) . '%"',
|
240 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
241 |
+
),
|
242 |
+
'classes' => array( 'normal' ),
|
243 |
+
'screens' => array( 'slimview2', 'slimview5', 'dashboard' )
|
244 |
+
),
|
245 |
+
|
246 |
+
'slim_p2_01' => array(
|
247 |
+
'title' => __( 'Human Visits', 'wp-slimstat' ),
|
248 |
+
'callback' => array( __CLASS__, 'show_chart' ),
|
249 |
+
'callback_args' => array(
|
250 |
+
'id' => 'slim_p2_01',
|
251 |
+
'chart_data' => array(
|
252 |
+
'data1' => 'COUNT( DISTINCT visit_id )',
|
253 |
+
'data2' => 'COUNT( DISTINCT ip )',
|
254 |
+
'where' => '(visit_id > 0 AND browser_type <> 1)'
|
255 |
+
),
|
256 |
+
'chart_labels' => array(
|
257 |
+
__( 'Visits', 'wp-slimstat' ),
|
258 |
+
__( 'Unique IPs', 'wp-slimstat' )
|
259 |
+
)
|
260 |
+
),
|
261 |
+
'classes' => array( 'extralarge', 'chart' ),
|
262 |
+
'screens' => array( 'slimview3' ),
|
263 |
+
'tooltip' => $chart_tooltip
|
264 |
+
),
|
265 |
+
'slim_p2_02' => array(
|
266 |
+
'title' => __( 'Audience Overview', 'wp-slimstat' ),
|
267 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
268 |
+
'callback_args' => array(
|
269 |
+
'raw' => array( __CLASS__, 'get_visitors_summary' )
|
270 |
+
),
|
271 |
+
'classes' => array( 'normal' ),
|
272 |
+
'screens' => array( 'slimview3', 'dashboard' ),
|
273 |
+
'tooltip' => __( 'Where not otherwise specified, the metrics in this report are referred to human visitors.', 'wp-slimstat' )
|
274 |
+
),
|
275 |
+
'slim_p2_03' => array(
|
276 |
+
'title' => __( 'Top Languages', 'wp-slimstat' ),
|
277 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
278 |
+
'callback_args' => array(
|
279 |
+
'type' => 'top',
|
280 |
+
'columns' => 'language',
|
281 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
282 |
+
),
|
283 |
+
'classes' => array( 'normal' ),
|
284 |
+
'screens' => array( 'slimview3' )
|
285 |
+
),
|
286 |
+
'slim_p2_04' => array(
|
287 |
+
'title' => __( 'Top Browsers', 'wp-slimstat' ),
|
288 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
289 |
+
'callback_args' => array(
|
290 |
+
'type' => 'top',
|
291 |
+
'columns' => 'browser, browser_version',
|
292 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
293 |
+
),
|
294 |
+
'classes' => array( 'normal' ),
|
295 |
+
'screens' => array( 'slimview3', 'dashboard' )
|
296 |
+
),
|
297 |
+
'slim_p2_05' => array(
|
298 |
+
'title' => __( 'Top Service Providers', 'wp-slimstat' ),
|
299 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
300 |
+
'callback_args' => array(
|
301 |
+
'type' => 'top',
|
302 |
+
'columns' => 'ip',
|
303 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
304 |
+
),
|
305 |
+
'classes' => array( 'extralarge', 'hidden' ),
|
306 |
+
'screens' => array( 'slimview3' ),
|
307 |
+
'tooltip' => __( 'Internet Service Provider: a company which provides other companies or individuals with access to the Internet. Your DSL or cable internet service is provided to you by your ISP.<br><br>You can ignore specific IP addresses by setting the corresponding filter under Settings > Slimstat > Filters.', 'wp-slimstat' )
|
308 |
+
),
|
309 |
+
'slim_p2_06' => array(
|
310 |
+
'title' => __( 'Top Operating Systems', 'wp-slimstat' ),
|
311 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
312 |
+
'callback_args' => array(
|
313 |
+
'type' => 'top',
|
314 |
+
'columns' => 'platform',
|
315 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
316 |
+
),
|
317 |
+
'classes' => array( 'normal', 'hidden' ),
|
318 |
+
'screens' => array( 'slimview3' ),
|
319 |
+
'tooltip' => __( 'Internet Service Provider: a company which provides other companies or individuals with access to the Internet. Your DSL or cable internet service is provided to you by your ISP.<br><br>You can ignore specific IP addresses by setting the corresponding filter under Settings > Slimstat > Filters.', 'wp-slimstat' )
|
320 |
+
),
|
321 |
+
'slim_p2_07' => array(
|
322 |
+
'title' => __( 'Top Screen Resolutions', 'wp-slimstat' ),
|
323 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
324 |
+
'callback_args' => array(
|
325 |
+
'type' => 'top',
|
326 |
+
'columns' => 'screen_width, screen_height',
|
327 |
+
'where' => 'screen_width <> 0 AND screen_height <> 0',
|
328 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
329 |
+
),
|
330 |
+
'classes' => array( 'normal' ),
|
331 |
+
'screens' => array( 'slimview3', 'dashboard' )
|
332 |
+
),
|
333 |
+
'slim_p2_08' => array(
|
334 |
+
'title' => __( 'Top Viewport Sizes', 'wp-slimstat' ),
|
335 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
336 |
+
'callback_args' => array(
|
337 |
+
'type' => 'top',
|
338 |
+
'columns' => 'resolution',
|
339 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
340 |
+
),
|
341 |
+
'classes' => array( 'normal', 'hidden' ),
|
342 |
+
'screens' => array( 'slimview3' )
|
343 |
+
),
|
344 |
+
'slim_p2_09' => array(
|
345 |
+
'title' => __( 'Browser Capabilities', 'wp-slimstat' ),
|
346 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
347 |
+
'callback_args' => array(
|
348 |
+
'raw' => array( __CLASS__, 'get_plugins' )
|
349 |
+
),
|
350 |
+
'classes' => array( 'normal', 'hidden' ),
|
351 |
+
'screens' => array( 'slimview3' )
|
352 |
+
),
|
353 |
+
'slim_p2_12' => array(
|
354 |
+
'title' => __( 'Visit Duration', 'wp-slimstat' ),
|
355 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
356 |
+
'callback_args' => array(
|
357 |
+
'raw' => array( __CLASS__, 'get_visits_duration' )
|
358 |
+
),
|
359 |
+
'classes' => array( 'normal', 'hidden' ),
|
360 |
+
'screens' => array( 'slimview3' ),
|
361 |
+
'tooltip' => __( 'All values represent the percentages of pageviews within the corresponding time range.', 'wp-slimstat' )
|
362 |
+
),
|
363 |
+
'slim_p2_13' => array(
|
364 |
+
'title' => __( 'Recent Countries', 'wp-slimstat' ),
|
365 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
366 |
+
'callback_args' => array(
|
367 |
+
'type' => 'recent',
|
368 |
+
'columns' => 'country',
|
369 |
+
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
370 |
+
),
|
371 |
+
'classes' => array( 'normal', 'hidden' ),
|
372 |
+
'screens' => array( 'slimview3', 'slimview5' )
|
373 |
+
),
|
374 |
+
'slim_p2_14' => array(
|
375 |
+
'title' => __( 'Recent Viewport Sizes', 'wp-slimstat' ),
|
376 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
377 |
+
'callback_args' => array(
|
378 |
+
'type' => 'recent',
|
379 |
+
'columns' => 'resolution',
|
380 |
+
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
381 |
+
),
|
382 |
+
'classes' => array( 'normal', 'hidden' ),
|
383 |
+
'screens' => array( 'slimview3' )
|
384 |
+
),
|
385 |
+
'slim_p2_15' => array(
|
386 |
+
'title' => __( 'Recent Operating Systems', 'wp-slimstat' ),
|
387 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
388 |
+
'callback_args' => array(
|
389 |
+
'type' => 'recent',
|
390 |
+
'columns' => 'platform',
|
391 |
+
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
392 |
+
),
|
393 |
+
'classes' => array( 'normal', 'hidden' ),
|
394 |
+
'screens' => array( 'slimview3' )
|
395 |
+
),
|
396 |
+
'slim_p2_16' => array(
|
397 |
+
'title' => __( 'Recent Browsers', 'wp-slimstat' ),
|
398 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
399 |
+
'callback_args' => array(
|
400 |
+
'type' => 'recent',
|
401 |
+
'columns' => 'browser, browser_version',
|
402 |
+
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
403 |
+
),
|
404 |
+
'classes' => array( 'normal', 'hidden' ),
|
405 |
+
'screens' => array( 'slimview3' )
|
406 |
+
),
|
407 |
+
'slim_p2_17' => array(
|
408 |
+
'title' => __( 'Recent Languages', 'wp-slimstat' ),
|
409 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
410 |
+
'callback_args' => array(
|
411 |
+
'type' => 'recent',
|
412 |
+
'columns' => 'language',
|
413 |
+
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
414 |
+
),
|
415 |
+
'classes' => array( 'normal', 'hidden' ),
|
416 |
+
'screens' => array( 'slimview3' )
|
417 |
+
),
|
418 |
+
'slim_p2_18' => array(
|
419 |
+
'title' => __( 'Top Browser Families', 'wp-slimstat' ),
|
420 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
421 |
+
'callback_args' => array(
|
422 |
+
'type' => 'top',
|
423 |
+
'columns' => 'browser',
|
424 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
425 |
+
),
|
426 |
+
'classes' => array( 'normal', 'hidden' ),
|
427 |
+
'screens' => array( 'slimview3' ),
|
428 |
+
'tooltip' => __( 'This report shows you what user agent families (no version considered) are popular among your visitors.', 'wp-slimstat' )
|
429 |
+
),
|
430 |
+
'slim_p2_19' => array(
|
431 |
+
'title' => __( 'Top OS Families', 'wp-slimstat' ),
|
432 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
433 |
+
'callback_args' => array(
|
434 |
+
'type' => 'top',
|
435 |
+
'columns' => 'CONCAT("p-", SUBSTRING(platform, 1, 3))',
|
436 |
+
'as_column' => 'platform_calculated',
|
437 |
+
'filter_op' => 'contains',
|
438 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
439 |
+
),
|
440 |
+
'classes' => array( 'normal' ),
|
441 |
+
'screens' => array( 'slimview3' ),
|
442 |
+
'tooltip' => __( 'This report shows you what operating system families (no version considered) are popular among your visitors.', 'wp-slimstat' )
|
443 |
+
),
|
444 |
+
'slim_p2_20' => array(
|
445 |
+
'title' => __( 'Recent Users', 'wp-slimstat' ),
|
446 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
447 |
+
'callback_args' => array(
|
448 |
+
'type' => 'recent',
|
449 |
+
'columns' => 'username',
|
450 |
+
'where' => 'notes LIKE "%user:%"',
|
451 |
+
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
452 |
+
),
|
453 |
+
'classes' => array( 'normal' ),
|
454 |
+
'screens' => array( 'slimview3' )
|
455 |
+
),
|
456 |
+
'slim_p2_21' => array(
|
457 |
+
'title' => __( 'Top Users', 'wp-slimstat' ),
|
458 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
459 |
+
'callback_args' => array(
|
460 |
+
'type' => 'top',
|
461 |
+
'columns' => 'username',
|
462 |
+
'where' => 'notes LIKE "%user:%"',
|
463 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
464 |
+
),
|
465 |
+
'classes' => array( 'normal', 'hidden' ),
|
466 |
+
'screens' => array( 'slimview3', 'dashboard' )
|
467 |
+
),
|
468 |
+
'slim_p2_22_01' => array( // Chart Reports need to always have a _01 suffix to tell our custom "refresh" code to avoid fading the chart, which apparently doesn't work
|
469 |
+
'title' => __( 'Users', 'wp-slimstat' ),
|
470 |
+
'callback' => array( __CLASS__, 'show_chart' ),
|
471 |
+
'callback_args' => array(
|
472 |
+
'id' => 'slim_p2_22_01',
|
473 |
+
'chart_data' => array(
|
474 |
+
'data1' => 'COUNT( username )',
|
475 |
+
'data2' => 'COUNT( DISTINCT username )'
|
476 |
+
),
|
477 |
+
'chart_labels' => array(
|
478 |
+
__( 'Users', 'wp-slimstat' ),
|
479 |
+
__( 'Unique Users', 'wp-slimstat' )
|
480 |
+
)
|
481 |
+
),
|
482 |
+
'classes' => array( 'extralarge', 'chart' ),
|
483 |
+
'screens' => array( 'slimview3' ),
|
484 |
+
'tooltip' => $chart_tooltip
|
485 |
+
),
|
486 |
+
|
487 |
+
'slim_p3_01' => array(
|
488 |
+
'title' => __( 'Traffic Sources', 'wp-slimstat' ),
|
489 |
+
'callback' => array( __CLASS__, 'show_chart' ),
|
490 |
+
'callback_args' => array(
|
491 |
+
'id' => 'slim_p3_01',
|
492 |
+
'chart_data' => array(
|
493 |
+
'data1' => 'COUNT( DISTINCT referer )',
|
494 |
+
'data2' => 'COUNT( DISTINCT ip )',
|
495 |
+
'where' => '(referer IS NOT NULL AND referer NOT LIKE "%' . home_url() . '%")'
|
496 |
+
),
|
497 |
+
'chart_labels' => array(
|
498 |
+
__( 'Domains', 'wp-slimstat' ),
|
499 |
+
__( 'Unique IPs', 'wp-slimstat' )
|
500 |
+
)
|
501 |
+
),
|
502 |
+
'classes' => array( 'extralarge', 'chart' ),
|
503 |
+
'screens' => array( 'slimview5' ),
|
504 |
+
'tooltip' => $chart_tooltip
|
505 |
+
),
|
506 |
+
'slim_p3_02' => array(
|
507 |
+
'title' => __( 'Traffic Summary', 'wp-slimstat' ),
|
508 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
509 |
+
'callback_args' => array(
|
510 |
+
'raw' => array( __CLASS__, 'get_traffic_sources_summary' )
|
511 |
+
),
|
512 |
+
'classes' => array( 'normal' ),
|
513 |
+
'screens' => array( 'slimview5' )
|
514 |
+
),
|
515 |
+
'slim_p3_06' => array(
|
516 |
+
'title' => __( 'Top Referring Search Engines', 'wp-slimstat' ),
|
517 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
518 |
+
'callback_args' => array(
|
519 |
+
'type' => 'top',
|
520 |
+
'columns' => 'REPLACE( SUBSTRING_INDEX( SUBSTRING_INDEX( SUBSTRING_INDEX( referer, "://", -1 ), "/", 1 ), ".", -5 ), "www.", "" )',
|
521 |
+
'as_column' => 'referer_calculated',
|
522 |
+
'filter_op' => 'contains',
|
523 |
+
'where' => 'searchterms IS NOT NULL AND searchterms <> "" AND searchterms <> "_" AND referer NOT LIKE "%' . str_replace( 'www.', '', parse_url( home_url(), PHP_URL_HOST ) ) . '%"',
|
524 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
525 |
+
),
|
526 |
+
'classes' => array( 'normal' ),
|
527 |
+
'screens' => array( 'slimview5', 'dashboard' )
|
528 |
+
),
|
529 |
+
|
530 |
+
'slim_p4_01' => array(
|
531 |
+
'title' => __( 'Recent Outbound Links', 'wp-slimstat' ),
|
532 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
533 |
+
'callback_args' => array(
|
534 |
+
'type' => 'recent',
|
535 |
+
'columns' => 'outbound_resource',
|
536 |
+
'raw' => array( 'wp_slimstat_db', 'get_recent_outbound' )
|
537 |
+
),
|
538 |
+
'classes' => array( 'large' ),
|
539 |
+
'screens' => array( 'slimview4' ),
|
540 |
+
'tooltip' => ''
|
541 |
+
),
|
542 |
+
'slim_p4_02' => array(
|
543 |
+
'title' => __( 'Recent Posts', 'wp-slimstat' ),
|
544 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
545 |
+
'callback_args' => array(
|
546 |
+
'type' => 'recent',
|
547 |
+
'columns' => 'resource',
|
548 |
+
'where' => 'content_type = "post"',
|
549 |
+
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
550 |
+
),
|
551 |
+
'classes' => array( 'normal' ),
|
552 |
+
'screens' => array( 'slimview4' )
|
553 |
+
),
|
554 |
+
'slim_p4_04' => array(
|
555 |
+
'title' => __( 'Recent Feeds', 'wp-slimstat' ),
|
556 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
557 |
+
'callback_args' => array(
|
558 |
+
'type' => 'recent',
|
559 |
+
'columns' => 'resource',
|
560 |
+
'where' => '(resource LIKE "%/feed%" OR resource LIKE "%?feed=>%" OR resource LIKE "%&feed=>%" OR content_type LIKE "%feed%")',
|
561 |
+
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
562 |
+
),
|
563 |
+
'classes' => array( 'normal', 'hidden' ),
|
564 |
+
'screens' => array( 'slimview4' )
|
565 |
+
),
|
566 |
+
'slim_p4_05' => array(
|
567 |
+
'title' => __( 'Recent Pages Not Found', 'wp-slimstat' ),
|
568 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
569 |
+
'callback_args' => array(
|
570 |
+
'type' => 'recent',
|
571 |
+
'columns' => 'resource',
|
572 |
+
'where' => '(resource LIKE "[404]%" OR content_type LIKE "%404%")',
|
573 |
+
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
574 |
+
),
|
575 |
+
'classes' => array( 'normal' ),
|
576 |
+
'screens' => array( 'slimview4' )
|
577 |
+
),
|
578 |
+
'slim_p4_06' => array(
|
579 |
+
'title' => __( 'Recent Internal Searches', 'wp-slimstat' ),
|
580 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
581 |
+
'callback_args' => array(
|
582 |
+
'type' => 'recent',
|
583 |
+
'columns' => 'searchterms',
|
584 |
+
'where' => 'content_type LIKE "%search%" AND searchterms <> "" AND searchterms IS NOT NULL',
|
585 |
+
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
586 |
+
),
|
587 |
+
'classes' => array( 'normal', 'hidden' ),
|
588 |
+
'screens' => array( 'slimview4' ),
|
589 |
+
'tooltip' => __( "Searches performed using WordPress' built-in search functionality.", 'wp-slimstat' )
|
590 |
+
),
|
591 |
+
'slim_p4_07' => array(
|
592 |
+
'title' => __( 'Top Categories', 'wp-slimstat' ),
|
593 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
594 |
+
'callback_args' => array(
|
595 |
+
'type' => 'top',
|
596 |
+
'columns' => 'category',
|
597 |
+
'where' => 'content_type LIKE "%category%"',
|
598 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
599 |
+
),
|
600 |
+
'classes' => array( 'normal' ),
|
601 |
+
'screens' => array( 'slimview4', 'dashboard' )
|
602 |
+
),
|
603 |
+
|
604 |
+
'slim_p4_09' => array(
|
605 |
+
'title' => __( 'Top Downloads', 'wp-slimstat' ),
|
606 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
607 |
+
'callback_args' => array(
|
608 |
+
'type' => 'top',
|
609 |
+
'columns' => 'resource',
|
610 |
+
'where' => 'content_type = "download"',
|
611 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' ),
|
612 |
+
'criteria' => 'swap'
|
613 |
+
),
|
614 |
+
'classes' => array( 'large', 'hidden' ),
|
615 |
+
'screens' => array( 'slimview4' ),
|
616 |
+
'tooltip' => __( 'You can configure Slimstat to track specific file extensions as downloads.', 'wp-slimstat' )
|
617 |
+
),
|
618 |
+
'slim_p4_10' => array(
|
619 |
+
'title' => __( 'Recent Events', 'wp-slimstat' ),
|
620 |
+
'callback' => array( __CLASS__, 'show_events' ),
|
621 |
+
'callback_args' => array(
|
622 |
+
'type' => 'recent',
|
623 |
+
'columns' => 'notes',
|
624 |
+
'raw' => array( 'wp_slimstat_db', 'get_recent_events' )
|
625 |
+
),
|
626 |
+
'classes' => array( 'normal', 'hidden' ),
|
627 |
+
'screens' => array( 'slimview4' ),
|
628 |
+
'tooltip' => __( 'This report lists any <em>event</em> occurred on your website. Please refer to the FAQ for more information on how to use this functionality.', 'wp-slimstat' )
|
629 |
+
),
|
630 |
+
'slim_p4_11' => array(
|
631 |
+
'title' => __( 'Top Posts', 'wp-slimstat' ),
|
632 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
633 |
+
'callback_args' => array(
|
634 |
+
'type' => 'top',
|
635 |
+
'columns' => 'resource',
|
636 |
+
'where' => 'content_type = "post"',
|
637 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
638 |
+
),
|
639 |
+
'classes' => array( 'normal' ),
|
640 |
+
'screens' => array( 'slimview4' )
|
641 |
+
),
|
642 |
+
'slim_p4_12' => array(
|
643 |
+
'title' => __( 'Top Events', 'wp-slimstat' ),
|
644 |
+
'callback' => array( __CLASS__, 'show_events' ),
|
645 |
+
'callback_args' => array(
|
646 |
+
'type' => 'top',
|
647 |
+
'columns' => 'notes',
|
648 |
+
'raw' => array( 'wp_slimstat_db', 'get_top_events' )
|
649 |
+
),
|
650 |
+
'classes' => array( 'normal', 'hidden' ),
|
651 |
+
'screens' => array( 'slimview4' ),
|
652 |
+
'tooltip' => __( 'This report lists any <em>event</em> occurred on your website. Please refer to the FAQ for more information on how to use this functionality.', 'wp-slimstat' )
|
653 |
+
),
|
654 |
+
'slim_p4_13' => array(
|
655 |
+
'title' => __( 'Top Internal Searches', 'wp-slimstat' ),
|
656 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
657 |
+
'callback_args' => array(
|
658 |
+
'type' => 'top',
|
659 |
+
'columns' => 'searchterms',
|
660 |
+
'where' => 'content_type LIKE "%search%" AND searchterms <> "" AND searchterms IS NOT NULL',
|
661 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
662 |
+
),
|
663 |
+
'classes' => array( 'normal', 'hidden' ),
|
664 |
+
'screens' => array( 'slimview4' )
|
665 |
+
),
|
666 |
+
'slim_p4_15' => array(
|
667 |
+
'title' => __( 'Recent Categories', 'wp-slimstat' ),
|
668 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
669 |
+
'callback_args' => array(
|
670 |
+
'type' => 'recent',
|
671 |
+
'columns' => 'resource',
|
672 |
+
'where' => '(content_type = "category" OR content_type = "tag")',
|
673 |
+
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
674 |
+
),
|
675 |
+
'classes' => array( 'normal', 'hidden' ),
|
676 |
+
'screens' => array( 'slimview4' )
|
677 |
+
),
|
678 |
+
'slim_p4_16' => array(
|
679 |
+
'title' => __( 'Top Pages Not Found', 'wp-slimstat' ),
|
680 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
681 |
+
'callback_args' => array(
|
682 |
+
'type' => 'top',
|
683 |
+
'columns' => 'resource',
|
684 |
+
'where' => 'content_type LIKE "%404%"',
|
685 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
686 |
+
),
|
687 |
+
'classes' => array( 'normal' ),
|
688 |
+
'screens' => array( 'slimview4' )
|
689 |
+
),
|
690 |
+
'slim_p4_18' => array(
|
691 |
+
'title' => __( 'Top Authors', 'wp-slimstat' ),
|
692 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
693 |
+
'callback_args' => array(
|
694 |
+
'type' => 'top',
|
695 |
+
'columns' => 'author',
|
696 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
697 |
+
),
|
698 |
+
'classes' => array( 'normal' ),
|
699 |
+
'screens' => array( 'slimview4', 'dashboard' )
|
700 |
+
),
|
701 |
+
'slim_p4_19' => array(
|
702 |
+
'title' => __( 'Top Tags', 'wp-slimstat' ),
|
703 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
704 |
+
'callback_args' => array(
|
705 |
+
'type' => 'top',
|
706 |
+
'columns' => 'category',
|
707 |
+
'where' => '(content_type LIKE "%tag%")',
|
708 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
709 |
+
),
|
710 |
+
'classes' => array( 'normal', 'hidden' ),
|
711 |
+
'screens' => array( 'slimview4' )
|
712 |
+
),
|
713 |
+
'slim_p4_20' => array(
|
714 |
+
'title' => __( 'Recent Downloads', 'wp-slimstat' ),
|
715 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
716 |
+
'callback_args' => array(
|
717 |
+
'type' => 'recent',
|
718 |
+
'columns' => 'resource',
|
719 |
+
'where' => 'content_type = "download"',
|
720 |
+
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
721 |
+
),
|
722 |
+
'classes' => array( 'large', 'hidden' ),
|
723 |
+
'screens' => array( 'slimview4' )
|
724 |
+
),
|
725 |
+
'slim_p4_21' => array(
|
726 |
+
'title' => __( 'Top Outbound Links', 'wp-slimstat' ),
|
727 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
728 |
+
'callback_args' => array(
|
729 |
+
'type' => 'top',
|
730 |
+
'columns' => 'outbound_resource',
|
731 |
+
'raw' => array( 'wp_slimstat_db', 'get_top_outbound' ),
|
732 |
+
'criteria' => 'swap'
|
733 |
+
),
|
734 |
+
'classes' => array( 'normal', 'hidden' ),
|
735 |
+
'screens' => array( 'slimview4', 'dashboard' ),
|
736 |
+
),
|
737 |
+
'slim_p4_22' => array(
|
738 |
+
'title' => __( 'Your Website', 'wp-slimstat' ),
|
739 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
740 |
+
'callback_args' => array(
|
741 |
+
'raw' => array( __CLASS__, 'get_your_blog' )
|
742 |
+
),
|
743 |
+
'classes' => array( 'normal', 'hidden' ),
|
744 |
+
'screens' => array( 'slimview4' ),
|
745 |
+
'tooltip' => __( 'Your content at a glance: posts, comments, pingbacks, etc. Please note that this report is not affected by the filters set here above.', 'wp-slimstat' )
|
746 |
+
),
|
747 |
+
'slim_p4_23' => array(
|
748 |
+
'title' => __( 'Top Bounce Pages', 'wp-slimstat' ),
|
749 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
750 |
+
'callback_args' => array(
|
751 |
+
'type' => 'top',
|
752 |
+
'columns' => 'resource',
|
753 |
+
'where' => 'content_type <> "404"',
|
754 |
+
'having' => 'HAVING COUNT(visit_id) = 1',
|
755 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
756 |
+
),
|
757 |
+
'classes' => array( 'normal', 'hidden' ),
|
758 |
+
'screens' => array( 'slimview4' )
|
759 |
+
),
|
760 |
+
'slim_p4_24' => array(
|
761 |
+
'title' => __( 'Top Exit Pages', 'wp-slimstat' ),
|
762 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
763 |
+
'callback_args' => array(
|
764 |
+
'type' => 'top',
|
765 |
+
'columns' => 'visit_id',
|
766 |
+
'outer_select_column' => 'resource',
|
767 |
+
'aggr_function' => 'MAX',
|
768 |
+
'raw' => array( 'wp_slimstat_db', 'get_top_aggr' )
|
769 |
+
),
|
770 |
+
'classes' => array( 'large', 'hidden' ),
|
771 |
+
'screens' => array( 'slimview4', 'dashboard' )
|
772 |
+
),
|
773 |
+
'slim_p4_25' => array(
|
774 |
+
'title' => __( 'Top Entry Pages', 'wp-slimstat' ),
|
775 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
776 |
+
'callback_args' => array(
|
777 |
+
'type' => 'top',
|
778 |
+
'columns' => 'visit_id',
|
779 |
+
'outer_select_column' => 'resource',
|
780 |
+
'aggr_function' => 'MIN',
|
781 |
+
'raw' => array( 'wp_slimstat_db', 'get_top_aggr' )
|
782 |
+
),
|
783 |
+
'classes' => array( 'large', 'hidden' ),
|
784 |
+
'screens' => array( 'slimview4' )
|
785 |
+
),
|
786 |
+
'slim_p4_26_01' => array( // Chart Reports need to always have a _01 suffix to tell our custom "refresh" code to avoid fading the chart, which apparently doesn't work
|
787 |
+
'title' => __( 'Pages with Outbound Links', 'wp-slimstat' ),
|
788 |
+
'callback' => array( __CLASS__, 'show_chart' ),
|
789 |
+
'callback_args' => array(
|
790 |
+
'id' => 'slim_p4_26_01',
|
791 |
+
'chart_data' => array(
|
792 |
+
'data1' => 'COUNT( outbound_resource )',
|
793 |
+
'data2' => 'COUNT( DISTINCT outbound_resource )'
|
794 |
+
),
|
795 |
+
'chart_labels' => array(
|
796 |
+
__( 'Outbound Links', 'wp-slimstat' ),
|
797 |
+
__( 'Unique Outbound', 'wp-slimstat' )
|
798 |
+
)
|
799 |
+
),
|
800 |
+
'classes' => array( 'extralarge', 'chart' ),
|
801 |
+
'screens' => array( 'slimview4' ),
|
802 |
+
'tooltip' => $chart_tooltip
|
803 |
+
),
|
804 |
+
|
805 |
+
'slim_p6_01' => array(
|
806 |
+
'title' => __( 'World Map', 'wp-slimstat' ),
|
807 |
+
'callback' => array( __CLASS__, 'show_world_map' ),
|
808 |
+
'callback_args' => array(
|
809 |
+
'id' => 'slim_p6_01'
|
810 |
+
),
|
811 |
+
'classes' => array( 'full-width', 'tall' ),
|
812 |
+
'screens' => array( 'slimview6' ),
|
813 |
+
'tooltip' => __( 'Dots on the map represent the most recent pageviews geolocated by City. This feature is only available by enabling the corresponding precision level in the settings.', 'wp-slimstat' )
|
814 |
+
)
|
815 |
+
);
|
816 |
+
|
817 |
+
if ( wp_slimstat::$settings[ 'geolocation_country' ] != 'on' ) {
|
818 |
+
self::$reports_info [ 'slim_p2_23' ] = array(
|
819 |
+
'title' => __( 'Top Cities', 'wp-slimstat' ),
|
820 |
+
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
821 |
+
'callback_args' => array(
|
822 |
+
'type' => 'top',
|
823 |
+
'columns' => 'city',
|
824 |
+
|
825 |
+
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
826 |
+
),
|
827 |
+
'classes' => array( 'normal' ),
|
828 |
+
'screens' => array( 'slimview3' )
|
829 |
+
);
|
830 |
+
}
|
831 |
+
|
832 |
+
// Allow third party tools to manipulate this list here above: please use unique report IDs that don't interfere with built-in ones, if you add your own custom report
|
833 |
+
self::$reports_info = apply_filters( 'slimstat_reports_info', self::$reports_info );
|
834 |
+
|
835 |
+
// Define what reports have been deprecated over time, to remove them from the user's settings
|
836 |
+
$deprecated_reports = array(
|
837 |
+
'slim_p1_05' => 1,
|
838 |
+
'slim_p1_18' => 1,
|
839 |
+
'slim_p2_10' => 1,
|
840 |
+
'slim_p3_03' => 1,
|
841 |
+
'slim_p3_04' => 1,
|
842 |
+
'slim_p3_05' => 1,
|
843 |
+
'slim_p3_08' => 1,
|
844 |
+
'slim_p3_09' => 1,
|
845 |
+
'slim_p3_10' => 1,
|
846 |
+
'slim_p4_08' => 1,
|
847 |
+
'slim_p4_14' => 1,
|
848 |
+
'slim_p4_17' => 1,
|
849 |
+
'slim_getsocial' => 1
|
850 |
+
);
|
851 |
+
|
852 |
+
// Retrieve this user's list of active reports,
|
853 |
+
$current_user = wp_get_current_user();
|
854 |
+
$page_location = ( wp_slimstat::$settings[ 'use_separate_menu' ] == 'on' ) ? 'slimstat' : 'admin';
|
855 |
+
|
856 |
+
// Superadmins can customize the layout at network level, to override per-site settings
|
857 |
+
self::$user_reports = get_user_option( "meta-box-order_slimstat_page_slimlayout-network", 1 );
|
858 |
+
|
859 |
+
// No network-wide settings exist
|
860 |
+
if ( empty( self::$user_reports ) ) {
|
861 |
+
self::$user_reports = get_user_option( "meta-box-order_slimstat_page_slimlayout", $current_user->ID );
|
862 |
+
}
|
863 |
+
|
864 |
+
// Do this only if we are in one of our screens (no dashboard!)
|
865 |
+
if ( is_admin() && !empty( $_REQUEST[ 'page' ] ) && strpos( $_REQUEST[ 'page' ], 'slimview' ) !== false ) {
|
866 |
+
|
867 |
+
// If this list is not empty, we rearrange the order of our reports
|
868 |
+
if ( !empty( self::$user_reports[ $_REQUEST[ 'page' ] ] ) ) {
|
869 |
+
$user_reports_intersect = array_flip( explode( ',', self::$user_reports[ $_REQUEST[ 'page' ] ] ) );
|
870 |
+
self::$reports_info = array_intersect_key( array_merge( $user_reports_intersect, self::$reports_info ), $user_reports_intersect );
|
871 |
+
}
|
872 |
+
else {
|
873 |
+
foreach ( self::$reports_info as $a_report_id => $a_report_info ) {
|
874 |
+
if ( !in_array( $_REQUEST[ 'page' ], $a_report_info[ 'screens' ] ) ) {
|
875 |
+
unset( self::$reports_info[ $a_report_id ] );
|
876 |
+
}
|
877 |
+
}
|
878 |
+
}
|
879 |
+
|
880 |
+
// Remove deprecated reports
|
881 |
+
self::$reports_info = array_diff_key( self::$reports_info, $deprecated_reports );
|
882 |
+
|
883 |
+
$hidden_reports = get_user_option( "metaboxhidden_{$page_location}_page_{$_REQUEST['page']}", $current_user->ID );
|
884 |
+
|
885 |
+
// If this list is not empty, use it instead of the predefined visibility
|
886 |
+
if ( is_array( $hidden_reports ) ) {
|
887 |
+
foreach ( self::$reports_info as $a_report_id => $a_report_info ) {
|
888 |
+
if ( in_array( $a_report_id, $hidden_reports ) ) {
|
889 |
+
if ( is_array( self::$reports_info[ $a_report_id ][ 'classes' ] ) && !in_array( 'hidden', $a_report_info[ 'classes' ] ) ) {
|
890 |
+
self::$reports_info[ $a_report_id ][ 'classes' ][] = 'hidden';
|
891 |
+
}
|
892 |
+
}
|
893 |
+
else if ( is_array( self::$reports_info[ $a_report_id ][ 'classes' ] ) ) {
|
894 |
+
self::$reports_info[ $a_report_id ][ 'classes' ] = array_diff( self::$reports_info[ $a_report_id ][ 'classes' ], array( 'hidden' ) );
|
895 |
+
}
|
896 |
+
}
|
897 |
+
}
|
898 |
+
}
|
899 |
+
// If we are on the WP Dashboard page, all the reports are 'visible': WP will take care of honoring the Screen Options settings for that page
|
900 |
+
else if ( !empty( $_REQUEST['page'] ) && strpos( $_REQUEST['page'], 'slimlayout' ) === false ) {
|
901 |
+
foreach ( self::$reports_info as $a_report_id => $a_report_info ) {
|
902 |
+
if ( is_array( self::$reports_info[ $a_report_id ][ 'classes' ] ) ) {
|
903 |
+
self::$reports_info[ $a_report_id ][ 'classes' ] = array_diff( self::$reports_info[ $a_report_id ][ 'classes' ], array( 'hidden' ) );
|
904 |
+
}
|
905 |
+
}
|
906 |
+
}
|
907 |
+
}
|
908 |
+
// end init
|
909 |
+
|
910 |
+
public static function report_header( $_report_id = '' ) {
|
911 |
+
if ( empty( self::$reports_info[ $_report_id ] ) ) {
|
912 |
+
return false;
|
913 |
+
}
|
914 |
+
|
915 |
+
$header_classes = !empty( self::$reports_info[ $_report_id ][ 'classes' ] ) ? implode( ' ', self::$reports_info[ $_report_id ][ 'classes' ] ) : '';
|
916 |
+
$header_buttons = '';
|
917 |
+
$header_tooltip = '';
|
918 |
+
|
919 |
+
// Don't show the header buttons on the frontend
|
920 |
+
if ( is_admin() ) {
|
921 |
+
// Show the refresh button only if the time range is not in the past
|
922 |
+
if ( wp_slimstat_db::$filters_normalized[ 'utime' ][ 'end' ] >= date_i18n( 'U' ) - 300 ) {
|
923 |
+
$header_buttons = '<a class="noslimstat refresh slimstat-font-arrows-cw" title="'.__('Refresh','wp-slimstat').'" href="'.self::fs_url().'"></a>';
|
924 |
+
}
|
925 |
+
|
926 |
+
// Allow third-party code to add more buttons
|
927 |
+
$header_buttons = apply_filters( 'slimstat_report_header_buttons', $header_buttons, $_report_id );
|
928 |
+
$header_buttons = '<div class="slimstat-header-buttons">' . $header_buttons . '</div>';
|
929 |
+
$header_tooltip = !empty( self::$reports_info[ $_report_id ][ 'tooltip' ] ) ? '<i class="slimstat-tooltip-trigger corner"><span class="slimstat-tooltip-content">' . self::$reports_info[ $_report_id ][ 'tooltip' ] . '</span></i>' : '';
|
930 |
+
}
|
931 |
+
|
932 |
+
echo "<div class='postbox $header_classes' id='$_report_id'>{$header_buttons} <h3 data-report-id='{$_report_id}'>" . self::$reports_info[ $_report_id ][ 'title' ] . " {$header_tooltip}</h3><div class='inside'>";
|
933 |
+
}
|
934 |
+
|
935 |
+
public static function report_footer(){
|
936 |
+
echo '</div></div>';
|
937 |
+
}
|
938 |
+
|
939 |
+
public static function report_pagination( $_count_page_results = 0, $_count_all_results = 0, $_show_refresh_countdown = false, $_results_per_page = -1 ) {
|
940 |
+
if ( !is_admin() ) {
|
941 |
+
return '';
|
942 |
+
}
|
943 |
+
|
944 |
+
$_results_per_page = ( $_results_per_page < 0 ) ? wp_slimstat::$settings[ 'rows_to_show' ] : $_results_per_page;
|
945 |
+
|
946 |
+
$endpoint = min( $_count_all_results, wp_slimstat_db::$filters_normalized[ 'misc' ][ 'start_from' ] + $_results_per_page );
|
947 |
+
$pagination_buttons = '';
|
948 |
+
$direction_prev = is_rtl() ? 'right' : 'left';
|
949 |
+
$direction_next = is_rtl() ? 'left' : 'right';
|
950 |
+
|
951 |
+
if ( $endpoint + $_results_per_page < $_count_all_results && $_count_page_results > 0 ) {
|
952 |
+
$startpoint = $_count_all_results - $_count_all_results % $_results_per_page;
|
953 |
+
if ( $startpoint == $_count_all_results ) {
|
954 |
+
$startpoint -= $_results_per_page;
|
955 |
+
}
|
956 |
+
$pagination_buttons .= '<a class="refresh slimstat-font-angle-double-' . $direction_next . '" href="' . wp_slimstat_reports::fs_url( 'start_from equals ' . $startpoint ) . '"></a> ';
|
957 |
+
}
|
958 |
+
if ($endpoint < $_count_all_results && $_count_page_results > 0){
|
959 |
+
$startpoint = wp_slimstat_db::$filters_normalized['misc']['start_from'] + $_results_per_page;
|
960 |
+
$pagination_buttons .= '<a class="refresh slimstat-font-angle-'.$direction_next.'" href="' . wp_slimstat_reports::fs_url( 'start_from equals ' . $startpoint ) . '"></a> ';
|
961 |
+
}
|
962 |
+
if (wp_slimstat_db::$filters_normalized['misc']['start_from'] > 0){
|
963 |
+
$startpoint = (wp_slimstat_db::$filters_normalized['misc']['start_from'] > $_results_per_page)?wp_slimstat_db::$filters_normalized['misc']['start_from'] - $_results_per_page : 0;
|
964 |
+
$pagination_buttons .= '<a class="refresh slimstat-font-angle-'.$direction_prev.'" href="'.wp_slimstat_reports::fs_url('start_from equals '.$startpoint).'"></a> ';
|
965 |
+
}
|
966 |
+
if (wp_slimstat_db::$filters_normalized['misc']['start_from'] - $_results_per_page > 0){
|
967 |
+
$pagination_buttons .= '<a class="refresh slimstat-font-angle-double-'.$direction_prev.'" href="'.wp_slimstat_reports::fs_url('start_from equals 0').'"></a> ';
|
968 |
+
}
|
969 |
+
|
970 |
+
$pagination = '<p class="pagination">' . sprintf( __( 'Results %s - %s of %s', 'wp-slimstat' ), number_format( wp_slimstat_db::$filters_normalized[ 'misc' ][ 'start_from' ] + 1, 0, '', wp_slimstat_db::$formats[ 'thousand' ] ), number_format( $endpoint, 0, '', wp_slimstat_db::$formats[ 'thousand' ] ), number_format( $_count_all_results, 0, '', wp_slimstat_db::$formats[ 'thousand' ] ) . ( ( $_count_all_results == wp_slimstat::$settings[ 'limit_results' ] ) ? '+' : '') );
|
971 |
+
|
972 |
+
if ( $_show_refresh_countdown && wp_slimstat::$settings[ 'refresh_interval' ] > 0 && wp_slimstat_db::$filters_normalized[ 'utime' ][ 'end' ] >= date_i18n( 'U' ) - 300 ) {
|
973 |
+
$pagination .= ' [' . __( 'Refresh in', 'wp-slimstat' ) . ' <i class="refresh-timer"></i>]';
|
974 |
+
}
|
975 |
+
$pagination .= $pagination_buttons.'</p>';
|
976 |
+
|
977 |
+
return $pagination;
|
978 |
+
}
|
979 |
+
|
980 |
+
public static function callback_wrapper() {
|
981 |
+
$_args = self::_check_args( func_get_args() );
|
982 |
+
call_user_func( $_args[ 'callback' ] , $_args[ 'callback_args' ] );
|
983 |
+
}
|
984 |
+
|
985 |
+
public static function raw_results_to_html( $_args = array() ) {
|
986 |
+
if ( wp_slimstat::$settings[ 'async_load' ] == 'on' && ( !defined( 'DOING_AJAX' ) || !DOING_AJAX ) ) {
|
987 |
+
return '';
|
988 |
+
}
|
989 |
+
|
990 |
+
wp_slimstat_db::$debug_message = '';
|
991 |
+
|
992 |
+
$all_results = call_user_func( $_args[ 'raw' ] , $_args );
|
993 |
+
|
994 |
+
echo wp_slimstat_db::$debug_message;
|
995 |
+
|
996 |
+
// Some reports don't need any kind of pre/post-processing, we just display the data contained in the array
|
997 |
+
if ( empty( $_args[ 'columns' ] ) ) {
|
998 |
+
foreach ( $all_results as $a_result ) {
|
999 |
+
echo '<p>';
|
1000 |
+
|
1001 |
+
if ( !empty( $a_result[ 'tooltip' ] ) ) {
|
1002 |
+
self::inline_help( $a_result[ 'tooltip' ] );
|
1003 |
+
}
|
1004 |
+
|
1005 |
+
echo "{$a_result[ 'metric' ]} <span>{$a_result[ 'value' ]}</span>";
|
1006 |
+
|
1007 |
+
if ( !empty( $a_result[ 'details' ] ) ) {
|
1008 |
+
$is_expanded = ( wp_slimstat::$settings[ 'expand_details' ] == 'on' ) ? ' expanded' : '';
|
1009 |
+
echo "<b class='slimstat-tooltip-content$is_expanded'>{$a_result[ 'details' ]}</b>";
|
1010 |
+
}
|
1011 |
+
|
1012 |
+
echo '</p>';
|
1013 |
+
}
|
1014 |
+
}
|
1015 |
+
else {
|
1016 |
+
$results = array_slice(
|
1017 |
+
$all_results,
|
1018 |
+
wp_slimstat_db::$filters_normalized[ 'misc' ][ 'start_from' ],
|
1019 |
+
wp_slimstat::$settings[ 'rows_to_show' ]
|
1020 |
+
);
|
1021 |
+
|
1022 |
+
// Count the results
|
1023 |
+
$count_page_results = count( $results );
|
1024 |
+
|
1025 |
+
if ($count_page_results == 0){
|
1026 |
+
echo '<p class="nodata">' . __( 'No data to display', 'wp-slimstat' ) . '</p>';
|
1027 |
+
|
1028 |
+
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
1029 |
+
die();
|
1030 |
+
}
|
1031 |
+
else{
|
1032 |
+
return array();
|
1033 |
+
}
|
1034 |
+
}
|
1035 |
+
|
1036 |
+
// Some reports use aliases for column names
|
1037 |
+
if ( !empty( $_args[ 'as_column' ] ) ) {
|
1038 |
+
$_args[ 'columns' ] = $_args[ 'as_column' ];
|
1039 |
+
}
|
1040 |
+
else if ( !empty( $_args[ 'outer_select_column' ] ) ) {
|
1041 |
+
$_args[ 'columns' ] = $_args[ 'outer_select_column' ];
|
1042 |
+
}
|
1043 |
+
|
1044 |
+
// Some reports query more than one column
|
1045 |
+
if ( strpos( $_args[ 'columns' ], ',' ) !== false ) {
|
1046 |
+
$_args[ 'columns' ] = explode( ',', $_args[ 'columns' ] );
|
1047 |
+
$_args[ 'columns' ] = trim( $_args[ 'columns' ][ 0 ] );
|
1048 |
+
}
|
1049 |
+
|
1050 |
+
echo self::report_pagination( $count_page_results, count( $all_results ) );
|
1051 |
+
|
1052 |
+
$is_expanded = ( is_admin() && wp_slimstat::$settings[ 'expand_details' ] == 'on' ) ? ' expanded' : '';
|
1053 |
+
$permalinks_enabled = get_option( 'permalink_structure' );
|
1054 |
+
$column_not_calculated = str_replace( '_calculated', '', $_args[ 'columns' ] );
|
1055 |
+
|
1056 |
+
for($i=0; $i<$count_page_results; $i++){
|
1057 |
+
$row_details = $percentage = '';
|
1058 |
+
$element_pre_value = '';
|
1059 |
+
$element_value = $results[ $i ][ $_args[ 'columns' ] ];
|
1060 |
+
|
1061 |
+
// Some columns require a special pre-treatment
|
1062 |
+
switch ( $column_not_calculated ){
|
1063 |
+
|
1064 |
+
case 'browser':
|
1065 |
+
if ( !empty( $results[ $i ][ 'user_agent' ] ) && wp_slimstat::$settings[ 'show_complete_user_agent_tooltip' ] == 'on' ) {
|
1066 |
+
$element_pre_value = self::inline_help($results[$i]['user_agent'], false);
|
1067 |
+
}
|
1068 |
+
$element_value = $results[$i]['browser'].((isset($results[$i]['browser_version']) && intval($results[$i]['browser_version']) != 0)?' '.$results[$i]['browser_version']:'');
|
1069 |
+
break;
|
1070 |
+
|
1071 |
+
case 'category':
|
1072 |
+
$row_details = __( 'Category ID', 'wp-slimstat' ) . ": {$results[ $i ][ $_args[ 'columns' ] ]}";
|
1073 |
+
$element_value = get_cat_name( $results[ $i ][ $_args[ 'columns' ] ] );
|
1074 |
+
break;
|
1075 |
+
|
1076 |
+
case 'country':
|
1077 |
+
$row_details .= __('Code','wp-slimstat').": {$results[$i]['country']}";
|
1078 |
+
$element_value = __('c-'.$results[$i]['country'], 'wp-slimstat');
|
1079 |
+
break;
|
1080 |
+
|
1081 |
+
case 'ip':
|
1082 |
+
if ( wp_slimstat::$settings[ 'convert_ip_addresses' ] == 'on' ) {
|
1083 |
+
$element_value = gethostbyaddr( $results[ $i ][ $_args[ 'columns' ] ] );
|
1084 |
+
}
|
1085 |
+
else{
|
1086 |
+
$element_value = $results[ $i ][ $_args[ 'columns' ] ];
|
1087 |
+
}
|
1088 |
+
break;
|
1089 |
+
|
1090 |
+
case 'language':
|
1091 |
+
$row_details = __( 'Code', 'wp-slimstat' ) . ": {$results[ $i ][ $_args[ 'columns' ] ]}";
|
1092 |
+
$element_value = __( 'l-' . $results[ $i ][ $_args[ 'columns' ] ], 'wp-slimstat' );
|
1093 |
+
break;
|
1094 |
+
|
1095 |
+
case 'platform':
|
1096 |
+
$row_details = __( 'Code', 'wp-slimstat' ).": {$results[ $i ][ $_args[ 'columns' ] ]}";
|
1097 |
+
$element_value = __( $results[ $i ][ $_args[ 'columns' ] ], 'wp-slimstat' );
|
1098 |
+
$results[ $i ][ $_args[ 'columns' ] ] = str_replace( 'p-', '', $results[ $i ][ $_args[ 'columns' ] ] );
|
1099 |
+
break;
|
1100 |
+
|
1101 |
+
case 'referer':
|
1102 |
+
$element_value = str_replace( array( '<', '>' ), array( '<', '>' ), urldecode( $results[ $i ][ $_args[ 'columns' ] ] ) );
|
1103 |
+
//$element_value = parse_url( $element_value, PHP_URL_HOST );
|
1104 |
+
break;
|
1105 |
+
|
1106 |
+
case 'resource':
|
1107 |
+
$resource_title = self::get_resource_title( $results[ $i ][ $_args[ 'columns' ] ] );
|
1108 |
+
if ( $resource_title != $results[ $i ][ $_args[ 'columns' ] ] ) {
|
1109 |
+
$row_details = __( 'URL', 'wp-slimstat' ) . ': ' . htmlentities( $results[ $i ][ $_args[ 'columns' ] ], ENT_QUOTES, 'UTF-8' );
|
1110 |
+
}
|
1111 |
+
if ( !empty( $_args[ 'where' ] ) && strpos( $_args[ 'where' ], 'download' ) !== false ) {
|
1112 |
+
$clean_extension = pathinfo( strtolower( parse_url( $results[ $i ][ $_args[ 'columns' ] ], PHP_URL_PATH ) ), PATHINFO_EXTENSION );
|
1113 |
+
if ( in_array( $clean_extension, array( 'jpg', 'gif', 'png', 'jpeg', 'bmp' ) ) ) {
|
1114 |
+
$row_details = '<br><img src="' . $results[ $i ][ $_args[ 'columns' ] ] . '" style="width:100px">';
|
1115 |
+
}
|
1116 |
+
}
|
1117 |
+
$element_value = $resource_title;
|
1118 |
+
break;
|
1119 |
+
|
1120 |
+
case 'screen_width':
|
1121 |
+
$element_value = "{$results[ $i ][ $_args[ 'columns' ] ]} x {$results[ $i ][ 'screen_height' ]}";
|
1122 |
+
break;
|
1123 |
+
|
1124 |
+
case 'searchterms':
|
1125 |
+
if ( $_args[ 'type' ] == 'recent' ) {
|
1126 |
+
$domain = parse_url( $results[ $i ][ 'referer' ], PHP_URL_HOST );
|
1127 |
+
|
1128 |
+
$row_details = __( 'Referrer', 'wp-slimstat' ) . ": $domain";
|
1129 |
+
$element_value = self::get_search_terms_info( $results[ $i ][ 'searchterms' ], $results[ $i ][ 'referer' ], true );
|
1130 |
+
}
|
1131 |
+
else{
|
1132 |
+
$element_value = htmlentities( $results[ $i ][ 'searchterms' ], ENT_QUOTES, 'UTF-8' );
|
1133 |
+
}
|
1134 |
+
break;
|
1135 |
+
|
1136 |
+
case 'username':
|
1137 |
+
$element_value = $results[ $i ][ 'username' ];
|
1138 |
+
if ( wp_slimstat::$settings[ 'show_display_name' ] == 'on' ) {
|
1139 |
+
$element_custom_value = get_user_by( 'login', $results[ $i ][ 'username' ] );
|
1140 |
+
if ( is_object( $element_custom_value ) ) {
|
1141 |
+
$element_value = $element_custom_value->display_name;
|
1142 |
+
}
|
1143 |
+
}
|
1144 |
+
break;
|
1145 |
+
|
1146 |
+
case 'visit_id':
|
1147 |
+
$resource_title = self::get_resource_title( $results[ $i ][ 'resource' ] );
|
1148 |
+
if ( $resource_title != $results[ $i ][ 'resource' ] ) {
|
1149 |
+
$row_details = htmlentities( $results[ $i ][ 'resource' ], ENT_QUOTES, 'UTF-8' );
|
1150 |
+
}
|
1151 |
+
$element_value = $resource_title;
|
1152 |
+
break;
|
1153 |
+
default:
|
1154 |
+
}
|
1155 |
+
|
1156 |
+
if ( is_admin() ) {
|
1157 |
+
$element_value = "<a class='slimstat-filter-link' href='" . self::fs_url( $column_not_calculated. ' ' . $_args[ 'filter_op' ] . ' ' . $results[ $i ][ $_args[ 'columns' ] ] ) . "'>$element_value</a>";
|
1158 |
+
}
|
1159 |
+
|
1160 |
+
if ( !empty( $_args['type'] ) && $_args['type'] == 'recent' ) {
|
1161 |
+
$row_details = date_i18n(wp_slimstat::$settings[ 'date_format' ] . ' ' . wp_slimstat::$settings[ 'time_format' ], $results[ $i ][ 'dt' ], true ) . ( !empty( $row_details ) ? '<br>' : '' ) . $row_details;
|
1162 |
+
}
|
1163 |
+
|
1164 |
+
if ( !empty($_args[ 'type' ] ) && $_args[ 'type' ] == 'top' ) {
|
1165 |
+
$percentage_value = ( ( self::$pageviews > 0 ) ? number_format( sprintf( "%01.2f", ( 100 * $results[ $i ][ 'counthits' ] / self::$pageviews ) ), 2, wp_slimstat_db::$formats[ 'decimal' ], wp_slimstat_db::$formats[ 'thousand' ] ) : 0 );
|
1166 |
+
$counthits = number_format( $results[ $i ][ 'counthits' ], 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1167 |
+
|
1168 |
+
if ( !empty( $_args[ 'criteria' ] ) && $_args[ 'criteria' ] == 'swap' ) {
|
1169 |
+
$percentage = ' <span>' . $counthits . '</span>';
|
1170 |
+
$row_details = __('Hits','wp-slimstat') . ': ' . ( ( $column_not_calculated != 'outbound_resource' ) ? $percentage_value . '%' . ( !empty( $row_details ) ? '<br>' : '' ) . $row_details : '' );
|
1171 |
+
}
|
1172 |
+
else {
|
1173 |
+
$percentage = ' <span>' . $percentage_value . '%</span>';
|
1174 |
+
$row_details = __('Hits','wp-slimstat') . ': ' . $counthits . ( !empty( $row_details ) ? '<br>' : '' ) . $row_details;
|
1175 |
+
}
|
1176 |
+
}
|
1177 |
+
|
1178 |
+
// Some columns require a special post-treatment
|
1179 |
+
if ( $_args[ 'columns' ] == 'resource' && strpos( $_args['where'], '404' ) === false ) {
|
1180 |
+
$base_url = '';
|
1181 |
+
if (isset($results[$i]['blog_id'])){
|
1182 |
+
$base_url = parse_url(get_site_url($results[$i]['blog_id']));
|
1183 |
+
$base_url = $base_url['scheme'].'://'.$base_url['host'];
|
1184 |
+
}
|
1185 |
+
$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;
|
1186 |
+
}
|
1187 |
+
|
1188 |
+
if ( $_args[ 'columns' ] == 'referer_calculated' && !empty( $_args[ 'type' ] ) && $_args[ 'type' ] == 'top' ) {
|
1189 |
+
$element_url = 'http://' . htmlentities( $results[ $i ][ 'referer_calculated' ], ENT_QUOTES, 'UTF-8' );
|
1190 |
+
$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;
|
1191 |
+
}
|
1192 |
+
|
1193 |
+
if ( $_args[ 'columns' ] == 'referer' && !empty( $_args[ 'type' ] ) && $_args[ 'type' ] == 'top' ) {
|
1194 |
+
$element_url = htmlentities( $results[ $i ][ 'referer' ], ENT_QUOTES, 'UTF-8' );
|
1195 |
+
$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;
|
1196 |
+
}
|
1197 |
+
|
1198 |
+
if ( is_admin() && !empty( $results[ $i ][ 'ip' ]) && $_args[ 'columns' ] != 'ip' && wp_slimstat::$settings[ 'convert_ip_addresses' ] != 'on' ) {
|
1199 |
+
$row_details .= '<br> IP: <a class="slimstat-filter-link" href="'.self::fs_url( 'ip equals ' . $results[ $i ][ 'ip' ] ) . '">' . $results[ $i ][ 'ip' ] . '</a>' . ( !empty( $results[ $i ][ 'other_ip' ] ) ? ' / ' . $results[ $i ][ 'other_ip' ] : '' ) . '<a title="WHOIS: ' . $results[ $i ][ 'ip' ] . '" class="slimstat-font-location-1 whois" href="' . wp_slimstat::$settings[ 'ip_lookup_service' ] . $results[ $i ][ 'ip' ] . '"></a>';
|
1200 |
+
}
|
1201 |
+
if ( !empty( $row_details ) ) {
|
1202 |
+
$row_details = "<b class='slimstat-tooltip-content$is_expanded'>$row_details</b>";
|
1203 |
+
}
|
1204 |
+
|
1205 |
+
$row_output = "<p class='slimstat-tooltip-trigger'>$element_pre_value$element_value$percentage $row_details</p>";
|
1206 |
+
|
1207 |
+
// Strip all the filter links, if this information is shown on the frontend
|
1208 |
+
if ( !is_admin() ) {
|
1209 |
+
$row_output = preg_replace('/<a (.*?)>(.*?)<\/a>/', "\\2", $row_output);
|
1210 |
+
}
|
1211 |
+
|
1212 |
+
echo $row_output;
|
1213 |
+
}
|
1214 |
+
}
|
1215 |
+
|
1216 |
+
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
1217 |
+
die();
|
1218 |
+
}
|
1219 |
+
}
|
1220 |
+
|
1221 |
+
public static function show_activity_log( $_args = array() ) {
|
1222 |
+
// This function is too long, so it was moved to a separate file
|
1223 |
+
include( WP_PLUGIN_DIR . '/wp-slimstat/admin/view/right-now.php' );
|
1224 |
+
|
1225 |
+
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
1226 |
+
die();
|
1227 |
+
}
|
1228 |
+
}
|
1229 |
+
|
1230 |
+
public static function show_chart( $_args = array() ) {
|
1231 |
+
$data = wp_slimstat_db::get_data_for_chart( $_args[ 'chart_data' ] );
|
1232 |
+
|
1233 |
+
if ( empty( $data[ 'keys' ] ) ) {
|
1234 |
+
echo '<p class="nodata">' . __( 'No data to display', 'wp-slimstat') . '</p>';
|
1235 |
+
|
1236 |
+
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
1237 |
+
die();
|
1238 |
+
}
|
1239 |
+
else {
|
1240 |
+
return 0;
|
1241 |
+
}
|
1242 |
+
}
|
1243 |
+
|
1244 |
+
// Enqueue all the Javascript and styles
|
1245 |
+
$path_slimstat = dirname( dirname( __FILE__ ) );
|
1246 |
+
wp_enqueue_script( 'slimstat_amcharts', plugins_url( '/admin/js/amcharts/amcharts.js', $path_slimstat ), array(), null, false );
|
1247 |
+
wp_enqueue_script( 'slimstat_amcharts_serial', plugins_url( '/admin/js/amcharts/serial.js', $path_slimstat ), array( 'slimstat_amcharts' ), null, false );
|
1248 |
+
wp_enqueue_script( 'slimstat_amcharts_plugins_export', plugins_url( '/admin/js/amcharts/plugins/export/export.min.js', $path_slimstat ), array( 'slimstat_amcharts' ), null, false );
|
1249 |
+
wp_enqueue_script( 'slimstat_amcharts_theme_light', plugins_url( '/admin/js/amcharts/themes/light.js', $path_slimstat ), array( 'slimstat_amcharts' ), null, false );
|
1250 |
+
|
1251 |
+
wp_enqueue_style( 'slimstat_amcharts_plugins_export_css', plugins_url( '/admin/js/amcharts/plugins/export/export.css', $path_slimstat ) );
|
1252 |
+
|
1253 |
+
$chart_colors = !empty( wp_slimstat::$settings[ 'chart_colors' ] ) ? wp_slimstat::string_to_array( wp_slimstat::$settings[ 'chart_colors' ] ) : array( '#bbcc44', '#21759b', '#ccc', '#999' );
|
1254 |
+
|
1255 |
+
?>
|
1256 |
+
<div class="chart-placeholder" id="chart_<?php echo $_args[ 'id' ]; ?>" style="min-height: 280px"></div>
|
1257 |
+
|
1258 |
+
<script type="text/javascript">
|
1259 |
+
<?php if ( !defined( 'DOING_AJAX' ) || !DOING_AJAX ): ?>
|
1260 |
+
jQuery(function() {
|
1261 |
+
<?php endif; ?>
|
1262 |
+
var chart_<?php echo $_args[ 'id' ]; ?> = AmCharts.makeChart( "chart_<?php echo $_args[ 'id' ]; ?>", {
|
1263 |
+
"type": "serial",
|
1264 |
+
"zoomOutButtonPadding": 25,
|
1265 |
+
"theme": "light",
|
1266 |
+
"creditsPosition": "top-left",
|
1267 |
+
"mouseWheelZoomEnabled": true,
|
1268 |
+
"legend": {
|
1269 |
+
"equalWidths": true,
|
1270 |
+
"position": "bottom",
|
1271 |
+
"align": "center"
|
1272 |
+
},
|
1273 |
+
"valueAxes": [ {
|
1274 |
+
"id":"v1",
|
1275 |
+
"axisAlpha": 0,
|
1276 |
+
"integersOnly": true,
|
1277 |
+
"position": "left",
|
1278 |
+
} ],
|
1279 |
+
"chartCursor": {
|
1280 |
+
"cursorPosition": "mouse",
|
1281 |
+
"pan": true,
|
1282 |
+
"valueLineBalloonEnabled": true
|
1283 |
+
},
|
1284 |
+
"categoryField": "v1_label",
|
1285 |
+
"categoryAxis": {
|
1286 |
+
"dashLength": 1,
|
1287 |
+
"minHorizontalGap": <?php echo ( !empty( $data[ 'keys' ] ) && strlen( $data[ 0 ][ 'v1_label' ] ) > 5 ) ? 150 : 100; ?>,
|
1288 |
+
"parseDates": false,
|
1289 |
+
"position": "bottom"
|
1290 |
+
},
|
1291 |
+
"export": {
|
1292 |
+
"enabled": true
|
1293 |
+
},
|
1294 |
+
"numberFormatter": {
|
1295 |
+
"precision": 0
|
1296 |
+
},
|
1297 |
+
"graphs": [
|
1298 |
+
<?php if ( wp_slimstat::$settings[ 'comparison_chart' ] == 'on' ): ?>
|
1299 |
+
{
|
1300 |
+
"id": "g3_<?php echo $_args[ 'id' ]; ?>",
|
1301 |
+
"balloonText": "[[v3_label]]: [[value]]",
|
1302 |
+
"bullet": "round",
|
1303 |
+
"bulletBorderAlpha": 1,
|
1304 |
+
"bulletColor": "#00FF00",
|
1305 |
+
"bulletSize": 4,
|
1306 |
+
"hideBulletsCount": 50,
|
1307 |
+
"lineThickness": 2,
|
1308 |
+
"lineColor": "<?php echo $chart_colors[ 2 ] ?>",
|
1309 |
+
"title": "<?php echo htmlspecialchars( $_args[ 'chart_labels' ][ 0 ], ENT_QUOTES, 'UTF-8' ) . ' ' . __( '(previous)', 'wp-slimstat' ); ?>",
|
1310 |
+
"type": "line",
|
1311 |
+
"useLineColorForBulletBorder": true,
|
1312 |
+
"valueField": "v3"
|
1313 |
+
}, {
|
1314 |
+
"id": "g4_<?php echo $_args[ 'id' ]; ?>",
|
1315 |
+
"balloonText": "[[v3_label]]: [[value]]",
|
1316 |
+
"bullet": "round",
|
1317 |
+
"bulletBorderAlpha": 1,
|
1318 |
+
"bulletColor": "#00FF00",
|
1319 |
+
"bulletSize": 4,
|
1320 |
+
"hideBulletsCount": 50,
|
1321 |
+
"lineThickness": 2,
|
1322 |
+
"lineColor": "<?php echo $chart_colors[ 3 ] ?>",
|
1323 |
+
"title": "<?php echo htmlspecialchars( $_args[ 'chart_labels' ][ 1 ], ENT_QUOTES, 'UTF-8' ) . ' ' . __( '(previous)', 'wp-slimstat' ); ?>",
|
1324 |
+
"type": "line",
|
1325 |
+
"useLineColorForBulletBorder": true,
|
1326 |
+
"valueField": "v4"
|
1327 |
+
},
|
1328 |
+
<?php endif; ?>
|
1329 |
+
{
|
1330 |
+
"id": "g1_<?php echo $_args[ 'id' ]; ?>",
|
1331 |
+
"balloonText": "<?php echo ( wp_slimstat::$settings[ 'comparison_chart' ] == 'on' ) ? '[[v1_label]]: [[value]]' : '[[value]]'; ?>",
|
1332 |
+
"bullet": "round",
|
1333 |
+
"bulletBorderAlpha": 1,
|
1334 |
+
"bulletColor": "#FFFFFF",
|
1335 |
+
"bulletSize": 4,
|
1336 |
+
"hideBulletsCount": 50,
|
1337 |
+
"lineColor": "<?php echo $chart_colors[ 0 ] ?>",
|
1338 |
+
"lineThickness": 2,
|
1339 |
+
"title": "<?php echo htmlspecialchars( $_args[ 'chart_labels' ][ 0 ], ENT_QUOTES, 'UTF-8' ); ?>",
|
1340 |
+
"type": "line",
|
1341 |
+
"useLineColorForBulletBorder": true,
|
1342 |
+
"valueField": "v1"
|
1343 |
+
}, {
|
1344 |
+
"id": "g2_<?php echo $_args[ 'id' ]; ?>",
|
1345 |
+
"balloonText": "<?php echo ( wp_slimstat::$settings[ 'comparison_chart' ] == 'on' ) ? '[[v1_label]]: [[value]]' : '[[value]]'; ?>",
|
1346 |
+
"bullet": "round",
|
1347 |
+
"bulletBorderAlpha": 0.6,
|
1348 |
+
"bulletColor": "#00FF00",
|
1349 |
+
"bulletSize": 4,
|
1350 |
+
"hideBulletsCount": 50,
|
1351 |
+
"lineColor": "<?php echo $chart_colors[ 1 ] ?>",
|
1352 |
+
"lineThickness": 2,
|
1353 |
+
"title": "<?php echo htmlspecialchars( $_args[ 'chart_labels' ][ 1 ], ENT_QUOTES, 'UTF-8' ); ?>",
|
1354 |
+
"type": "line",
|
1355 |
+
"useLineColorForBulletBorder": true,
|
1356 |
+
"valueField": "v2"
|
1357 |
+
}
|
1358 |
+
],
|
1359 |
+
"dataProvider": <?php unset( $data[ 'keys' ] ); echo json_encode( $data ) ?>
|
1360 |
+
});
|
1361 |
+
<?php if ( !defined( 'DOING_AJAX' ) || !DOING_AJAX ): ?>
|
1362 |
+
});
|
1363 |
+
<?php endif; ?>
|
1364 |
+
</script>
|
1365 |
+
<?php
|
1366 |
+
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
1367 |
+
die();
|
1368 |
+
}
|
1369 |
+
}
|
1370 |
+
|
1371 |
+
public static function get_about_wpslimstat() {
|
1372 |
+
$dt = wp_slimstat_db::get_oldest_visit( '1=1', false );
|
1373 |
+
$results = array();
|
1374 |
+
|
1375 |
+
$results[ 0 ][ 'metric' ] = __( 'Dataset Size', 'wp-slimstat' );
|
1376 |
+
$results[ 0 ][ 'value' ] = number_format( wp_slimstat_db::count_records( 'id', '1=1', false ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1377 |
+
$results[ 0 ][ 'tooltip' ] = __( 'Total number of records stored in the database.', 'wp-slimstat' );
|
1378 |
+
|
1379 |
+
$results[ 1 ][ 'metric' ] = __( 'DB Size', 'wp-slimstat' );
|
1380 |
+
$results[ 1 ][ 'value' ] = wp_slimstat_db::get_data_size();
|
1381 |
+
|
1382 |
+
$results[ 2 ][ 'metric' ] = __( 'Tracking Enabled', 'wp-slimstat' );
|
1383 |
+
$results[ 2 ][ 'value' ] = __( ucfirst( wp_slimstat::$settings[ 'is_tracking' ] ), 'wp-slimstat' );
|
1384 |
+
|
1385 |
+
$results[ 3 ][ 'metric' ] = __( 'Javascript Mode', 'wp-slimstat' );
|
1386 |
+
$results[ 3 ][ 'value' ] = __( ucfirst( wp_slimstat::$settings[ 'javascript_mode' ] ), 'wp-slimstat' );
|
1387 |
+
|
1388 |
+
$results[ 4 ][ 'metric' ] = __( 'Tracking Browser Caps', 'wp-slimstat' );
|
1389 |
+
$results[ 4 ][ 'value' ] = __( ucfirst( wp_slimstat::$settings[ 'enable_javascript' ] ), 'wp-slimstat' );
|
1390 |
+
|
1391 |
+
$results[ 5 ][ 'metric' ] = __( 'Auto purge', 'wp-slimstat' );
|
1392 |
+
$results[ 5 ][ 'value' ] = ( wp_slimstat::$settings[ 'auto_purge' ] > 0 ) ? wp_slimstat::$settings[ 'auto_purge' ] . ' ' . __( 'days', 'wp-slimstat' ) : __( 'Off', 'wp-slimstat' );
|
1393 |
+
|
1394 |
+
$results[ 6 ][ 'metric' ] = __( 'Oldest pageview', 'wp-slimstat' );
|
1395 |
+
$results[ 6 ][ 'value' ] = ( $dt == null ) ? __( 'No visits', 'wp-slimstat' ) : date_i18n( wp_slimstat::$settings[ 'date_format' ], $dt );
|
1396 |
+
|
1397 |
+
$results[ 7 ][ 'metric' ] = __( 'Geolocation', 'wp-slimstat' );
|
1398 |
+
$results[ 7 ][ 'value' ] = date_i18n( wp_slimstat::$settings[ 'date_format' ], @filemtime( wp_slimstat::$maxmind_path ) );
|
1399 |
+
$results[ 7 ][ 'tooltip' ] = __( 'Date when the MaxMind Geolocation database was last updated.', 'wp-slimstat' );
|
1400 |
+
|
1401 |
+
return $results;
|
1402 |
+
}
|
1403 |
+
|
1404 |
+
public static function get_overview_summary() {
|
1405 |
+
$days_in_range = ceil( ( wp_slimstat_db::$filters_normalized[ 'utime' ][ 'end' ] - wp_slimstat_db::$filters_normalized[ 'utime' ][ 'start' ] ) / 86400 );
|
1406 |
+
$results = array();
|
1407 |
+
|
1408 |
+
$results[ 0 ][ 'metric' ] = __( 'Pageviews', 'wp-slimstat' );
|
1409 |
+
$results[ 0 ][ 'value' ] = number_format( self::$pageviews, 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1410 |
+
$results[ 0 ][ 'tooltip' ] = __( 'A request to load a single HTML file. Slimstat logs a "pageview" each time the tracking code is executed.', 'wp-slimstat' );
|
1411 |
+
|
1412 |
+
$results[ 1 ][ 'metric' ] = __( 'Days in Range', 'wp-slimstat' );
|
1413 |
+
$results[ 1 ][ 'value' ] = $days_in_range;
|
1414 |
+
|
1415 |
+
$results[ 2 ][ 'metric' ] = __( 'Average Daily Pageviews', 'wp-slimstat' );
|
1416 |
+
$results[ 2 ][ 'value' ] = number_format( round( self::$pageviews / $days_in_range, 0 ), 0, '', wp_slimstat_db::$formats['thousand'] );
|
1417 |
+
$results[ 2 ][ 'tooltip' ] = __( 'How many pages have been visited on average every day during the current period.', 'wp-slimstat' );
|
1418 |
+
|
1419 |
+
$results[ 3 ][ 'metric' ] = __( 'From Search Results', 'wp-slimstat' );
|
1420 |
+
$results[ 3 ][ 'value' ] = number_format( wp_slimstat_db::count_records( 'id', 'searchterms IS NOT NULL' ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1421 |
+
$results[ 3 ][ 'tooltip' ] = __( 'Visitors who landed on your site after searching for a keyword on Google, Yahoo, etc.', 'wp-slimstat' );
|
1422 |
+
|
1423 |
+
$results[ 4 ][ 'metric' ] = __( 'Unique IPs', 'wp-slimstat' );
|
1424 |
+
$results[ 4 ][ 'value' ] = number_format( wp_slimstat_db::count_records( 'ip' ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1425 |
+
$results[ 4 ][ 'tooltip' ] = __( 'Used to differentiate between multiple requests to download a file from one internet address (IP) and requests originating from many distinct addresses', 'wp-slimstat' );
|
1426 |
+
|
1427 |
+
$results[ 5 ][ 'metric' ] = __( 'Last 30 minutes', 'wp-slimstat' );
|
1428 |
+
$results[ 5 ][ 'value' ] = number_format( wp_slimstat_db::count_records( 'id', 'dt > ' . ( date_i18n( 'U' ) - 1800 ), false ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1429 |
+
|
1430 |
+
$results[ 6 ][ 'metric' ] = __( 'Today', 'wp-slimstat' );
|
1431 |
+
$results[ 6 ][ 'value' ] = number_format( wp_slimstat_db::count_records( 'id', 'dt > ' . ( date_i18n( 'U', mktime( 0, 0, 0, date_i18n( 'm' ), date_i18n( 'd' ), date_i18n( 'Y' ) ) ) ), false ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1432 |
+
|
1433 |
+
$results[ 7 ][ 'metric' ] = __( 'Yesterday', 'wp-slimstat' );
|
1434 |
+
$results[ 7 ][ 'value' ] = number_format( wp_slimstat_db::count_records( 'id', 'dt BETWEEN ' . ( date_i18n( 'U', mktime( 0, 0, 0, date_i18n( 'm' ), date_i18n( 'd' ) - 1, date_i18n( 'Y' ) ) ) ) . ' AND ' . ( date_i18n( 'U', mktime( 23, 59, 59, date_i18n( 'm' ), date_i18n( 'd' ) - 1, date_i18n( 'Y' ) ) ) ), false ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1435 |
+
|
1436 |
+
return $results;
|
1437 |
+
}
|
1438 |
+
|
1439 |
+
public static function get_plugins() {
|
1440 |
+
$wp_slim_plugins = array( 'flash', 'silverlight', 'acrobat', 'java', 'mediaplayer', 'director', 'real', 'quicktime' );
|
1441 |
+
$total_human_hits = wp_slimstat_db::count_records( 'id', 'visit_id > 0 AND browser_type <> 1' );
|
1442 |
+
$results = array();
|
1443 |
+
|
1444 |
+
foreach ( $wp_slim_plugins as $i => $a_plugin ) {
|
1445 |
+
$count_results = wp_slimstat_db::count_records( 'id', "plugins LIKE '%{$a_plugin}%'" );
|
1446 |
+
$results[ $i ][ 'metric' ] = ucfirst( $a_plugin );
|
1447 |
+
$results[ $i ][ 'value' ] = ( $total_human_hits > 0 ) ? number_format( ( 100 * $count_results / $total_human_hits ), 2, wp_slimstat_db::$formats[ 'decimal' ], wp_slimstat_db::$formats[ 'thousand' ] ) : 0;
|
1448 |
+
$results[ $i ][ 'details' ] = __( 'Hits', 'wp-slimstat' ) . ": $count_results";
|
1449 |
+
}
|
1450 |
+
|
1451 |
+
return $results;
|
1452 |
+
}
|
1453 |
+
|
1454 |
+
public static function get_visitors_summary() {
|
1455 |
+
$results = array();
|
1456 |
+
$total_human_hits = wp_slimstat_db::count_records( 'id', 'visit_id > 0 AND browser_type <> 1');
|
1457 |
+
$new_visitors = wp_slimstat_db::count_records_having( 'ip', 'visit_id > 0 AND browser_type <> 1', 'COUNT(visit_id) = 1' );
|
1458 |
+
$new_visitors_rate = ( $total_human_hits > 0) ? ( 100 * $new_visitors / $total_human_hits ) : 0;
|
1459 |
+
$metrics_per_visit = wp_slimstat_db::get_max_and_average_pages_per_visit();
|
1460 |
+
if ( empty( $metrics_per_visit[ 0 ] ) ) {
|
1461 |
+
$metrics_per_visit[ 0 ] = array( 'avghits' => 0, 'maxhits' => 0);
|
1462 |
+
}
|
1463 |
+
if ( intval( $new_visitors_rate ) > 99 ) {
|
1464 |
+
$new_visitors_rate = '100';
|
1465 |
+
}
|
1466 |
+
|
1467 |
+
$results[ 0 ][ 'metric' ] = __( 'Visits', 'wp-slimstat' );
|
1468 |
+
$results[ 0 ][ 'value' ] = number_format( wp_slimstat_db::count_records( 'visit_id', 'visit_id > 0 AND browser_type <> 1' ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1469 |
+
$results[ 0 ][ 'tooltip' ] = __( 'A visit is a session of at most 30 minutes. Returning visitors are counted multiple times if they perform multiple visits.', 'wp-slimstat' );
|
1470 |
+
|
1471 |
+
$results[ 1 ][ 'metric' ] = __( 'Unique IPs', 'wp-slimstat' );
|
1472 |
+
$results[ 1 ][ 'value' ] = number_format( wp_slimstat_db::count_records( 'ip', 'visit_id > 0 AND browser_type <> 1' ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1473 |
+
$results[ 1 ][ 'tooltip' ] = __( 'It includes only traffic generated by human visitors.', 'wp-slimstat' );
|
1474 |
+
|
1475 |
+
$results[ 2 ][ 'metric' ] = __( 'Bounce rate', 'wp-slimstat' );
|
1476 |
+
$results[ 2 ][ 'value' ] = number_format( $new_visitors_rate, 2, wp_slimstat_db::$formats[ 'decimal' ], wp_slimstat_db::$formats[ 'thousand' ] );
|
1477 |
+
$results[ 2 ][ 'tooltip' ] = __( 'Percentage of single-page visits, i.e. visits in which the person left your site from the entrance page.', 'wp-slimstat' );
|
1478 |
+
|
1479 |
+
$results[ 3 ][ 'metric' ] = __( 'Known visitors', 'wp-slimstat' );
|
1480 |
+
$results[ 3 ][ 'value' ] = number_format( wp_slimstat_db::count_records( 'username' ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1481 |
+
$results[ 3 ][ 'tooltip' ] = __( 'Visitors who had previously left a comment on your blog.', 'wp-slimstat' );
|
1482 |
+
|
1483 |
+
$results[ 4 ][ 'metric' ] = __( 'New visitors', 'wp-slimstat' );
|
1484 |
+
$results[ 4 ][ 'value' ] = number_format( $new_visitors, 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1485 |
+
$results[ 4 ][ 'tooltip' ] = __( 'Human users who visited your site only once.', 'wp-slimstat' );
|
1486 |
+
|
1487 |
+
$results[ 5 ][ 'metric' ] = __( 'Bots', 'wp-slimstat' );
|
1488 |
+
$results[ 5 ][ 'value' ] = number_format( wp_slimstat_db::count_records( 'id', 'browser_type = 1' ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1489 |
+
|
1490 |
+
$results[ 6 ][ 'metric' ] = __( 'Pageviews per visit', 'wp-slimstat' );
|
1491 |
+
$results[ 6 ][ 'value' ] = number_format( $metrics_per_visit[ 0 ][ 'avghits' ], 2, wp_slimstat_db::$formats[ 'decimal' ], wp_slimstat_db::$formats[ 'thousand' ] );
|
1492 |
+
|
1493 |
+
$results[ 7 ][ 'metric' ] = __( 'Longest visit', 'wp-slimstat' );
|
1494 |
+
$results[ 7 ][ 'value' ] = number_format( $metrics_per_visit[ 0 ][ 'maxhits' ], 0, '', wp_slimstat_db::$formats[ 'thousand' ] ) . ' ' . __( 'hits', 'wp-slimstat' );
|
1495 |
+
|
1496 |
+
return $results;
|
1497 |
+
}
|
1498 |
+
|
1499 |
+
public static function get_visits_duration() {
|
1500 |
+
$total_human_visits = wp_slimstat_db::count_records( 'visit_id', 'visit_id > 0 AND browser_type <> 1' );
|
1501 |
+
$results = array();
|
1502 |
+
|
1503 |
+
$count_results = wp_slimstat_db::count_records_having( 'visit_id', 'visit_id > 0 AND browser_type <> 1', ' GREATEST( MAX( dt ), MAX( dt_out ) ) - MIN( dt ) >= 0 AND GREATEST( MAX( dt ), MAX( dt_out ) ) - MIN( dt ) <= 30' );
|
1504 |
+
$average_time = 30 * $count_results;
|
1505 |
+
$results[ 0 ][ 'metric' ] = __( '0 - 30 seconds', 'wp-slimstat' );
|
1506 |
+
$results[ 0 ][ 'value' ] = ( ( $total_human_visits > 0 ) ? number_format( ( 100 * $count_results / $total_human_visits ), 2, wp_slimstat_db::$formats[ 'decimal' ], wp_slimstat_db::$formats[ 'thousand' ] ) : 0 ) . '%';
|
1507 |
+
$results[ 0 ][ 'details' ] = __( 'Hits', 'wp-slimstat' ) . ": $count_results";
|
1508 |
+
|
1509 |
+
$count_results = wp_slimstat_db::count_records_having( 'visit_id', 'visit_id > 0 AND browser_type <> 1', 'GREATEST( MAX( dt ), MAX( dt_out ) ) - MIN( dt ) > 30 AND GREATEST( MAX( dt ), MAX( dt_out ) ) - MIN( dt ) <= 60' );
|
1510 |
+
$average_time += 60 * $count_results;
|
1511 |
+
$results[ 1 ][ 'metric' ] = __( '31 - 60 seconds', 'wp-slimstat' );
|
1512 |
+
$results[ 1 ][ 'value' ] = ( ( $total_human_visits > 0 ) ? number_format( ( 100 * $count_results / $total_human_visits ), 2, wp_slimstat_db::$formats[ 'decimal' ], wp_slimstat_db::$formats[ 'thousand' ] ) : 0 ) . '%';
|
1513 |
+
$results[ 1 ][ 'details' ] = __( 'Hits', 'wp-slimstat' ) . ": $count_results";
|
1514 |
+
|
1515 |
+
$count_results = wp_slimstat_db::count_records_having( 'visit_id', 'visit_id > 0 AND browser_type <> 1', 'GREATEST( MAX( dt ), MAX( dt_out ) ) - MIN( dt ) > 60 AND GREATEST( MAX( dt ), MAX( dt_out ) ) - MIN( dt ) <= 180' );
|
1516 |
+
$average_time += 180 * $count_results;
|
1517 |
+
$results[ 2 ][ 'metric' ] = __( '1 - 3 minutes', 'wp-slimstat' );
|
1518 |
+
$results[ 2 ][ 'value' ] = ( ( $total_human_visits > 0 ) ? number_format( ( 100 * $count_results / $total_human_visits ), 2, wp_slimstat_db::$formats[ 'decimal' ], wp_slimstat_db::$formats[ 'thousand' ] ) : 0 ) . '%';
|
1519 |
+
$results[ 2 ][ 'details' ] = __( 'Hits', 'wp-slimstat' ) . ": $count_results";
|
1520 |
+
|
1521 |
+
$count_results = wp_slimstat_db::count_records_having( 'visit_id', 'visit_id > 0 AND browser_type <> 1', 'GREATEST( MAX( dt ), MAX( dt_out ) ) - MIN( dt ) > 180 AND GREATEST( MAX( dt ), MAX( dt_out ) ) - MIN( dt ) <= 300' );
|
1522 |
+
$average_time += 300 * $count_results;
|
1523 |
+
$results[ 3 ][ 'metric' ] = __( '3 - 5 minutes', 'wp-slimstat' );
|
1524 |
+
$results[ 3 ][ 'value' ] = ( ( $total_human_visits > 0 ) ? number_format( ( 100 * $count_results / $total_human_visits ), 2, wp_slimstat_db::$formats[ 'decimal' ], wp_slimstat_db::$formats[ 'thousand' ] ) : 0 ) . '%';
|
1525 |
+
$results[ 3 ][ 'details' ] = __( 'Hits', 'wp-slimstat' ) . ": $count_results";
|
1526 |
+
|
1527 |
+
$count_results = wp_slimstat_db::count_records_having( 'visit_id', 'visit_id > 0 AND browser_type <> 1', 'GREATEST( MAX( dt ), MAX( dt_out ) ) - MIN( dt ) > 300 AND GREATEST( MAX( dt ), MAX( dt_out ) ) - MIN( dt ) <= 420' );
|
1528 |
+
$average_time += 420 * $count_results;
|
1529 |
+
$results[ 4 ][ 'metric' ] = __( '5 - 7 minutes', 'wp-slimstat' );
|
1530 |
+
$results[ 4 ][ 'value' ] = ( ( $total_human_visits > 0 ) ? number_format( ( 100 * $count_results / $total_human_visits ), 2, wp_slimstat_db::$formats[ 'decimal' ], wp_slimstat_db::$formats[ 'thousand' ] ) : 0 ) . '%';
|
1531 |
+
$results[ 4 ][ 'details' ] = __( 'Hits', 'wp-slimstat' ) . ": $count_results";
|
1532 |
+
|
1533 |
+
$count_results = wp_slimstat_db::count_records_having( 'visit_id', 'visit_id > 0 AND browser_type <> 1', 'GREATEST( MAX( dt ), MAX( dt_out ) ) - MIN( dt ) > 420 AND GREATEST( MAX( dt ), MAX( dt_out ) ) - MIN( dt ) <= 600' );
|
1534 |
+
$average_time += 600* $count_results;
|
1535 |
+
$results[ 5 ][ 'metric' ] = __( '7 - 10 minutes', 'wp-slimstat' );
|
1536 |
+
$results[ 5 ][ 'value' ] = ( ( $total_human_visits > 0 ) ? number_format( ( 100 * $count_results / $total_human_visits ), 2, wp_slimstat_db::$formats[ 'decimal' ], wp_slimstat_db::$formats[ 'thousand' ] ) : 0 ) . '%';
|
1537 |
+
$results[ 5 ][ 'details' ] = __( 'Hits', 'wp-slimstat' ) . ": $count_results";
|
1538 |
+
|
1539 |
+
$count_results = wp_slimstat_db::count_records_having( 'visit_id', 'visit_id > 0 AND browser_type <> 1', 'GREATEST( MAX( dt ), MAX( dt_out ) ) - MIN( dt ) > 600' );
|
1540 |
+
$average_time += 900 * $count_results;
|
1541 |
+
$results[ 6 ][ 'metric' ] = __( 'More than 10 minutes', 'wp-slimstat' );
|
1542 |
+
$results[ 6 ][ 'value' ] = ( ( $total_human_visits > 0 ) ? number_format( ( 100 * $count_results / $total_human_visits ), 2, wp_slimstat_db::$formats[ 'decimal' ], wp_slimstat_db::$formats[ 'thousand' ] ) : 0 ) . '%';
|
1543 |
+
$results[ 6 ][ 'details' ] = __( 'Hits', 'wp-slimstat' ) . ": $count_results";
|
1544 |
+
|
1545 |
+
if ( $total_human_visits > 0 ) {
|
1546 |
+
$average_time /= $total_human_visits;
|
1547 |
+
$average_time = date('m:s', intval($average_time));
|
1548 |
+
}
|
1549 |
+
else{
|
1550 |
+
$average_time = '0:00';
|
1551 |
+
}
|
1552 |
+
|
1553 |
+
$results[ 7 ][ 'metric' ] = __( 'Average visit duration', 'wp-slimstat' );
|
1554 |
+
$results[ 7 ][ 'value' ] = $average_time;
|
1555 |
+
$results[ 7 ][ 'details' ] = '';
|
1556 |
+
|
1557 |
+
return $results;
|
1558 |
+
}
|
1559 |
+
|
1560 |
+
public static function get_traffic_sources_summary() {
|
1561 |
+
$results = array();
|
1562 |
+
$total_human_hits = wp_slimstat_db::count_records( 'id', 'visit_id > 0 AND browser_type <> 1' );
|
1563 |
+
$new_visitors = wp_slimstat_db::count_records_having( 'ip', 'visit_id > 0', 'COUNT(visit_id) = 1' );
|
1564 |
+
$new_visitors_rate = ($total_human_hits > 0)?sprintf("%01.2f", (100*$new_visitors/$total_human_hits)):0;
|
1565 |
+
if (intval($new_visitors_rate) > 99) {
|
1566 |
+
$new_visitors_rate = '100';
|
1567 |
+
}
|
1568 |
+
|
1569 |
+
$results[ 0 ][ 'metric' ] = __( 'Pageviews', 'wp-slimstat' );
|
1570 |
+
$results[ 0 ][ 'value' ] = number_format( self::$pageviews, 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1571 |
+
$results[ 0 ][ 'tooltip' ] = __( 'A request to load a single HTML file. Slimstat logs a "pageview" each time the tracking code is executed.', 'wp-slimstat' );
|
1572 |
+
|
1573 |
+
$results[ 1 ][ 'metric' ] = __( 'Unique Referrers', 'wp-slimstat' );
|
1574 |
+
$results[ 1 ][ 'value' ] = number_format( wp_slimstat_db::count_records( 'referer', "referer NOT LIKE '%{$_SERVER['SERVER_NAME']}%'" ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1575 |
+
$results[ 1 ][ 'tooltip' ] = __( 'A referrer (or referring site) is the site that a visitor previously visited before following a link to your site.', 'wp-slimstat' );
|
1576 |
+
|
1577 |
+
$results[ 2 ][ 'metric' ] = __( 'Direct Pageviews', 'wp-slimstat' );
|
1578 |
+
$results[ 2 ][ 'value' ] = number_format( wp_slimstat_db::count_records( 'id', 'resource IS NULL' ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1579 |
+
$results[ 2 ][ 'tooltip' ] = __( "Visitors who visited the site by typing the URL directly into their browser. <em>Direct</em> can also refer to the visitors who clicked on the links from their bookmarks/favorites, untagged links within emails, or links from documents that don't include tracking variables.", 'wp-slimstat' );
|
1580 |
+
|
1581 |
+
$results[ 3 ][ 'metric' ] = __( 'From a search result', 'wp-slimstat' );
|
1582 |
+
$results[ 3 ][ 'value' ] = number_format( wp_slimstat_db::count_records( 'id', "searchterms IS NOT NULL AND referer IS NOT NULL AND referer NOT LIKE '%" . home_url() . "%'" ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1583 |
+
$results[ 3 ][ 'tooltip' ] = __( "Visitors who came to your site via searches on Google or some other search engine.", 'wp-slimstat' );
|
1584 |
+
|
1585 |
+
$results[ 4 ][ 'metric' ] = __( 'Unique Landing Pages', 'wp-slimstat' );
|
1586 |
+
$results[ 4 ][ 'value' ] = number_format( wp_slimstat_db::count_records( 'resource' ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1587 |
+
$results[ 4 ][ 'tooltip' ] = __( "The first page that a user views during a session. This is also known as the <em>entrance page</em>. For example, if they search for 'Brooklyn Office Space,' and they land on your home page, it gets counted (for that visit) as a landing page.", 'wp-slimstat' );
|
1588 |
+
|
1589 |
+
$results[ 5 ][ 'metric' ] = __( 'Bounce Pages', 'wp-slimstat' );
|
1590 |
+
$results[ 5 ][ 'value' ] = number_format( wp_slimstat_db::count_bouncing_pages(), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1591 |
+
$results[ 5 ][ 'tooltip' ] = __( 'Number of single page visits to your site over the selected period.', 'wp-slimstat' );
|
1592 |
+
|
1593 |
+
$results[ 6 ][ 'metric' ] = __( 'New Visitors Rate', 'wp-slimstat' );
|
1594 |
+
$results[ 6 ][ 'value' ] = number_format( $new_visitors_rate, 2, wp_slimstat_db::$formats[ 'decimal' ], wp_slimstat_db::$formats[ 'thousand' ] );
|
1595 |
+
$results[ 6 ][ 'tooltip' ] = __( 'Percentage of single page visits, i.e. visits in which the person left your site from the entrance page.', 'wp-slimstat' );
|
1596 |
+
|
1597 |
+
$results[ 7 ][ 'metric' ] = __( 'Currently from search engines', 'wp-slimstat' );
|
1598 |
+
$results[ 7 ][ 'value' ] = number_format( wp_slimstat_db::count_records( 'id', "searchterms IS NOT NULL AND referer IS NOT NULL AND referer NOT LIKE '%" . home_url() . "%' AND dt > UNIX_TIMESTAMP() - 300", false ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1599 |
+
$results[ 7 ][ 'tooltip' ] = __( 'Visitors who visited the site in the last 5 minutes coming from a search engine.', 'wp-slimstat' );
|
1600 |
+
|
1601 |
+
return $results;
|
1602 |
+
}
|
1603 |
+
|
1604 |
+
public static function show_rankings(){
|
1605 |
+
$options = array( 'timeout' => 1, 'headers' => array( 'Accept' => 'application/json' ) );
|
1606 |
+
$site_url = parse_url( home_url(), PHP_URL_HOST );
|
1607 |
+
if ( !empty( wp_slimstat_db::$filters_normalized[ 'resource' ] ) && wp_slimstat_db::$filters_normalized[ 'resource' ][ 0 ] == 'equals' ) {
|
1608 |
+
$site_url .= wp_slimstat_db::$filters_normalized[ 'resource' ][ 1 ];
|
1609 |
+
}
|
1610 |
+
$site_url = urlencode( $site_url );
|
1611 |
+
|
1612 |
+
// Check if we have a valied transient
|
1613 |
+
if ( false === ( $rankings = get_transient( 'slimstat_ranking_values' ) ) ) {
|
1614 |
+
$rankings = array(
|
1615 |
+
'seomoz_equity_backlinks' => array(
|
1616 |
+
0,
|
1617 |
+
__( 'Backlinks', 'wp-slimstat' ),
|
1618 |
+
__( 'Number of external equity links to your website.', 'wp-slimstat' )
|
1619 |
+
),
|
1620 |
+
'seomoz_mozrank' => array(
|
1621 |
+
0,
|
1622 |
+
__( 'MozRank', 'wp-slimstat' ),
|
1623 |
+
__( 'MozRank of the URL, in a normalized 10-point score. MozRank represents a link popularity score. It reflects the importance of any given web page on the Internet.', 'wp-slimstat' )
|
1624 |
+
),
|
1625 |
+
'seomoz_equity_links' => array(
|
1626 |
+
0,
|
1627 |
+
__( 'Equity Links', 'wp-slimstat' ),
|
1628 |
+
__( 'Number of authority-passing links (including followed links and redirects, internal or external) to your website. Set the permalink filter here above to get the corresponding metrics in this report.', 'wp-slimstat' )
|
1629 |
+
),
|
1630 |
+
'facebook_shares' => array(
|
1631 |
+
0,
|
1632 |
+
__( 'Facebook Shares', 'wp-slimstat' ),
|
1633 |
+
''
|
1634 |
+
),
|
1635 |
+
'facebook_clicks' => array(
|
1636 |
+
0,
|
1637 |
+
__( 'Facebook Clicks', 'wp-slimstat' ),
|
1638 |
+
__( 'How many times links to your website have been clicked on Facebook.', 'wp-slimstat' )
|
1639 |
+
),
|
1640 |
+
'alexa_world_rank' => array(
|
1641 |
+
0,
|
1642 |
+
__( 'Alexa World Rank', 'wp-slimstat' ),
|
1643 |
+
__( 'Alexa is a subsidiary company of Amazon.com which provides commercial web traffic data.', 'wp-slimstat' )
|
1644 |
+
),
|
1645 |
+
'alexa_country_rank' => array(
|
1646 |
+
0,
|
1647 |
+
__( 'Alexa Country Rank', 'wp-slimstat' ),
|
1648 |
+
''
|
1649 |
+
),
|
1650 |
+
'alexa_popularity' => array(
|
1651 |
+
0,
|
1652 |
+
__( 'Alexa Popularity', 'wp-slimstat' ),
|
1653 |
+
''
|
1654 |
+
)
|
1655 |
+
);
|
1656 |
+
|
1657 |
+
if ( !empty( wp_slimstat::$settings[ 'mozcom_access_id' ] ) && !empty( wp_slimstat::$settings[ 'mozcom_secret_key' ] ) ) {
|
1658 |
+
$expiration_token = time() + 300;
|
1659 |
+
$binary_signature = @hash_hmac( 'sha1', wp_slimstat::$settings[ 'mozcom_access_id' ] . "\n" . $expiration_token, wp_slimstat::$settings[ 'mozcom_secret_key' ], true );
|
1660 |
+
$binary_signature = urlencode( base64_encode( $binary_signature ) );
|
1661 |
+
|
1662 |
+
// SeoMoz Equity Links (Backlinks) and MozRank
|
1663 |
+
$response = @wp_remote_get( 'http://lsapi.seomoz.com/linkscape/url-metrics/' . $site_url . '?Cols=16672&AccessID=' . wp_slimstat::$settings[ 'mozcom_access_id' ] . '&Expires=' . $expiration_token . '&Signature=' . $binary_signature, $options );
|
1664 |
+
if ( !is_wp_error( $response ) && isset( $response[ 'response' ][ 'code' ] ) && ( $response[ 'response' ][ 'code' ] == 200 ) && !empty( $response[ 'body' ] ) ) {
|
1665 |
+
$response = @json_decode( $response[ 'body' ] );
|
1666 |
+
if ( is_object( $response ) ) {
|
1667 |
+
if ( !empty( $response->ujid ) ) {
|
1668 |
+
$rankings[ 'seomoz_equity_links' ][ 0 ] = number_format( intval( $response->ujid ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1669 |
+
}
|
1670 |
+
|
1671 |
+
if ( !empty( $response->ueid ) ) {
|
1672 |
+
$rankings[ 'seomoz_equity_backlinks' ][ 0 ] = number_format( intval( $response->ueid ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1673 |
+
}
|
1674 |
+
|
1675 |
+
if ( !empty( $response->umrp ) ) {
|
1676 |
+
$rankings[ 'seomoz_mozrank' ][ 0 ] = number_format( floatval( $response->umrp ), 2, wp_slimstat_db::$formats[ 'decimal' ], wp_slimstat_db::$formats[ 'thousand' ] );
|
1677 |
+
}
|
1678 |
+
}
|
1679 |
+
}
|
1680 |
+
}
|
1681 |
+
|
1682 |
+
// Alexa
|
1683 |
+
$response = @wp_remote_get( 'http://data.alexa.com/data?cli=10&dat=snbamz&url=' . $site_url, $options );
|
1684 |
+
if ( !is_wp_error( $response ) && isset( $response[ 'response' ][ 'code' ] ) && ( $response[ 'response' ][ 'code' ] == 200 ) && !empty( $response[ 'body' ] ) ) {
|
1685 |
+
$response = @simplexml_load_string( $response[ 'body' ] );
|
1686 |
+
if ( is_object( $response->SD[ 1 ] ) ) {
|
1687 |
+
if ( $response->SD[ 1 ]->POPULARITY && $response->SD[ 1 ]->POPULARITY->attributes() ) {
|
1688 |
+
$popularity = $response->SD[ 1 ]->POPULARITY->attributes();
|
1689 |
+
if ( !empty( $popularity ) ) {
|
1690 |
+
$rankings[ 'alexa_popularity' ][ 0 ] = number_format( floatval( $popularity[ 'TEXT' ] ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1691 |
+
}
|
1692 |
+
}
|
1693 |
+
|
1694 |
+
if ( $response->SD[ 1 ]->REACH && $response->SD[ 1 ]->REACH->attributes() ) {
|
1695 |
+
$reach = $response->SD[ 1 ]->REACH->attributes();
|
1696 |
+
if ( !empty( $reach ) ) {
|
1697 |
+
$rankings[ 'alexa_world_rank' ][ 0 ] = number_format( floatval( $reach[ 'RANK' ] ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1698 |
+
}
|
1699 |
+
}
|
1700 |
+
|
1701 |
+
if ( $response->SD[ 1 ]->COUNTRY && $response->SD[ 1 ]->COUNTRY->attributes() ) {
|
1702 |
+
$country = $response->SD[ 1 ]->COUNTRY->attributes();
|
1703 |
+
if ( !empty( $country ) ) {
|
1704 |
+
$rankings[ 'alexa_country_rank' ][ 0 ] = number_format( floatval( $country[ 'RANK' ] ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1705 |
+
}
|
1706 |
+
}
|
1707 |
+
else if ( $response->SD[ 1 ]->RANK && $response->SD[ 1 ]->RANK->attributes() ) {
|
1708 |
+
$rank = $response->SD[ 1 ]->RANK->attributes();
|
1709 |
+
if ( !empty( $rank ) ) {
|
1710 |
+
$rankings[ 'alexa_country_rank' ][ 0 ] = number_format( floatval( $rank[ 'DELTA' ] ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1711 |
+
$rankings[ 'alexa_country_rank' ][ 1 ] = __( 'Alexa Delta', 'wp-slimstat' );
|
1712 |
+
}
|
1713 |
+
}
|
1714 |
+
}
|
1715 |
+
}
|
1716 |
+
|
1717 |
+
// Facebook
|
1718 |
+
$options[ 'headers' ][ 'Accept' ] = 'text/xml';
|
1719 |
+
$response = @wp_remote_get( 'http://api.facebook.com/restserver.php?method=links.getStats&urls=' . $site_url, $options );
|
1720 |
+
if ( !is_wp_error( $response ) && isset( $response[ 'response' ][ 'code' ] ) && ( $response[ 'response' ][ 'code' ] == 200 ) && !empty( $response[ 'body' ] ) ) {
|
1721 |
+
$response = @simplexml_load_string( $response[ 'body' ] );
|
1722 |
+
if ( is_object( $response ) && is_object( $response->link_stat ) ) {
|
1723 |
+
$rankings[ 'facebook_shares' ][ 0 ] = number_format( intval( $response->link_stat->share_count ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1724 |
+
$rankings[ 'facebook_clicks' ][ 0 ] = number_format( intval( $response->link_stat->click_count ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1725 |
+
}
|
1726 |
+
}
|
1727 |
+
|
1728 |
+
// Store rankings as transients for 12 hours
|
1729 |
+
//set_transient('slimstat_ranking_values', $rankings, 43200);
|
1730 |
+
}
|
1731 |
+
|
1732 |
+
foreach ( $rankings as $a_ranking ) {
|
1733 |
+
echo '<p>' . self::inline_help( $a_ranking[ 2 ], false ) . $a_ranking[ 1 ] . '<span>' . $a_ranking[ 0 ] . '</span></p>';
|
1734 |
+
}
|
1735 |
+
|
1736 |
+
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
1737 |
+
die();
|
1738 |
+
}
|
1739 |
+
}
|
1740 |
+
|
1741 |
+
public static function get_your_blog(){
|
1742 |
+
if ( false === ( $results = get_transient( 'slimstat_your_content' ) ) ) {
|
1743 |
+
$results = array();
|
1744 |
+
|
1745 |
+
$results[ 0 ][ 'metric' ] = __( 'Content Items', 'wp-slimstat' );
|
1746 |
+
$results[ 0 ][ 'value' ] = number_format( $GLOBALS[ 'wpdb' ]->get_var( "SELECT COUNT(*) FROM {$GLOBALS['wpdb']->posts} WHERE post_type <> 'revision' AND post_status <> 'auto-draft'" ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1747 |
+
$results[ 0 ][ 'tooltip' ] = __( 'This value includes not only posts, but also custom post types, regardless of their status', 'wp-slimstat' );
|
1748 |
+
|
1749 |
+
$results[ 1 ][ 'metric' ] = __( 'Posts', 'wp-slimstat' );
|
1750 |
+
$results[ 1 ][ 'value' ] = $GLOBALS[ 'wpdb' ]->get_var( "SELECT COUNT(*) FROM {$GLOBALS['wpdb']->posts} WHERE post_type = 'post'" );
|
1751 |
+
|
1752 |
+
$results[ 2 ][ 'metric' ] = __( 'Pages', 'wp-slimstat' );
|
1753 |
+
$results[ 2 ][ 'value' ] = number_format( $GLOBALS[ 'wpdb' ]->get_var( "SELECT COUNT(*) FROM {$GLOBALS['wpdb']->posts} WHERE post_type = 'page'" ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1754 |
+
|
1755 |
+
$results[ 3 ][ 'metric' ] = __( 'Attachments', 'wp-slimstat' );
|
1756 |
+
$results[ 3 ][ 'value' ] = number_format( $GLOBALS[ 'wpdb' ]->get_var( "SELECT COUNT(*) FROM {$GLOBALS['wpdb']->posts} WHERE post_type = 'attachment'" ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1757 |
+
|
1758 |
+
$results[ 4 ][ 'metric' ] = __( 'Revisions', 'wp-slimstat' );
|
1759 |
+
$results[ 4 ][ 'value' ] = number_format( $GLOBALS[ 'wpdb' ]->get_var( "SELECT COUNT(*) FROM {$GLOBALS['wpdb']->posts} WHERE post_type = 'revision'" ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1760 |
+
|
1761 |
+
$results[ 5 ][ 'metric' ] = __( 'Comments', 'wp-slimstat' );
|
1762 |
+
$results[ 5 ][ 'value' ] = $GLOBALS[ 'wpdb' ]->get_var( "SELECT COUNT(*) FROM {$GLOBALS['wpdb']->comments}" );
|
1763 |
+
|
1764 |
+
$results[ 6 ][ 'metric' ] = __( 'Avg Comments per Post', 'wp-slimstat' );
|
1765 |
+
$results[ 6 ][ 'value' ] = number_format( !empty( $results[ 1 ][ 'value' ] ) ? $results[ 5 ][ 'value' ] / $results[ 1 ][ 'value' ] : 0, 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1766 |
+
|
1767 |
+
$results[ 7 ][ 'metric' ] = __( 'Avg Server Latency', 'wp-slimstat' );
|
1768 |
+
$results[ 7 ][ 'value' ] = number_format( wp_slimstat::$wpdb->get_var( "SELECT AVG(server_latency) FROM {$GLOBALS[ 'wpdb' ]->prefix }slim_stats WHERE server_latency <> 0" ), 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1769 |
+
$results[ 7 ][ 'tooltip' ] = __( 'Latency is the amount of time it takes for the host server to receive and process a request for a page object. The amount of latency depends largely on how far away the user is from the server.', 'wp-slimstat' );
|
1770 |
+
|
1771 |
+
$results[ 1 ][ 'value' ] = number_format( $results[ 1 ][ 'value' ], 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1772 |
+
$results[ 5 ][ 'value' ] = number_format( $results[ 5 ][ 'value' ], 0, '', wp_slimstat_db::$formats[ 'thousand' ] );
|
1773 |
+
|
1774 |
+
// Store values as transients for 30 minutes
|
1775 |
+
set_transient( 'slimstat_your_content', $results, 1800 );
|
1776 |
+
}
|
1777 |
+
|
1778 |
+
return $results;
|
1779 |
+
}
|
1780 |
+
|
1781 |
+
public static function show_events( $_args = array() ) {
|
1782 |
+
$all_results = call_user_func( $_args[ 'raw' ] , $_args );
|
1783 |
+
|
1784 |
+
$results = array_slice(
|
1785 |
+
$all_results,
|
1786 |
+
wp_slimstat_db::$filters_normalized[ 'misc' ][ 'start_from' ],
|
1787 |
+
wp_slimstat::$settings[ 'rows_to_show' ]
|
1788 |
+
);
|
1789 |
+
|
1790 |
+
// Count the results
|
1791 |
+
$count_page_results = count( $results );
|
1792 |
+
|
1793 |
+
if ($count_page_results == 0){
|
1794 |
+
echo '<p class="nodata">' . __( 'No data to display', 'wp-slimstat' ) . '</p>';
|
1795 |
+
|
1796 |
+
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
1797 |
+
die();
|
1798 |
+
}
|
1799 |
+
else{
|
1800 |
+
return array();
|
1801 |
+
}
|
1802 |
+
}
|
1803 |
+
|
1804 |
+
echo self::report_pagination( $count_page_results, count( $all_results ) );
|
1805 |
+
$is_expanded = ( wp_slimstat::$settings[ 'expand_details' ] == 'on' ) ? ' expanded' : '';
|
1806 |
+
|
1807 |
+
foreach ( $results as $a_result ) {
|
1808 |
+
echo "<p class='slimstat-tooltip-trigger'>{$a_result[ 'notes' ]} <b class='slimstat-tooltip-content$is_expanded'>" . __( 'Type', 'wp-slimstat' ) . ": {$a_result[ 'type' ]}";
|
1809 |
+
|
1810 |
+
if ( !empty( $a_result[ 'dt' ] ) ) {
|
1811 |
+
$date_time = date_i18n( wp_slimstat::$settings[ 'date_format' ] . ' ' . wp_slimstat::$settings[ 'time_format' ], $a_result[ 'dt' ], true );
|
1812 |
+
echo '<br/>' . __( 'Coordinates', 'wp-slimstat' ) . ": {$a_result[ 'position' ]}<br/>" . __( 'Date', 'wp-slimstat' ) . ": $date_time";
|
1813 |
+
}
|
1814 |
+
if ( !empty( $a_result[ 'counthits' ] ) ) {
|
1815 |
+
echo '<br/>' . __( 'Hits', 'wp-slimstat' ) . ": {$a_result[ 'counthits' ]}";
|
1816 |
+
}
|
1817 |
+
|
1818 |
+
echo "</b></p>";
|
1819 |
+
}
|
1820 |
+
|
1821 |
+
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
1822 |
+
die();
|
1823 |
+
}
|
1824 |
+
}
|
1825 |
+
|
1826 |
+
public static function show_world_map() {
|
1827 |
+
$countries = wp_slimstat_db::get_top( 'country' );
|
1828 |
+
$recent_visits = wp_slimstat_db::get_recent( 'location', '', '', true, '', 'city' );
|
1829 |
+
|
1830 |
+
$data_points = array();
|
1831 |
+
if ( !empty( $recent_visits ) ) {
|
1832 |
+
$recent_visits = array_slice( $recent_visits, 0, wp_slimstat::$settings[ 'max_dots_on_map' ] );
|
1833 |
+
|
1834 |
+
foreach ( $recent_visits as $a_recent_visit ) {
|
1835 |
+
if ( !empty( $a_recent_visit[ 'city' ] ) && !empty( $a_recent_visit[ 'location' ] ) ) {
|
1836 |
+
list( $latitude, $longitude ) = explode( ',', $a_recent_visit[ 'location' ] );
|
1837 |
+
$clean_city_name = htmlentities( $a_recent_visit[ 'city' ], ENT_QUOTES, 'UTF-8' );
|
1838 |
+
$date_time = date_i18n( wp_slimstat::$settings[ 'date_format' ] . ' ' . wp_slimstat::$settings[ 'time_format' ], $a_recent_visit[ 'dt' ], true );
|
1839 |
+
$data_points[] = "{zoomLevel:7,type:'circle',title:'{$clean_city_name}<br>{$date_time}',latitude:$latitude,longitude:$longitude}";
|
1840 |
+
}
|
1841 |
+
}
|
1842 |
+
}
|
1843 |
+
|
1844 |
+
$data_areas = array('xx'=>'{id:"XX",balloonText:"'.__('c-xx','wp-slimstat').': 0",value:0,color:"#ededed"}','af'=>'{id:"AF",balloonText:"'.__('c-af','wp-slimstat').': 0",value:0,color:"#ededed"}','ax'=>'{id:"AX",balloonText:"'.__('c-ax','wp-slimstat').': 0",value:0,color:"#ededed"}','al'=>'{id:"AL",balloonText:"'.__('c-al','wp-slimstat').': 0",value:0,color:"#ededed"}','dz'=>'{id:"DZ",balloonText:"'.__('c-dz','wp-slimstat').': 0",value:0,color:"#ededed"}','ad'=>'{id:"AD",balloonText:"'.__('c-ad','wp-slimstat').': 0",value:0,color:"#ededed"}','ao'=>'{id:"AO",balloonText:"'.__('c-ao','wp-slimstat').': 0",value:0,color:"#ededed"}','ai'=>'{id:"AI",balloonText:"'.__('c-ai','wp-slimstat').': 0",value:0,color:"#ededed"}','ag'=>'{id:"AG",balloonText:"'.__('c-ag','wp-slimstat').': 0",value:0,color:"#ededed"}','ar'=>'{id:"AR",balloonText:"'.__('c-ar','wp-slimstat').': 0",value:0,color:"#ededed"}','am'=>'{id:"AM",balloonText:"'.__('c-am','wp-slimstat').': 0",value:0,color:"#ededed"}','aw'=>'{id:"AW",balloonText:"'.__('c-aw','wp-slimstat').': 0",value:0,color:"#ededed"}','au'=>'{id:"AU",balloonText:"'.__('c-au','wp-slimstat').': 0",value:0,color:"#ededed"}','at'=>'{id:"AT",balloonText:"'.__('c-at','wp-slimstat').': 0",value:0,color:"#ededed"}','az'=>'{id:"AZ",balloonText:"'.__('c-az','wp-slimstat').': 0",value:0,color:"#ededed"}','bs'=>'{id:"BS",balloonText:"'.__('c-bs','wp-slimstat').': 0",value:0,color:"#ededed"}','bh'=>'{id:"BH",balloonText:"'.__('c-bh','wp-slimstat').': 0",value:0,color:"#ededed"}','bd'=>'{id:"BD",balloonText:"'.__('c-bd','wp-slimstat').': 0",value:0,color:"#ededed"}','bb'=>'{id:"BB",balloonText:"'.__('c-bb','wp-slimstat').': 0",value:0,color:"#ededed"}','by'=>'{id:"BY",balloonText:"'.__('c-by','wp-slimstat').': 0",value:0,color:"#ededed"}','be'=>'{id:"BE",balloonText:"'.__('c-be','wp-slimstat').': 0",value:0,color:"#ededed"}','bz'=>'{id:"BZ",balloonText:"'.__('c-bz','wp-slimstat').': 0",value:0,color:"#ededed"}','bj'=>'{id:"BJ",balloonText:"'.__('c-bj','wp-slimstat').': 0",value:0,color:"#ededed"}','bm'=>'{id:"BM",balloonText:"'.__('c-bm','wp-slimstat').': 0",value:0,color:"#ededed"}','bt'=>'{id:"BT",balloonText:"'.__('c-bt','wp-slimstat').': 0",value:0,color:"#ededed"}','bo'=>'{id:"BO",balloonText:"'.__('c-bo','wp-slimstat').': 0",value:0,color:"#ededed"}','ba'=>'{id:"BA",balloonText:"'.__('c-ba','wp-slimstat').': 0",value:0,color:"#ededed"}','bw'=>'{id:"BW",balloonText:"'.__('c-bw','wp-slimstat').': 0",value:0,color:"#ededed"}','br'=>'{id:"BR",balloonText:"'.__('c-br','wp-slimstat').': 0",value:0,color:"#ededed"}','bn'=>'{id:"BN",balloonText:"'.__('c-bn','wp-slimstat').': 0",value:0,color:"#ededed"}','bg'=>'{id:"BG",balloonText:"'.__('c-bg','wp-slimstat').': 0",value:0,color:"#ededed"}','bf'=>'{id:"BF",balloonText:"'.__('c-bf','wp-slimstat').': 0",value:0,color:"#ededed"}','bi'=>'{id:"BI",balloonText:"'.__('c-bi','wp-slimstat').': 0",value:0,color:"#ededed"}','kh'=>'{id:"KH",balloonText:"'.__('c-kh','wp-slimstat').': 0",value:0,color:"#ededed"}','cm'=>'{id:"CM",balloonText:"'.__('c-cm','wp-slimstat').': 0",value:0,color:"#ededed"}','ca'=>'{id:"CA",balloonText:"'.__('c-ca','wp-slimstat').': 0",value:0,color:"#ededed"}','cv'=>'{id:"CV",balloonText:"'.__('c-cv','wp-slimstat').': 0",value:0,color:"#ededed"}','ky'=>'{id:"KY",balloonText:"'.__('c-ky','wp-slimstat').': 0",value:0,color:"#ededed"}','cf'=>'{id:"CF",balloonText:"'.__('c-cf','wp-slimstat').': 0",value:0,color:"#ededed"}','td'=>'{id:"TD",balloonText:"'.__('c-td','wp-slimstat').': 0",value:0,color:"#ededed"}','cl'=>'{id:"CL",balloonText:"'.__('c-cl','wp-slimstat').': 0",value:0,color:"#ededed"}','cn'=>'{id:"CN",balloonText:"'.__('c-cn','wp-slimstat').': 0",value:0,color:"#ededed"}','co'=>'{id:"CO",balloonText:"'.__('c-co','wp-slimstat').': 0",value:0,color:"#ededed"}','km'=>'{id:"KM",balloonText:"'.__('c-km','wp-slimstat').': 0",value:0,color:"#ededed"}','cg'=>'{id:"CG",balloonText:"'.__('c-cg','wp-slimstat').': 0",value:0,color:"#ededed"}','cd'=>'{id:"CD",balloonText:"'.__('c-cd','wp-slimstat').': 0",value:0,color:"#ededed"}','cr'=>'{id:"CR",balloonText:"'.__('c-cr','wp-slimstat').': 0",value:0,color:"#ededed"}','ci'=>'{id:"CI",balloonText:"'.__('c-ci','wp-slimstat').': 0",value:0,color:"#ededed"}','hr'=>'{id:"HR",balloonText:"'.__('c-hr','wp-slimstat').': 0",value:0,color:"#ededed"}','cu'=>'{id:"CU",balloonText:"'.__('c-cu','wp-slimstat').': 0",value:0,color:"#ededed"}','cy'=>'{id:"CY",balloonText:"'.__('c-cy','wp-slimstat').': 0",value:0,color:"#ededed"}','cz'=>'{id:"CZ",balloonText:"'.__('c-cz','wp-slimstat').': 0",value:0,color:"#ededed"}','dk'=>'{id:"DK",balloonText:"'.__('c-dk','wp-slimstat').': 0",value:0,color:"#ededed"}','dj'=>'{id:"DJ",balloonText:"'.__('c-dj','wp-slimstat').': 0",value:0,color:"#ededed"}','dm'=>'{id:"DM",balloonText:"'.__('c-dm','wp-slimstat').': 0",value:0,color:"#ededed"}','do'=>'{id:"DO",balloonText:"'.__('c-do','wp-slimstat').': 0",value:0,color:"#ededed"}','ec'=>'{id:"EC",balloonText:"'.__('c-ec','wp-slimstat').': 0",value:0,color:"#ededed"}','eg'=>'{id:"EG",balloonText:"'.__('c-eg','wp-slimstat').': 0",value:0,color:"#ededed"}','sv'=>'{id:"SV",balloonText:"'.__('c-sv','wp-slimstat').': 0",value:0,color:"#ededed"}','gq'=>'{id:"GQ",balloonText:"'.__('c-gq','wp-slimstat').': 0",value:0,color:"#ededed"}','er'=>'{id:"ER",balloonText:"'.__('c-er','wp-slimstat').': 0",value:0,color:"#ededed"}','ee'=>'{id:"EE",balloonText:"'.__('c-ee','wp-slimstat').': 0",value:0,color:"#ededed"}','et'=>'{id:"ET",balloonText:"'.__('c-et','wp-slimstat').': 0",value:0,color:"#ededed"}','fo'=>'{id:"FO",balloonText:"'.__('c-fo','wp-slimstat').': 0",value:0,color:"#ededed"}','fk'=>'{id:"FK",balloonText:"'.__('c-fk','wp-slimstat').': 0",value:0,color:"#ededed"}','fj'=>'{id:"FJ",balloonText:"'.__('c-fj','wp-slimstat').': 0",value:0,color:"#ededed"}','fi'=>'{id:"FI",balloonText:"'.__('c-fi','wp-slimstat').': 0",value:0,color:"#ededed"}','fr'=>'{id:"FR",balloonText:"'.__('c-fr','wp-slimstat').': 0",value:0,color:"#ededed"}','gf'=>'{id:"GF",balloonText:"'.__('c-gf','wp-slimstat').': 0",value:0,color:"#ededed"}','ga'=>'{id:"GA",balloonText:"'.__('c-ga','wp-slimstat').': 0",value:0,color:"#ededed"}','gm'=>'{id:"GM",balloonText:"'.__('c-gm','wp-slimstat').': 0",value:0,color:"#ededed"}','ge'=>'{id:"GE",balloonText:"'.__('c-ge','wp-slimstat').': 0",value:0,color:"#ededed"}','de'=>'{id:"DE",balloonText:"'.__('c-de','wp-slimstat').': 0",value:0,color:"#ededed"}','gh'=>'{id:"GH",balloonText:"'.__('c-gh','wp-slimstat').': 0",value:0,color:"#ededed"}','gr'=>'{id:"GR",balloonText:"'.__('c-gr','wp-slimstat').': 0",value:0,color:"#ededed"}','gl'=>'{id:"GL",balloonText:"'.__('c-gl','wp-slimstat').': 0",value:0,color:"#ededed"}','gd'=>'{id:"GD",balloonText:"'.__('c-gd','wp-slimstat').': 0",value:0,color:"#ededed"}','gp'=>'{id:"GP",balloonText:"'.__('c-gp','wp-slimstat').': 0",value:0,color:"#ededed"}','gt'=>'{id:"GT",balloonText:"'.__('c-gt','wp-slimstat').': 0",value:0,color:"#ededed"}','gn'=>'{id:"GN",balloonText:"'.__('c-gn','wp-slimstat').': 0",value:0,color:"#ededed"}','gw'=>'{id:"GW",balloonText:"'.__('c-gw','wp-slimstat').': 0",value:0,color:"#ededed"}','gy'=>'{id:"GY",balloonText:"'.__('c-gy','wp-slimstat').': 0",value:0,color:"#ededed"}','ht'=>'{id:"HT",balloonText:"'.__('c-ht','wp-slimstat').': 0",value:0,color:"#ededed"}','hn'=>'{id:"HN",balloonText:"'.__('c-hn','wp-slimstat').': 0",value:0,color:"#ededed"}','hk'=>'{id:"HK",balloonText:"'.__('c-hk','wp-slimstat').': 0",value:0,color:"#ededed"}','hu'=>'{id:"HU",balloonText:"'.__('c-hu','wp-slimstat').': 0",value:0,color:"#ededed"}','is'=>'{id:"IS",balloonText:"'.__('c-is','wp-slimstat').': 0",value:0,color:"#ededed"}','in'=>'{id:"IN",balloonText:"'.__('c-in','wp-slimstat').': 0",value:0,color:"#ededed"}','id'=>'{id:"ID",balloonText:"'.__('c-id','wp-slimstat').': 0",value:0,color:"#ededed"}','ir'=>'{id:"IR",balloonText:"'.__('c-ir','wp-slimstat').': 0",value:0,color:"#ededed"}','iq'=>'{id:"IQ",balloonText:"'.__('c-iq','wp-slimstat').': 0",value:0,color:"#ededed"}','ie'=>'{id:"IE",balloonText:"'.__('c-ie','wp-slimstat').': 0",value:0,color:"#ededed"}','il'=>'{id:"IL",balloonText:"'.__('c-il','wp-slimstat').': 0",value:0,color:"#ededed"}','it'=>'{id:"IT",balloonText:"'.__('c-it','wp-slimstat').': 0",value:0,color:"#ededed"}','jm'=>'{id:"JM",balloonText:"'.__('c-jm','wp-slimstat').': 0",value:0,color:"#ededed"}','jp'=>'{id:"JP",balloonText:"'.__('c-jp','wp-slimstat').': 0",value:0,color:"#ededed"}','jo'=>'{id:"JO",balloonText:"'.__('c-jo','wp-slimstat').': 0",value:0,color:"#ededed"}','kz'=>'{id:"KZ",balloonText:"'.__('c-kz','wp-slimstat').': 0",value:0,color:"#ededed"}','ke'=>'{id:"KE",balloonText:"'.__('c-ke','wp-slimstat').': 0",value:0,color:"#ededed"}','nr'=>'{id:"NR",balloonText:"'.__('c-nr','wp-slimstat').': 0",value:0,color:"#ededed"}','kp'=>'{id:"KP",balloonText:"'.__('c-kp','wp-slimstat').': 0",value:0,color:"#ededed"}','kr'=>'{id:"KR",balloonText:"'.__('c-kr','wp-slimstat').': 0",value:0,color:"#ededed"}','kv'=>'{id:"KV",balloonText:"'.__('c-kv','wp-slimstat').': 0",value:0,color:"#ededed"}','kw'=>'{id:"KW",balloonText:"'.__('c-kw','wp-slimstat').': 0",value:0,color:"#ededed"}','kg'=>'{id:"KG",balloonText:"'.__('c-kg','wp-slimstat').': 0",value:0,color:"#ededed"}','la'=>'{id:"LA",balloonText:"'.__('c-la','wp-slimstat').': 0",value:0,color:"#ededed"}','lv'=>'{id:"LV",balloonText:"'.__('c-lv','wp-slimstat').': 0",value:0,color:"#ededed"}','lb'=>'{id:"LB",balloonText:"'.__('c-lb','wp-slimstat').': 0",value:0,color:"#ededed"}','ls'=>'{id:"LS",balloonText:"'.__('c-ls','wp-slimstat').': 0",value:0,color:"#ededed"}','lr'=>'{id:"LR",balloonText:"'.__('c-lr','wp-slimstat').': 0",value:0,color:"#ededed"}','ly'=>'{id:"LY",balloonText:"'.__('c-ly','wp-slimstat').': 0",value:0,color:"#ededed"}','li'=>'{id:"LI",balloonText:"'.__('c-li','wp-slimstat').': 0",value:0,color:"#ededed"}','lt'=>'{id:"LT",balloonText:"'.__('c-lt','wp-slimstat').': 0",value:0,color:"#ededed"}','lu'=>'{id:"LU",balloonText:"'.__('c-lu','wp-slimstat').': 0",value:0,color:"#ededed"}','mk'=>'{id:"MK",balloonText:"'.__('c-mk','wp-slimstat').': 0",value:0,color:"#ededed"}','mg'=>'{id:"MG",balloonText:"'.__('c-mg','wp-slimstat').': 0",value:0,color:"#ededed"}','mw'=>'{id:"MW",balloonText:"'.__('c-mw','wp-slimstat').': 0",value:0,color:"#ededed"}','my'=>'{id:"MY",balloonText:"'.__('c-my','wp-slimstat').': 0",value:0,color:"#ededed"}','ml'=>'{id:"ML",balloonText:"'.__('c-ml','wp-slimstat').': 0",value:0,color:"#ededed"}','mt'=>'{id:"MT",balloonText:"'.__('c-mt','wp-slimstat').': 0",value:0,color:"#ededed"}','mq'=>'{id:"MQ",balloonText:"'.__('c-mq','wp-slimstat').': 0",value:0,color:"#ededed"}','mr'=>'{id:"MR",balloonText:"'.__('c-mr','wp-slimstat').': 0",value:0,color:"#ededed"}','mu'=>'{id:"MU",balloonText:"'.__('c-mu','wp-slimstat').': 0",value:0,color:"#ededed"}','mx'=>'{id:"MX",balloonText:"'.__('c-mx','wp-slimstat').': 0",value:0,color:"#ededed"}','md'=>'{id:"MD",balloonText:"'.__('c-md','wp-slimstat').': 0",value:0,color:"#ededed"}','mn'=>'{id:"MN",balloonText:"'.__('c-mn','wp-slimstat').': 0",value:0,color:"#ededed"}','me'=>'{id:"ME",balloonText:"'.__('c-me','wp-slimstat').': 0",value:0,color:"#ededed"}','ms'=>'{id:"MS",balloonText:"'.__('c-ms','wp-slimstat').': 0",value:0,color:"#ededed"}','ma'=>'{id:"MA",balloonText:"'.__('c-ma','wp-slimstat').': 0",value:0,color:"#ededed"}','mz'=>'{id:"MZ",balloonText:"'.__('c-mz','wp-slimstat').': 0",value:0,color:"#ededed"}','mm'=>'{id:"MM",balloonText:"'.__('c-mm','wp-slimstat').': 0",value:0,color:"#ededed"}','na'=>'{id:"NA",balloonText:"'.__('c-na','wp-slimstat').': 0",value:0,color:"#ededed"}','np'=>'{id:"NP",balloonText:"'.__('c-np','wp-slimstat').': 0",value:0,color:"#ededed"}','nl'=>'{id:"NL",balloonText:"'.__('c-nl','wp-slimstat').': 0",value:0,color:"#ededed"}','nc'=>'{id:"NC",balloonText:"'.__('c-nc','wp-slimstat').': 0",value:0,color:"#ededed"}','nz'=>'{id:"NZ",balloonText:"'.__('c-nz','wp-slimstat').': 0",value:0,color:"#ededed"}','ni'=>'{id:"NI",balloonText:"'.__('c-ni','wp-slimstat').': 0",value:0,color:"#ededed"}','ne'=>'{id:"NE",balloonText:"'.__('c-ne','wp-slimstat').': 0",value:0,color:"#ededed"}','ng'=>'{id:"NG",balloonText:"'.__('c-ng','wp-slimstat').': 0",value:0,color:"#ededed"}','no'=>'{id:"NO",balloonText:"'.__('c-no','wp-slimstat').': 0",value:0,color:"#ededed"}','om'=>'{id:"OM",balloonText:"'.__('c-om','wp-slimstat').': 0",value:0,color:"#ededed"}','pk'=>'{id:"PK",balloonText:"'.__('c-pk','wp-slimstat').': 0",value:0,color:"#ededed"}','pw'=>'{id:"PW",balloonText:"'.__('c-pw','wp-slimstat').': 0",value:0,color:"#ededed"}','ps'=>'{id:"PS",balloonText:"'.__('c-ps','wp-slimstat').': 0",value:0,color:"#ededed"}','pa'=>'{id:"PA",balloonText:"'.__('c-pa','wp-slimstat').': 0",value:0,color:"#ededed"}','pg'=>'{id:"PG",balloonText:"'.__('c-pg','wp-slimstat').': 0",value:0,color:"#ededed"}','py'=>'{id:"PY",balloonText:"'.__('c-py','wp-slimstat').': 0",value:0,color:"#ededed"}','pe'=>'{id:"PE",balloonText:"'.__('c-pe','wp-slimstat').': 0",value:0,color:"#ededed"}','ph'=>'{id:"PH",balloonText:"'.__('c-ph','wp-slimstat').': 0",value:0,color:"#ededed"}','pl'=>'{id:"PL",balloonText:"'.__('c-pl','wp-slimstat').': 0",value:0,color:"#ededed"}','pt'=>'{id:"PT",balloonText:"'.__('c-pt','wp-slimstat').': 0",value:0,color:"#ededed"}','pr'=>'{id:"PR",balloonText:"'.__('c-pr','wp-slimstat').': 0",value:0,color:"#ededed"}','qa'=>'{id:"QA",balloonText:"'.__('c-qa','wp-slimstat').': 0",value:0,color:"#ededed"}','re'=>'{id:"RE",balloonText:"'.__('c-re','wp-slimstat').': 0",value:0,color:"#ededed"}','ro'=>'{id:"RO",balloonText:"'.__('c-ro','wp-slimstat').': 0",value:0,color:"#ededed"}','ru'=>'{id:"RU",balloonText:"'.__('c-ru','wp-slimstat').': 0",value:0,color:"#ededed"}','rw'=>'{id:"RW",balloonText:"'.__('c-rw','wp-slimstat').': 0",value:0,color:"#ededed"}','kn'=>'{id:"KN",balloonText:"'.__('c-kn','wp-slimstat').': 0",value:0,color:"#ededed"}','lc'=>'{id:"LC",balloonText:"'.__('c-lc','wp-slimstat').': 0",value:0,color:"#ededed"}','mf'=>'{id:"MF",balloonText:"'.__('c-mf','wp-slimstat').': 0",value:0,color:"#ededed"}','vc'=>'{id:"VC",balloonText:"'.__('c-vc','wp-slimstat').': 0",value:0,color:"#ededed"}','ws'=>'{id:"WS",balloonText:"'.__('c-ws','wp-slimstat').': 0",value:0,color:"#ededed"}','st'=>'{id:"ST",balloonText:"'.__('c-st','wp-slimstat').': 0",value:0,color:"#ededed"}','sa'=>'{id:"SA",balloonText:"'.__('c-sa','wp-slimstat').': 0",value:0,color:"#ededed"}','sn'=>'{id:"SN",balloonText:"'.__('c-sn','wp-slimstat').': 0",value:0,color:"#ededed"}','rs'=>'{id:"RS",balloonText:"'.__('c-rs','wp-slimstat').': 0",value:0,color:"#ededed"}','sl'=>'{id:"SL",balloonText:"'.__('c-sl','wp-slimstat').': 0",value:0,color:"#ededed"}','sg'=>'{id:"SG",balloonText:"'.__('c-sg','wp-slimstat').': 0",value:0,color:"#ededed"}','sk'=>'{id:"SK",balloonText:"'.__('c-sk','wp-slimstat').': 0",value:0,color:"#ededed"}','si'=>'{id:"SI",balloonText:"'.__('c-si','wp-slimstat').': 0",value:0,color:"#ededed"}','sb'=>'{id:"SB",balloonText:"'.__('c-sb','wp-slimstat').': 0",value:0,color:"#ededed"}','so'=>'{id:"SO",balloonText:"'.__('c-so','wp-slimstat').': 0",value:0,color:"#ededed"}','za'=>'{id:"ZA",balloonText:"'.__('c-za','wp-slimstat').': 0",value:0,color:"#ededed"}','gs'=>'{id:"GS",balloonText:"'.__('c-gs','wp-slimstat').': 0",value:0,color:"#ededed"}','es'=>'{id:"ES",balloonText:"'.__('c-es','wp-slimstat').': 0",value:0,color:"#ededed"}','lk'=>'{id:"LK",balloonText:"'.__('c-lk','wp-slimstat').': 0",value:0,color:"#ededed"}','sc'=>'{id:"SC",balloonText:"'.__('c-sc','wp-slimstat').': 0",value:0,color:"#ededed"}','sd'=>'{id:"SD",balloonText:"'.__('c-sd','wp-slimstat').': 0",value:0,color:"#ededed"}','ss'=>'{id:"SS",balloonText:"'.__('c-ss','wp-slimstat').': 0",value:0,color:"#ededed"}','sr'=>'{id:"SR",balloonText:"'.__('c-sr','wp-slimstat').': 0",value:0,color:"#ededed"}','sj'=>'{id:"SJ",balloonText:"'.__('c-sj','wp-slimstat').': 0",value:0,color:"#ededed"}','sz'=>'{id:"SZ",balloonText:"'.__('c-sz','wp-slimstat').': 0",value:0,color:"#ededed"}','se'=>'{id:"SE",balloonText:"'.__('c-se','wp-slimstat').': 0",value:0,color:"#ededed"}','ch'=>'{id:"CH",balloonText:"'.__('c-ch','wp-slimstat').': 0",value:0,color:"#ededed"}','sy'=>'{id:"SY",balloonText:"'.__('c-sy','wp-slimstat').': 0",value:0,color:"#ededed"}','tw'=>'{id:"TW",balloonText:"'.__('c-tw','wp-slimstat').': 0",value:0,color:"#ededed"}','tj'=>'{id:"TJ",balloonText:"'.__('c-tj','wp-slimstat').': 0",value:0,color:"#ededed"}','tz'=>'{id:"TZ",balloonText:"'.__('c-tz','wp-slimstat').': 0",value:0,color:"#ededed"}','th'=>'{id:"TH",balloonText:"'.__('c-th','wp-slimstat').': 0",value:0,color:"#ededed"}','tl'=>'{id:"TL",balloonText:"'.__('c-tl','wp-slimstat').': 0",value:0,color:"#ededed"}','tg'=>'{id:"TG",balloonText:"'.__('c-tg','wp-slimstat').': 0",value:0,color:"#ededed"}','to'=>'{id:"TO",balloonText:"'.__('c-to','wp-slimstat').': 0",value:0,color:"#ededed"}','tt'=>'{id:"TT",balloonText:"'.__('c-tt','wp-slimstat').': 0",value:0,color:"#ededed"}','tn'=>'{id:"TN",balloonText:"'.__('c-tn','wp-slimstat').': 0",value:0,color:"#ededed"}','tr'=>'{id:"TR",balloonText:"'.__('c-tr','wp-slimstat').': 0",value:0,color:"#ededed"}','tm'=>'{id:"TM",balloonText:"'.__('c-tm','wp-slimstat').': 0",value:0,color:"#ededed"}','tc'=>'{id:"TC",balloonText:"'.__('c-tc','wp-slimstat').': 0",value:0,color:"#ededed"}','ug'=>'{id:"UG",balloonText:"'.__('c-ug','wp-slimstat').': 0",value:0,color:"#ededed"}','ua'=>'{id:"UA",balloonText:"'.__('c-ua','wp-slimstat').': 0",value:0,color:"#ededed"}','ae'=>'{id:"AE",balloonText:"'.__('c-ae','wp-slimstat').': 0",value:0,color:"#ededed"}','gb'=>'{id:"GB",balloonText:"'.__('c-gb','wp-slimstat').': 0",value:0,color:"#ededed"}','us'=>'{id:"US",balloonText:"'.__('c-us','wp-slimstat').': 0",value:0,color:"#ededed"}','uy'=>'{id:"UY",balloonText:"'.__('c-uy','wp-slimstat').': 0",value:0,color:"#ededed"}','uz'=>'{id:"UZ",balloonText:"'.__('c-uz','wp-slimstat').': 0",value:0,color:"#ededed"}','vu'=>'{id:"VU",balloonText:"'.__('c-vu','wp-slimstat').': 0",value:0,color:"#ededed"}','ve'=>'{id:"VE",balloonText:"'.__('c-ve','wp-slimstat').': 0",value:0,color:"#ededed"}','vn'=>'{id:"VN",balloonText:"'.__('c-vn','wp-slimstat').': 0",value:0,color:"#ededed"}','vg'=>'{id:"VG",balloonText:"'.__('c-vg','wp-slimstat').': 0",value:0,color:"#ededed"}','vi'=>'{id:"VI",balloonText:"'.__('c-vi','wp-slimstat').': 0",value:0,color:"#ededed"}','eh'=>'{id:"EH",balloonText:"'.__('c-eh','wp-slimstat').': 0",value:0,color:"#ededed"}','ye'=>'{id:"YE",balloonText:"'.__('c-ye','wp-slimstat').': 0",value:0,color:"#ededed"}','zm'=>'{id:"ZM",balloonText:"'.__('c-zm','wp-slimstat').': 0",value:0,color:"#ededed"}','zw'=>'{id:"ZW",balloonText:"'.__('c-zw','wp-slimstat').': 0",value:0,color:"#ededed"}','gg'=>'{id:"GG",balloonText:"'.__('c-gg','wp-slimstat').': 0",value:0,color:"#ededed"}','je'=>'{id:"JE",balloonText:"'.__('c-je','wp-slimstat').': 0",value:0,color:"#ededed"}','im'=>'{id:"IM",balloonText:"'.__('c-im','wp-slimstat').': 0",value:0,color:"#ededed"}','mv'=>'{id:"MV",balloonText:"'.__('c-mv','wp-slimstat').': 0",value:0,color:"#ededed"}');
|
1845 |
+
$countries_not_represented = array( __( 'c-eu', 'wp-slimstat' ) );
|
1846 |
+
$max = 0;
|
1847 |
+
|
1848 |
+
foreach ( $countries as $a_country ) {
|
1849 |
+
if ( !array_key_exists( $a_country[ 'country' ], $data_areas ) ) {
|
1850 |
+
continue;
|
1851 |
+
}
|
1852 |
+
|
1853 |
+
$percentage = ( self::$pageviews > 0 ) ? sprintf( "%01.2f", ( 100 * $a_country[ 'counthits' ] / self::$pageviews ) ) : 0;
|
1854 |
+
$percentage_format = number_format( $percentage, 2, wp_slimstat_db::$formats[ 'decimal' ], wp_slimstat_db::$formats[ 'thousand' ] );
|
1855 |
+
$balloon_text = __( 'c-' . $a_country[ 'country' ], 'wp-slimstat' ) . ': ' . $percentage_format . '% (' . number_format( $a_country[ 'counthits' ], 0, wp_slimstat_db::$formats[ 'decimal' ], wp_slimstat_db::$formats[ 'thousand' ] ) . ')';
|
1856 |
+
$data_areas[ $a_country[ 'country' ] ] = '{id:"' . strtoupper( $a_country[ 'country' ] ) . '",balloonText:"' . $balloon_text . '",value:' . $percentage . '}';
|
1857 |
+
|
1858 |
+
if ( $percentage > $max ) {
|
1859 |
+
$max = $percentage;
|
1860 |
+
}
|
1861 |
+
}
|
1862 |
+
|
1863 |
+
$path_slimstat = dirname( dirname( __FILE__ ) );
|
1864 |
+
wp_enqueue_script( 'slimstat_ammap', plugins_url( '/admin/js/ammap/ammap.js', $path_slimstat ), array(), null, false );
|
1865 |
+
wp_enqueue_script( 'slimstat_ammap_world', plugins_url( '/admin/js/ammap/world.js', $path_slimstat ), array(), null, false );
|
1866 |
+
wp_enqueue_script( 'slimstat_amcharts_plugins_export', plugins_url( '/admin/js/amcharts/plugins/export/export.min.js', $path_slimstat ), array( 'slimstat_ammap' ), null, false );
|
1867 |
+
wp_enqueue_script( 'slimstat_amcharts_theme_light', plugins_url( '/admin/js/amcharts/themes/light.js', $path_slimstat ), array( 'slimstat_ammap' ), null, false );
|
1868 |
+
|
1869 |
+
wp_enqueue_style( 'slimstat_amcharts_plugins_export_css', plugins_url( '/admin/js/amcharts/plugins/export/export.css', $path_slimstat ) );
|
1870 |
+
|
1871 |
+
?>
|
1872 |
+
|
1873 |
+
<div id="map_slim_p6_01" style="height: 100%"></div>
|
1874 |
+
|
1875 |
+
<script type="text/javascript">
|
1876 |
+
jQuery( function() {
|
1877 |
+
var targetSVG = "M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z";
|
1878 |
+
|
1879 |
+
var dataProvider = {
|
1880 |
+
map: "worldLow",
|
1881 |
+
getAreasFromMap: true,
|
1882 |
+
areas:[ <?php echo implode( ',', $data_areas ) ?> ],
|
1883 |
+
images: [ <?php if ( !empty( $data_points ) ) echo implode( ',', $data_points ) ?> ]
|
1884 |
+
};
|
1885 |
+
|
1886 |
+
// Create AmMap object
|
1887 |
+
var map = new AmCharts.AmMap();
|
1888 |
+
|
1889 |
+
<?php if ($max != 0): ?>
|
1890 |
+
var legend = new AmCharts.ValueLegend();
|
1891 |
+
legend.height = 20;
|
1892 |
+
legend.minValue = "0.01";
|
1893 |
+
legend.maxValue = "<?php echo $max ?>%";
|
1894 |
+
legend.right = 20;
|
1895 |
+
legend.showAsGradient = true;
|
1896 |
+
legend.width = 300;
|
1897 |
+
map.valueLegend = legend;
|
1898 |
+
<?php endif; ?>
|
1899 |
+
|
1900 |
+
// Configuration
|
1901 |
+
map.areasSettings = {
|
1902 |
+
autoZoom: false,
|
1903 |
+
color: "#9dff98",
|
1904 |
+
colorSolid: "#fa8a50",
|
1905 |
+
outlineColor: "#888888",
|
1906 |
+
selectedColor: "#ffb739"
|
1907 |
+
};
|
1908 |
+
map.imagesSettings = {
|
1909 |
+
rollOverColor: "#089282",
|
1910 |
+
rollOverScale: 2,
|
1911 |
+
selectedScale: 2,
|
1912 |
+
selectedColor: "#089282",
|
1913 |
+
color: "#13564e"
|
1914 |
+
};
|
1915 |
+
map.zoomControl = {
|
1916 |
+
zoomControlEnabled: true,
|
1917 |
+
zoomFactor: 3
|
1918 |
+
};
|
1919 |
+
map.export = {
|
1920 |
+
"enabled": true,
|
1921 |
+
"libs": {
|
1922 |
+
"path": "<?php echo plugins_url('/js/amcharts/plugins/export/libs/', dirname(__FILE__)) ?>"
|
1923 |
+
},
|
1924 |
+
"menu": [ {
|
1925 |
+
"class": "export-main",
|
1926 |
+
"menu": [ {
|
1927 |
+
"label": "Download as...",
|
1928 |
+
"menu": [ "PNG", "PDF" ]
|
1929 |
+
} ]
|
1930 |
+
} ]
|
1931 |
+
};
|
1932 |
+
map.backgroundAlpha = .9;
|
1933 |
+
map.backgroundColor = "#7adafd";
|
1934 |
+
map.backgroundZoomsToTop = false;
|
1935 |
+
map.balloon.color = "#000000";
|
1936 |
+
map.colorSteps = 5;
|
1937 |
+
map.mouseWheelZoomEnabled = true;
|
1938 |
+
map.pathToImages = "<?php echo plugins_url('/js/ammap/images/', dirname(__FILE__)) ?>";
|
1939 |
+
|
1940 |
+
// Init Data
|
1941 |
+
map.dataProvider = dataProvider;
|
1942 |
+
|
1943 |
+
// Display Map
|
1944 |
+
map.write( "map_slim_p6_01" );
|
1945 |
+
});
|
1946 |
+
</script><?php
|
1947 |
+
|
1948 |
+
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
1949 |
+
die();
|
1950 |
+
}
|
1951 |
+
}
|
1952 |
+
|
1953 |
+
public static function get_search_terms_info( $_searchterms = '', $_referer = '', $_serp_only = false ) {
|
1954 |
+
$query_details = '';
|
1955 |
+
$search_terms_info = '';
|
1956 |
+
parse_str( $_referer, $query_parse_str );
|
1957 |
+
|
1958 |
+
if ( !empty( $query_parse_str[ 'source' ] ) && !$_serp_only ) {
|
1959 |
+
$query_details = __( 'src', 'wp-slimstat' ) . ": {$query_parse_str[ 'source' ]}";
|
1960 |
+
}
|
1961 |
+
|
1962 |
+
if ( !empty( $query_parse_str[ 'cd' ] ) ) {
|
1963 |
+
$query_details = __( 'serp', 'wp-slimstat') . ": {$query_parse_str[ 'cd' ]}";
|
1964 |
+
}
|
1965 |
+
|
1966 |
+
if ( !empty( $query_details ) ) {
|
1967 |
+
$query_details = "($query_details)";
|
1968 |
+
}
|
1969 |
+
|
1970 |
+
if ( !empty( $_searchterms ) && $_searchterms != '_' ) {
|
1971 |
+
$search_terms_info = '<a class="slimstat-font-logout" target="_blank" title="' . htmlentities( __( 'Go to the referring page', 'wp-slimstat' ), ENT_QUOTES, 'UTF-8' ) . '" href="' . $_referer . '"></a>' . htmlentities( $_searchterms, ENT_QUOTES, 'UTF-8' );
|
1972 |
+
$search_terms_info = "$search_terms_info $query_details";
|
1973 |
+
}
|
1974 |
+
return $search_terms_info;
|
1975 |
+
}
|
1976 |
+
|
1977 |
+
/**
|
1978 |
+
* Generate the HTML that lists all the filters currently used
|
1979 |
+
*/
|
1980 |
+
public static function get_filters_html( $_filters_array = array() ) {
|
1981 |
+
$filters_html = '';
|
1982 |
+
|
1983 |
+
if ( !empty( $_filters_array ) ) {
|
1984 |
+
foreach( $_filters_array as $a_filter_label => $a_filter_details ) {
|
1985 |
+
if ( !array_key_exists( $a_filter_label, wp_slimstat_db::$columns_names ) || strpos( $a_filter_label, 'no_filter' ) !== false ) {
|
1986 |
+
continue;
|
1987 |
+
}
|
1988 |
+
|
1989 |
+
$a_filter_value_no_slashes = htmlentities( str_replace( '\\','', $a_filter_details[ 1 ] ), ENT_QUOTES, 'UTF-8' );
|
1990 |
+
$filters_html .= '<li>' . strtolower( wp_slimstat_db::$columns_names[ $a_filter_label ][ 0 ] ) . ' ' . __( str_replace( '_', ' ', $a_filter_details[ 0 ] ), 'wp-slimstat' ) . " $a_filter_value_no_slashes <a class='slimstat-filter-link slimstat-font-cancel' title='" . htmlentities( __( 'Remove filter for', 'wp-slimstat' ), ENT_QUOTES, 'UTF-8' ) . ' ' . wp_slimstat_db::$columns_names[ $a_filter_label ][ 0 ] . "' href='" . self::fs_url( "$a_filter_label equals " ) . "'></a></li>";
|
1991 |
+
}
|
1992 |
+
}
|
1993 |
+
|
1994 |
+
if ( !empty( $filters_html ) ) {
|
1995 |
+
$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>';
|
1996 |
+
}
|
1997 |
+
|
1998 |
+
if ( count( $_filters_array ) > 1 ) {
|
1999 |
+
$filters_html .= '<a href="' . self::fs_url() . '" id="slimstat-remove-all-filters" class="button-secondary slimstat-filter-action-button noslimstat">' . __( 'Reset All', 'wp-slimstat' ) . '</a>';
|
2000 |
+
}
|
2001 |
+
|
2002 |
+
return $filters_html;
|
2003 |
+
}
|
2004 |
+
|
2005 |
+
public static function fs_url( $_filters_string = '' ) {
|
2006 |
+
// Allow only legitimate requests
|
2007 |
+
if ( !is_admin() ) {
|
2008 |
+
return '';
|
2009 |
+
}
|
2010 |
+
|
2011 |
+
$request_uri = admin_url( 'admin.php' );
|
2012 |
+
|
2013 |
+
$request_page = 'slimview1';
|
2014 |
+
if ( !empty( $_REQUEST[ 'page' ] ) ) {
|
2015 |
+
if ( !array_key_exists( $_REQUEST[ 'page' ], wp_slimstat_admin::$screens_info ) ) {
|
2016 |
+
return '';
|
2017 |
+
}
|
2018 |
+
|
2019 |
+
$request_page = $_REQUEST[ 'page' ];
|
2020 |
+
}
|
2021 |
+
|
2022 |
+
$request_uri .= '?page=' . $request_page;
|
2023 |
+
|
2024 |
+
// Avoid XSS attacks ( why would the owner try to hack into his/her own website though? )
|
2025 |
+
if ( !empty( $_SERVER[ 'HTTP_REFERER' ] ) ) {
|
2026 |
+
$parsed_referer = parse_url( $_SERVER[ 'HTTP_REFERER' ] );
|
2027 |
+
if ( !$parsed_referer || ( !empty( $parsed_referer[ 'scheme' ] ) && !in_array( strtolower( $parsed_referer[ 'scheme' ] ), array( 'http', 'https' ) ) ) ) {
|
2028 |
+
return '';
|
2029 |
+
}
|
2030 |
+
}
|
2031 |
+
|
2032 |
+
$filters_normalized = wp_slimstat_db::parse_filters( $_filters_string );
|
2033 |
+
|
2034 |
+
// Columns
|
2035 |
+
if ( !empty( $filters_normalized[ 'columns' ] ) ) {
|
2036 |
+
foreach ( $filters_normalized[ 'columns' ] as $a_key => $a_filter ) {
|
2037 |
+
$a_key = str_replace( '_calculated', '', $a_key );
|
2038 |
+
$request_uri .= "&fs%5B$a_key%5D=" . urlencode( $a_filter[ 0 ] . ' ' . $a_filter[ 1 ] );
|
2039 |
+
}
|
2040 |
+
}
|
2041 |
+
|
2042 |
+
// Date ranges
|
2043 |
+
if ( !empty( $filters_normalized[ 'date' ] ) ) {
|
2044 |
+
foreach ( $filters_normalized[ 'date' ] as $a_key => $a_filter ) {
|
2045 |
+
if ( isset( $a_filter ) ) {
|
2046 |
+
$request_uri .= "&fs%5B$a_key%5D=" . urlencode( 'equals ' . $a_filter );
|
2047 |
+
}
|
2048 |
+
}
|
2049 |
+
}
|
2050 |
+
|
2051 |
+
// Misc filters
|
2052 |
+
if ( !empty( $filters_normalized[ 'misc' ] ) ) {
|
2053 |
+
foreach ( $filters_normalized[ 'misc' ] as $a_key => $a_filter ) {
|
2054 |
+
$request_uri .= "&fs%5B$a_key%5D=" . urlencode( 'equals ' . $a_filter );
|
2055 |
+
}
|
2056 |
+
}
|
2057 |
+
|
2058 |
+
return $request_uri;
|
2059 |
+
}
|
2060 |
+
|
2061 |
+
/**
|
2062 |
+
* Attempts to convert a permalink into a post title
|
2063 |
+
*/
|
2064 |
+
public static function get_resource_title( $_resource = '' ) {
|
2065 |
+
$resource_title = $_resource;
|
2066 |
+
|
2067 |
+
if ( wp_slimstat::$settings[ 'convert_resource_urls_to_titles' ] != 'on' ) {
|
2068 |
+
return htmlentities( urldecode( $resource_title ), ENT_QUOTES, 'UTF-8' );
|
2069 |
+
}
|
2070 |
+
|
2071 |
+
// Is this a post or a page?
|
2072 |
+
$post_id = url_to_postid( $_resource );
|
2073 |
+
|
2074 |
+
if ( $post_id > 0 ) {
|
2075 |
+
$resource_title = the_title_attribute( array( 'post' => $post_id, 'echo' => false ) );
|
2076 |
+
|
2077 |
+
// Encode URLs to avoid XSS attacks
|
2078 |
+
if ( $resource_title == $_resource ) {
|
2079 |
+
$resource_title = htmlspecialchars( $resource_title, ENT_QUOTES, 'UTF-8' );
|
2080 |
+
}
|
2081 |
+
}
|
2082 |
+
|
2083 |
+
// Is this a category or tag permalink?
|
2084 |
+
else {
|
2085 |
+
$term_names = array();
|
2086 |
+
$home_url = get_home_url();
|
2087 |
+
$relative_home = parse_url( $home_url, PHP_URL_PATH );
|
2088 |
+
|
2089 |
+
$all_terms = get_terms( 'category' );
|
2090 |
+
foreach ( $all_terms as $a_term ) {
|
2091 |
+
$term_link = get_term_link( $a_term, 'category' );
|
2092 |
+
if ( !is_wp_error( $term_link ) && str_replace( $home_url, $relative_home, $term_link ) == $_resource ) {
|
2093 |
+
$term_names[] = $a_term->name;
|
2094 |
+
}
|
2095 |
+
}
|
2096 |
+
|
2097 |
+
$all_terms = get_terms( 'tag' );
|
2098 |
+
foreach ( $all_terms as $a_term ) {
|
2099 |
+
$term_link = get_term_link( $a_term, 'tag' );
|
2100 |
+
if ( !is_wp_error( $term_link ) && str_replace( $home_url, $relative_home, $term_link ) == $_resource ) {
|
2101 |
+
$term_names[] = $a_term->name;
|
2102 |
+
}
|
2103 |
+
}
|
2104 |
+
|
2105 |
+
if ( !empty( $term_names ) ) {
|
2106 |
+
$resource_title = implode( ',', $term_names );
|
2107 |
+
}
|
2108 |
+
else {
|
2109 |
+
$resource_title = htmlspecialchars( $resource_title, ENT_QUOTES, 'UTF-8' );
|
2110 |
+
}
|
2111 |
+
}
|
2112 |
+
|
2113 |
+
return $resource_title;
|
2114 |
+
}
|
2115 |
+
|
2116 |
+
public static function inline_help( $_text = '', $_echo = true ) {
|
2117 |
+
if ( is_admin() && !empty( $_text ) ) {
|
2118 |
+
$wrapped_text = "<i class='slimstat-tooltip-trigger corner'><span class='slimstat-tooltip-content'>$_text</span></i>";
|
2119 |
+
}
|
2120 |
+
else {
|
2121 |
+
$wrapped_text = '';
|
2122 |
+
}
|
2123 |
+
|
2124 |
+
if ($_echo)
|
2125 |
+
echo $wrapped_text;
|
2126 |
+
else
|
2127 |
+
return $wrapped_text;
|
2128 |
+
}
|
2129 |
+
|
2130 |
+
protected static function _check_args( $_args = array() ) {
|
2131 |
+
|
2132 |
+
// When called from the WP Dashboard, the action passes 2 arguments: post_id (empty) and array of arguments
|
2133 |
+
if ( !empty( $_args[ 1 ] ) ) {
|
2134 |
+
$_args = $_args[ 1 ];
|
2135 |
+
}
|
2136 |
+
// When called from within Slimstat, the first argument is the array of arguments for the callback
|
2137 |
+
else {
|
2138 |
+
$_args = $_args[ 0 ];
|
2139 |
+
}
|
2140 |
+
|
2141 |
+
if ( !is_array( $_args ) ) {
|
2142 |
+
$_args = array();
|
2143 |
+
}
|
2144 |
+
|
2145 |
+
$report_id = 0;
|
2146 |
+
|
2147 |
+
// Is this an Ajax request?
|
2148 |
+
if ( !empty( $_POST[ 'report_id' ] ) ) {
|
2149 |
+
check_ajax_referer( 'meta-box-order', 'security' ); // Let's make sure the request is coming from an authorized source
|
2150 |
+
$report_id = $_POST[ 'report_id' ];
|
2151 |
+
}
|
2152 |
+
|
2153 |
+
// When on the WP Dashboard, the action sets the 'id' key of the $_args array
|
2154 |
+
else if ( !empty( $_args[ 'id' ] ) ){
|
2155 |
+
$report_id = $_args[ 'id' ];
|
2156 |
+
}
|
2157 |
+
|
2158 |
+
// Honor the 'hidden' attribute, but not on the WP Dashboard ( empty( $_args[ 'id' ] ) )
|
2159 |
+
// if ( empty( $report_id ) || in_array( 'hidden', self::$reports_info[ $report_id ][ 'classes' ] ) ) {
|
2160 |
+
// return array();
|
2161 |
+
// }
|
2162 |
+
|
2163 |
+
if ( !empty( self::$reports_info[ $report_id ] ) && is_array( self::$reports_info[ $report_id ] ) ) {
|
2164 |
+
// Default values
|
2165 |
+
$_args = array_merge( array(
|
2166 |
+
'title' => '',
|
2167 |
+
'callback' => '',
|
2168 |
+
'callback_args' => array(),
|
2169 |
+
'classes' => array(),
|
2170 |
+
'screens' => array(),
|
2171 |
+
'tooltip' => ''
|
2172 |
+
), self::$reports_info[ $report_id ] );
|
2173 |
+
}
|
2174 |
+
|
2175 |
+
// Default callback args
|
2176 |
+
$_args[ 'callback_args' ] = array_merge( array(
|
2177 |
+
'type' => '',
|
2178 |
+
'columns' => '',
|
2179 |
+
'where' => '',
|
2180 |
+
'having' => '',
|
2181 |
+
'as_column' => '',
|
2182 |
+
'filter_op' => 'equals',
|
2183 |
+
'outer_select_column' => '',
|
2184 |
+
'aggr_function' => 'MAX',
|
2185 |
+
'use_date_filters' => true,
|
2186 |
+
'results_per_page' => wp_slimstat::$settings[ 'rows_to_show' ],
|
2187 |
+
'criteria' => ''
|
2188 |
+
), $_args[ 'callback_args' ] );
|
2189 |
+
|
2190 |
+
return $_args;
|
2191 |
+
}
|
2192 |
+
}
|
|
|
|
|
|
|
|
|
|
admin/wp-slimstat-admin.php
CHANGED
@@ -11,7 +11,7 @@ class wp_slimstat_admin {
|
|
11 |
* Init -- Sets things up.
|
12 |
*/
|
13 |
public static function init() {
|
14 |
-
self::$admin_notice = "We
|
15 |
self::$admin_notice .= '<br/><br/><a id="slimstat-hide-admin-notice" href="#" class="button-secondary">Got it, thanks</a>';
|
16 |
|
17 |
// Load language files
|
@@ -691,7 +691,7 @@ class wp_slimstat_admin {
|
|
691 |
|
692 |
$parsed_permalink = parse_url( get_permalink( $_post_id ) );
|
693 |
$parsed_permalink = $parsed_permalink[ 'path' ] . ( !empty( $parsed_permalink[ 'query' ] ) ? '?' . $parsed_permalink[ 'query' ] : '' );
|
694 |
-
wp_slimstat_db::init( 'resource contains ' . $parsed_permalink . '&&&interval equals ' . wp_slimstat::$settings[ 'posts_column_day_interval' ]
|
695 |
|
696 |
if ( wp_slimstat::$settings[ 'posts_column_pageviews' ] == 'on' ) {
|
697 |
$count = wp_slimstat_db::count_records();
|
@@ -699,7 +699,7 @@ class wp_slimstat_admin {
|
|
699 |
else{
|
700 |
$count = wp_slimstat_db::count_records( 'ip' );
|
701 |
}
|
702 |
-
echo '<a href="'.wp_slimstat_reports::fs_url( 'resource contains ' . $parsed_permalink . '&&&interval equals ' . wp_slimstat::$settings[ 'posts_column_day_interval' ]
|
703 |
}
|
704 |
// end add_column
|
705 |
|
11 |
* Init -- Sets things up.
|
12 |
*/
|
13 |
public static function init() {
|
14 |
+
self::$admin_notice = "We've completely rewritten the portion of code that handles the date ranges in the Filter Bar. In order to simplify things, <strong>we have deprecated</strong> the shortcode filter <code>interval_direction</code>, which is now expressed by the sign in front of the interval value (positive for going forward from a given start date, and negative for going back in time). Please note that this change affect your existing shortcodes, if they use the aforementioned filter. We will update our documentation in the next few days to remove any reference to this filter, and to avoid any confusion. We've also reintroduced the various levels of granularity for our charts: hourly (when a single day is selected), daily (for ranges up to 120 days) and monthly. Last but not least, the comparison chart is now <strong>always</strong> displayed, using new criteria to determine the range to use. You may want to change your settings (Settings > Reports > Default Time Span > Days, and Reports > Comparison Chart) to mimic the old behavior or hide the comparison chart altogether, if you like. Please feel free to contact us if you have any questions or to report any issues.";
|
15 |
self::$admin_notice .= '<br/><br/><a id="slimstat-hide-admin-notice" href="#" class="button-secondary">Got it, thanks</a>';
|
16 |
|
17 |
// Load language files
|
691 |
|
692 |
$parsed_permalink = parse_url( get_permalink( $_post_id ) );
|
693 |
$parsed_permalink = $parsed_permalink[ 'path' ] . ( !empty( $parsed_permalink[ 'query' ] ) ? '?' . $parsed_permalink[ 'query' ] : '' );
|
694 |
+
wp_slimstat_db::init( 'resource contains ' . $parsed_permalink . '&&&interval equals -' . wp_slimstat::$settings[ 'posts_column_day_interval' ] );
|
695 |
|
696 |
if ( wp_slimstat::$settings[ 'posts_column_pageviews' ] == 'on' ) {
|
697 |
$count = wp_slimstat_db::count_records();
|
699 |
else{
|
700 |
$count = wp_slimstat_db::count_records( 'ip' );
|
701 |
}
|
702 |
+
echo '<a href="'.wp_slimstat_reports::fs_url( 'resource contains ' . $parsed_permalink . '&&&interval equals -' . wp_slimstat::$settings[ 'posts_column_day_interval' ] ). '">'.$count.'</a>';
|
703 |
}
|
704 |
// end add_column
|
705 |
|
readme.txt
CHANGED
@@ -1,155 +1,162 @@
|
|
1 |
-
=== Slimstat Analytics ===
|
2 |
-
Contributors: coolmann
|
3 |
-
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=BNJR5EZNY3W38
|
4 |
-
Tags: analytics, statistics, counter, tracking, reports, wassup, geolocation, online users, spider, tracker, pageviews, stats, maxmind, statistics, statpress, power stats, hit
|
5 |
-
Text Domain: wp-slimstat
|
6 |
-
Requires at least: 3.8
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
*
|
19 |
-
*
|
20 |
-
*
|
21 |
-
*
|
22 |
-
*
|
23 |
-
*
|
24 |
-
*
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
is
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
*
|
43 |
-
*
|
44 |
-
*
|
45 |
-
*
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
*
|
50 |
-
*
|
51 |
-
*
|
52 |
-
* At least
|
53 |
-
* At least
|
54 |
-
*
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
* If you
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
* [
|
84 |
-
* [
|
85 |
-
|
86 |
-
|
87 |
-
* [Fix] The
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
* [New]
|
92 |
-
* [
|
93 |
-
* [
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
* [
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
* [
|
106 |
-
|
107 |
-
|
108 |
-
* [
|
109 |
-
* [Fix]
|
110 |
-
|
111 |
-
= 4.7.
|
112 |
-
* [
|
113 |
-
* [
|
114 |
-
* [
|
115 |
-
* [
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
* [
|
120 |
-
* [
|
121 |
-
* [Fix]
|
122 |
-
* [Fix]
|
123 |
-
|
124 |
-
= 4.7.
|
125 |
-
* [
|
126 |
-
|
127 |
-
|
128 |
-
* [Fix]
|
129 |
-
* [Fix]
|
130 |
-
|
131 |
-
|
132 |
-
* [Fix]
|
133 |
-
|
134 |
-
= 4.7.
|
135 |
-
* [
|
136 |
-
* [
|
137 |
-
* [Fix] The
|
138 |
-
* [Fix]
|
139 |
-
|
140 |
-
|
141 |
-
= 4.7.2.
|
142 |
-
* [
|
143 |
-
* [
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
* [
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
* [
|
154 |
-
* [
|
155 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
=== Slimstat Analytics ===
|
2 |
+
Contributors: coolmann
|
3 |
+
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=BNJR5EZNY3W38
|
4 |
+
Tags: analytics, statistics, counter, tracking, reports, wassup, geolocation, online users, spider, tracker, pageviews, stats, maxmind, statistics, statpress, power stats, hit
|
5 |
+
Text Domain: wp-slimstat
|
6 |
+
Requires at least: 3.8
|
7 |
+
Requires PHP: 5.2
|
8 |
+
Tested up to: 4.9
|
9 |
+
Stable tag: 4.7.7
|
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.
|
13 |
+
|
14 |
+
= Feature Spotlight =
|
15 |
+
[youtube https://www.youtube.com/watch?v=zEKP9yC8x6g]
|
16 |
+
|
17 |
+
= Main features =
|
18 |
+
* Get access to real-time access log, measure server latency, track page events, keep an eye on your bounce rate and much more.
|
19 |
+
* Add shortcodes to your website to display reports in widgets or directly in posts and pages.
|
20 |
+
* Exclude users from statistics collection based on various criteria, including; user roles, common robots, IP subnets, admin pages, country, etc.
|
21 |
+
* Export your reports to CSV, generate user heatmaps or get daily emails right in your mailbox (via premium add-ons).
|
22 |
+
* Compatible with W3 Total Cache, WP SuperCache, CloudFlare and most caching plugins.
|
23 |
+
* Support for hashing IP addresses in the database to protect your users privacy.
|
24 |
+
* Accurate IP geolocation, browser and platform detection (courtesy of [MaxMind](http://www.maxmind.com/) and [Browscap](http://browscap.org)).
|
25 |
+
* World Map that works on your mobile device, too (courtesy of [amMap](http://www.ammap.com/)).
|
26 |
+
|
27 |
+
= Premium Add-ons =
|
28 |
+
Visit [our website](http://www.wp-slimstat.com/addons/) for a list of available extensions.
|
29 |
+
|
30 |
+
= Social Media =
|
31 |
+
[Like Us](https://www.facebook.com/slimstatistics/) on Facebook and [follow us](https://twitter.com/wp_stats) on Twitter to get the latest news and updates about our plugin.
|
32 |
+
|
33 |
+
= Contribute =
|
34 |
+
Slimstat Analytics is an open source project, dependent in large parts on community support. You can fork our [Github repository](https://github.com/slimstat/wp-slimstat) and submit code enhancements, bugfixes or provide localization files to let our plugin speak even more languages. [This page](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=BNJR5EZNY3W38)
|
35 |
+
is for those who would like to donate money - be it once, be it regularly, be it a small or a big amount. Everything is set up for an easy donation process.
|
36 |
+
Try it out, you'll be amazed how good it feels! If you're on a tight budget, and coding is not your thing, please consider writing [a review](https://wordpress.org/support/plugin/wp-slimstat/reviews/#new-post) for Slimstat as a token of appreciation for our hard work!
|
37 |
+
|
38 |
+
= Translations =
|
39 |
+
Slimstat is available in multiple languages: English, Belarusian (UStarCash), Chinese (沐熙工作室), Farsi, French (Michael Bastin, Jean-Michel Venet, Yves Pouplard, Henrick Kac), German (TechnoViel), Indonesian ([ChameleonJohn](https://www.chameleonjohn.com/)), Italian ([Slimstat Dev Team](https://www.wp-slimstat.com)), Japanese (h_a_l_f), Portuguese, Russian (Vitaly), Spanish ([WebHostingHub](http://www.webhostinghub.com/)), Swedish (Per Soderman) and Turkish (Seyit Mehmet Çoban). Is your language missing or incomplete? [Contact us](http://support.wp-slimstat.com/) today.
|
40 |
+
|
41 |
+
= Reviews and Feedback =
|
42 |
+
* This is by far the most accurate and in-depth tracking plugin I've encountered for WordPress [MiMango](https://wordpress.org/support/topic/excellent-plugin-and-service-9)
|
43 |
+
* I have been relying on SlimStat to not only track all traffic to my sites accurately but also to present the stats in very useful graphic format [JJD3](https://wordpress.org/support/topic/an-essential-plugin-14)
|
44 |
+
* Thanks you for such an excellent plugin. I am using it to kick Jetpack out of all the wordpress installations that I manage for myself and others - [robertwagnervt](http://wordpress.org/support/topic/plugin-wp-slimstat-excellent-but-some-errors-on-activating)
|
45 |
+
* I like Slimstat very much and so I decided to use it instead of Piwik - [Joannes](http://wordpress.org/support/topic/plugin-wp-slimstat-slimstat-and-privacy)
|
46 |
+
* Read all the [reviews](http://wordpress.org/support/view/plugin-reviews/wp-slimstat) and feel free to post your own!
|
47 |
+
|
48 |
+
= Requirements =
|
49 |
+
* WordPress 3.8+
|
50 |
+
* PHP 5.2+ (or 5.5+ if you use the Browscap data file)
|
51 |
+
* MySQL 5.0.3+
|
52 |
+
* At least 20 MB of free web space
|
53 |
+
* At least 5 MB of free DB space
|
54 |
+
* At least 32 Mb of free PHP memory for the tracker (peak memory usage)
|
55 |
+
* IE9+ or any browser supporting HTML5, to access the reports
|
56 |
+
|
57 |
+
== Installation ==
|
58 |
+
1. In your WordPress admin, go to Plugins > Add New
|
59 |
+
2. Search for WP Slimstat Analytics
|
60 |
+
3. Click on **Install Now** under WP Slimstat Analytics and then activate the plugin
|
61 |
+
4. Make sure your template calls `wp_footer()` or the equivalent hook somewhere (possibly just before the `</body>` tag)
|
62 |
+
5. Go to Slimstat > Settings > Maintenance tab > MaxMind IP to Country section and click on "Install GeoLite DB" to detect your visitors' countries based on their IP addresses
|
63 |
+
6. If your `wp-admin` folder is not publicly accessible, make sure to check the [FAQs](http://wordpress.org/extend/plugins/wp-slimstat/faq/) to see if there's anything else you need to do
|
64 |
+
|
65 |
+
== Please note ==
|
66 |
+
* If you decide to uninstall Slimstat Analytics, all the stats will be **PERMANENTLY** deleted from your database. Make sure to setup a database backup (wp_slim_*) to avoid losing your data.
|
67 |
+
* If you are upgrading from a version prior to 4.0, please install version 4.0 first to upgrade the database structure and download the new Geolocation data.
|
68 |
+
|
69 |
+
== Frequently Asked Questions ==
|
70 |
+
Our knowledge base is available on our [support center](http://docs.wp-slimstat.com/) website.
|
71 |
+
|
72 |
+
== Screenshots ==
|
73 |
+
1. **Overview** - Your website traffic at a glance
|
74 |
+
2. **Activity Log** - A real-time view of your visitors' whereabouts
|
75 |
+
3. **Settings** - Plenty of options to customize the plugin's behavior
|
76 |
+
4. **Interactive World Map** - See where your visitors are coming from
|
77 |
+
5. **Responsive layout** - Keep an eye on your reports on the go
|
78 |
+
|
79 |
+
== Changelog ==
|
80 |
+
= 4.7.7 =
|
81 |
+
* [New] We've completely rewritten the portion of code that handles the date ranges in the Filter Bar. In order to simplify things, **we have deprecated** the `interval_direction` filter, which is now expressed by the sign in front of the interval value (positive for going forward from a given start date, and negative for going back in time). Please note that this change affect your existing shortcodes, if they use the aforementioned filter. We will update our documentation in the next few days to remove any reference to this filter, and to avoid any confusion. Please feel free to contact us if you have any questions or to report any issues.
|
82 |
+
* [New] The comparison chart is now always displayed, using new criteria to determine the range to use. You may want to update your settings (Settings > Reports > Default Time Span > Days, and Reports > Comparison Chart) to mimic the old behavior or hide the comparison chart altogether, if you like.
|
83 |
+
* [Update] We've reintroduced the various levels of granularity for our charts: hourly (when a single day is selected), daily (for ranges up to 120 days) and monthly. Also, the comparison chart is now always available, regardless of the selected time range. Thank you, [WebsiteOpzetten](https://wordpress.org/support/topic/char-is-not-displayed-when-the-selected-time-range-is-comprised-of-a-single-day/).
|
84 |
+
* [Update] Tooltips across the interface have a more uniform behavior.
|
85 |
+
|
86 |
+
= 4.7.6.1 =
|
87 |
+
* [Fix] The new Javascript library was interfering with the dropdown menus on the WordPress Dashboard. Thanks to all of those who helped us troubleshoot the issue.
|
88 |
+
|
89 |
+
= 4.7.6 =
|
90 |
+
* [Note] As we mentioned earlier, we've been working on streamlining and cleaning up our source code. It's incredible how layers of code can deposit on top of each other, until they form a thick layer that prevents developers from seeing clearly what's happening. It was time to apply some virtual citric acid to descale our code. If you're using any kind of server caching functionality, please make sure to clear your cache before opening a support request. Also, do not hesitate to reach out to us if you notice any strange or unusual behaviors.
|
91 |
+
* [New] You can now download the geolocation map as a PDF file or PNG image. Thank you, Steve, for suggesting this feature!
|
92 |
+
* [New] You can now exclude pageviews by content type, like 404, taxonomy, search, etc. Thank you, [victor50g](https://wordpress.org/support/topic/suggestion-enable-filtering-on-content-404/).
|
93 |
+
* [Update] Deprecated the 'direction' filter, which was a leftover from over 5 years ago, when we used our old interface.
|
94 |
+
* [Fix] The cron job to archive old records was not firing as expected under certain circumstances.
|
95 |
+
* [Fix] Charts did not render correctly, if no data was available for that specific view.
|
96 |
+
|
97 |
+
= 4.7.5.3 =
|
98 |
+
* [New] For those who can't manage to automatically update their local copy of our premium add-ons, we've added a link to manually download the zip file. You'll find it under the Plugins screen, once you've entered and saved the corresponding license key under Slimstat > Add-ons.
|
99 |
+
* [Update] The [Update Checker](https://github.com/YahnisElsts/plugin-update-checker) library has been updated to version 4.4.
|
100 |
+
* [Fix] The world map was not being displayed correctly if no data points were available for the selected time range (thank you, Michel).
|
101 |
+
|
102 |
+
= 4.7.5.2 =
|
103 |
+
* [Update] You can now customize the amount of dots displayed on the World Map, under Slimstat > Settings > Reports > Access Log and World Map. Thank you, [service4](https://wordpress.org/support/topic/new-geolocation-map-with-cities/).
|
104 |
+
* [Fix] A dependency error was being highlighted for one of our premium add-ons under certain circumstances. Thank you, Peter.
|
105 |
+
* [Fix] The option to not set the session cookie was not working as expected. Thank you, [Bjarne](https://wordpress.org/support/topic/disable-cookies-2/#post-9887099).
|
106 |
+
|
107 |
+
= 4.7.5.1 =
|
108 |
+
* [Update] Implemented a workaround to try and fix the "Forbidden" error that a few users are experiencing when trying to download the MaxMind Geolite2 data file.
|
109 |
+
* [Fix] Updated the link to manually download the MaxMind data file from their servers, and added a new page to our knowledge base to explain how to manually install it.
|
110 |
+
|
111 |
+
= 4.7.5 =
|
112 |
+
* [New] Now that Slimstat is capable of geolocating visitors at the city level, wouldn't it make sense to display those visitors on the map? Well, of course! Go check out this new feature by accessing the Geolocation tab in Slimstat.
|
113 |
+
* [New] Updated the tracking script to handle events triggered by external libraries, like the [Vimeo API](https://github.com/vimeo/player.js/#events). Thank you, Max.
|
114 |
+
* [New] Added new operator "included_in_set", which allows you to list multiple values to match against, when composing a shortcode.
|
115 |
+
* [New] Added new option to avoid that Slimstat assigns a COOKIE to your visitors. Thank you, [dragon013](https://wordpress.org/support/topic/disable-cookies-2/).
|
116 |
+
* [Fix] A bug was preventing the feature to "restrict users" to only see their reports from working as expected.
|
117 |
+
|
118 |
+
= 4.7.4.1 =
|
119 |
+
* [Update] The Browscap data file is now loaded only when needed, thus removing its inherent overhead when unnecessary.
|
120 |
+
* [Update] The Browscap data file has been updated to the latest version available on their repository (ver 6026).
|
121 |
+
* [Fix] Addressed a remote XSS Vulnerability responsibly disclosed by one of our customers. Thank you, [riscybusiness](https://wordpress.org/support/topic/security-vulnerability-affecting-slimstat/).
|
122 |
+
* [Fix] Reintroduced the WHOIS pin, which has been removed by mistake because of a regression bug. Thank you, [brachialis](https://wordpress.org/support/topic/whois-location-icon-disappear/).
|
123 |
+
|
124 |
+
= 4.7.4 =
|
125 |
+
* [Update] New fields added to the Email Report and Export to Excel add-ons, by extending how certain reports are defined in core.
|
126 |
+
* [Fix] The [false positive](https://www.virustotal.com/#/file/43f69d9c4028f857b5b5544ea4559c03b4d58e02d75617482db517c626164363/detection) alert related to a virus in our code was fixed by updating [AmChart](https://www.amcharts.com/) to the latest version available (thank you, Sasa).
|
127 |
+
* [Fix] Removed a PHP warning of undefined index (thank you, [slewis1000 and Sasa](https://wordpress.org/support/topic/php-notice-undefined-index-country/))
|
128 |
+
* [Fix] The MozScape report was causing connectivity issues for some users, and it is now set as "hidden" by default.
|
129 |
+
* [Fix] Regression bug related to our Export to Excel add-on.
|
130 |
+
|
131 |
+
= 4.7.3.1 =
|
132 |
+
* [Fix] Apparently more people than we initially thought have issues with the MaxMind data file not being saved as expected. We are introducing a temporary fix while we try to investigate this issue further.
|
133 |
+
|
134 |
+
= 4.7.3 =
|
135 |
+
* [Fix] A [few users](https://wordpress.org/support/topic/cannot-install-maxmind-geolite-db/) pointed out a weird behavior when installing the MaxMind Geolocation data file, where an empty folder would be created instead of the actual file. If you still experience issues related to this problem, please make sure to delete the empty folder "maxmind.mmdb" under `wp-content/uploads/wp-slimstat/`.
|
136 |
+
* [Fix] Apparently Microsoft Security Essentials [was not pleased with our code](https://wordpress.org/support/topic/trojandownloader097m-donoff-detected-in-archive/), and was returning a false positive alert that a virus was included with the source code (thank you, Sasa).
|
137 |
+
* [Fix] The "content_id" filter could not be used in a shortcode to reference other pages (i.e. `[slimstat f='count-all' w='id']content_id equals 2012[/slimstat]`). Thank you, Felipe.
|
138 |
+
* [Fix] Country flags were not being displayed properly under certain circumstances (thank you, [Catmaniax](https://wordpress.org/support/topic/minor-issue-missing-png-file/)).
|
139 |
+
* [Fix] Bug preventing the new Heatmap Add-on from working as expected.
|
140 |
+
|
141 |
+
= 4.7.2.2 =
|
142 |
+
* [New] Added support for SCRIPT_DEBUG: by defining this constant in your `wp-config.php` will make Slimstat load the unminified version of the javascript tracker (thank you, Sasa)
|
143 |
+
* [Update] Added new parameter to make the `admin-ajax.php` URL relative, to solve issues like [this one](https://wordpress.org/support/topic/xmlhttprequest-cannot-load-wp-adminadmin-ajax-php-3/).
|
144 |
+
* [Fix] The Network Settings premium add-on was not working because of a bug in the main plugin. Thank you, Steve, for pointing us into the right direction.
|
145 |
+
* [Fix] Updated the schema (columns) for the archive table.
|
146 |
+
|
147 |
+
|
148 |
+
= 4.7.2.1 =
|
149 |
+
* [Fix] The new table columns "location" and "city" were not being created on a fresh install (thank you, [nielsgoossens](https://wordpress.org/support/topic/no-data-anymore-2/#post-9491034))
|
150 |
+
* [Fix] Async mode was not working as expected (thank you, [keithgbcc](https://wordpress.org/support/topic/doesnt-work-1694/#post-9487448))
|
151 |
+
|
152 |
+
= 4.7.2 =
|
153 |
+
* [New] As those who have been using Slimstat for a while know, we never stop doing our good share of research and development to improve our plugin. One feature on our wishlist was to make the geolocation functionality more accurate. Specifically, users have been asking us to track not just the Country of origin, but possibly the state and city. In order to geolocate visitors, our code has been leveraging a third-party data file provided by [MaxMind.com](https://www.maxmind.com/en/home). A while ago, they launched a new data format, which improves performance and offers a way to quickly determine the city of origin. However, the new library required a higher version of PHP, and up until now we had been hesitant to adopt it, to allow more people to use our plugin, over the chance of offering this feature. Now, after spending some time combing through their code, we found a way to get the best of both worlds: by customizing their PHP library, we were able to make it work with PHP 5.3! Which means that now Slimstat is able to tell you your visitors' city of origin (and State, when applicable) right out of the box. This information is available in the Access Log report and in a new 'Top Cities' report under the Audience tab. Please note: the MaxMind data file to enable this feature is approximately 60 Mb, and for this reason <strong>this new functionality is not enabled by default</strong>. You must go to Slimstat > Settings > Tracker and turn on the corresponding option. Then go to Slimstat > Settings > Maintenance and uninstall/install the GeoLite file to download the one that contains the city data. Please feel free to contact us if you have any questions.
|
154 |
+
* [Update] Removed backward compatibility code for those updating from a version prior to 4.2. Hopefully most of our users are using a newer version that that. If you're not, please contact our support service for instructions on how to upgrade.
|
155 |
+
* [Update] The format used to save your settings in the database has been changed. You MUST update your premium add-ons as soon as possible, and get the version compatible with this new format, or you might notice unexpected behaviors. Please contact us if you experience difficulties updating your add-ons.
|
156 |
+
* [Update] Cleaned up some old CSS code affecting the reports.
|
157 |
+
|
158 |
+
= 4.7.1 =
|
159 |
+
* [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.
|
160 |
+
* [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.
|
161 |
+
* [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).
|
162 |
+
|
wp-slimstat.php
CHANGED
@@ -1,1966 +1,1967 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
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
|
10 |
-
Domain Path: /languages
|
11 |
-
*/
|
12 |
-
|
13 |
-
if ( !empty( wp_slimstat::$settings ) ) {
|
14 |
-
return true;
|
15 |
-
}
|
16 |
-
|
17 |
-
class wp_slimstat {
|
18 |
-
public static $version = '4.7.
|
19 |
-
public static $settings = array();
|
20 |
-
|
21 |
-
public static $wpdb = '';
|
22 |
-
public static $upload_dir = '';
|
23 |
-
public static $maxmind_path = '';
|
24 |
-
|
25 |
-
public static $update_checker = array();
|
26 |
-
public static $raw_post_array = array();
|
27 |
-
|
28 |
-
protected static $data_js = array( 'id' => 0 );
|
29 |
-
protected static $stat = array();
|
30 |
-
protected static $settings_signature = '';
|
31 |
-
protected static $browser = array();
|
32 |
-
protected static $heuristic_key = 0;
|
33 |
-
protected static $date_i18n_filters = array();
|
34 |
-
|
35 |
-
/**
|
36 |
-
* Initializes variables and actions
|
37 |
-
*/
|
38 |
-
public static function init() {
|
39 |
-
|
40 |
-
// Load all the settings
|
41 |
-
if ( is_network_admin() && ( empty($_GET[ 'page' ] ) || strpos( $_GET[ 'page' ], 'slimview' ) === false ) ) {
|
42 |
-
self::$settings = get_site_option( 'slimstat_options', array() );
|
43 |
-
}
|
44 |
-
else {
|
45 |
-
self::$settings = get_option( 'slimstat_options', array() );
|
46 |
-
}
|
47 |
-
|
48 |
-
self::$settings = array_merge( self::init_options(), self::$settings );
|
49 |
-
|
50 |
-
// Allow third party tools to edit the options
|
51 |
-
self::$settings = apply_filters( 'slimstat_init_options', self::$settings );
|
52 |
-
|
53 |
-
// Determine the options' signature: if it hasn't changed, there's no need to update/save them in the database
|
54 |
-
self::$settings_signature = md5( serialize( self::$settings ) );
|
55 |
-
|
56 |
-
// Allow third-party tools to use a custom database for Slimstat
|
57 |
-
self::$wpdb = apply_filters( 'slimstat_custom_wpdb', $GLOBALS[ 'wpdb' ] );
|
58 |
-
|
59 |
-
// Hook a DB clean-up routine to the daily cronjob
|
60 |
-
add_action( 'wp_slimstat_purge', array( __CLASS__, 'wp_slimstat_purge' ) );
|
61 |
-
|
62 |
-
// Allow external domains on CORS requests
|
63 |
-
add_filter( 'allowed_http_origins', array(__CLASS__, 'open_cors_admin_ajax' ) );
|
64 |
-
|
65 |
-
// Define the folder where to store the geolocation database (shared among sites in a network, by default)
|
66 |
-
self::$upload_dir = wp_upload_dir();
|
67 |
-
self::$upload_dir = self::$upload_dir[ 'basedir' ];
|
68 |
-
if ( is_multisite() && ! ( is_main_network() && is_main_site() && defined( 'MULTISITE' ) ) ) {
|
69 |
-
self::$upload_dir = str_replace( '/sites/' . get_current_blog_id(), '', self::$upload_dir );
|
70 |
-
}
|
71 |
-
self::$upload_dir .= '/wp-slimstat';
|
72 |
-
self::$upload_dir = apply_filters( 'slimstat_maxmind_path', self::$upload_dir );
|
73 |
-
|
74 |
-
self::$maxmind_path = self::$upload_dir . '/maxmind.mmdb';
|
75 |
-
|
76 |
-
// Enable the tracker (both server- and client-side)
|
77 |
-
if ( !is_admin() || self::$settings[ 'track_admin_pages' ] == 'on' ) {
|
78 |
-
|
79 |
-
// Allow add-ons to turn off the tracker based on other conditions
|
80 |
-
$is_tracking_filter = apply_filters( 'slimstat_filter_pre_tracking', strpos( self::get_request_uri(), 'wp-admin/admin-ajax.php' ) === false );
|
81 |
-
$is_tracking_filter_js = apply_filters( 'slimstat_filter_pre_tracking_js', true );
|
82 |
-
|
83 |
-
// Is server-side tracking active?
|
84 |
-
if ( self::$settings[ 'javascript_mode' ] != 'on' && self::$settings[ 'is_tracking' ] == 'on' && $is_tracking_filter ) {
|
85 |
-
add_action( is_admin() ? 'admin_init' : 'wp', array( __CLASS__, 'slimtrack' ), 5 );
|
86 |
-
|
87 |
-
if ( self::$settings[ 'track_users' ] == 'on' ) {
|
88 |
-
add_action( 'login_init', array( __CLASS__, 'slimtrack' ), 10 );
|
89 |
-
}
|
90 |
-
}
|
91 |
-
|
92 |
-
// Slimstat tracks screen resolutions, outbound links and other client-side information using a client-side tracker
|
93 |
-
add_action( is_admin() ? 'admin_enqueue_scripts' : 'wp_enqueue_scripts' , array( __CLASS__, 'wp_slimstat_enqueue_tracking_script' ), 15 );
|
94 |
-
if ( self::$settings[ 'track_users' ] == 'on' ) {
|
95 |
-
add_action( 'login_enqueue_scripts', array( __CLASS__, 'wp_slimstat_enqueue_tracking_script' ), 10 );
|
96 |
-
}
|
97 |
-
}
|
98 |
-
|
99 |
-
// Shortcodes
|
100 |
-
add_shortcode('slimstat', array(__CLASS__, 'slimstat_shortcode'), 15);
|
101 |
-
|
102 |
-
// Load the admin library
|
103 |
-
if ( is_user_logged_in() ) {
|
104 |
-
include_once ( plugin_dir_path( __FILE__ ) . 'admin/wp-slimstat-admin.php' );
|
105 |
-
add_action( 'init', array( 'wp_slimstat_admin', 'init' ), 60 );
|
106 |
-
}
|
107 |
-
|
108 |
-
// Include our browser detector library
|
109 |
-
include_once( plugin_dir_path( __FILE__ ) . 'browscap/browser.php' );
|
110 |
-
add_action( 'init', array( 'slim_browser', 'init' ) );
|
111 |
-
|
112 |
-
// If add-ons are installed, check for updates
|
113 |
-
add_action( 'wp_loaded', array( __CLASS__, 'update_checker' ) );
|
114 |
-
|
115 |
-
// Update the options before shutting down
|
116 |
-
add_action( 'shutdown', array( __CLASS__, 'slimstat_save_options' ), 100 );
|
117 |
-
|
118 |
-
// REST API Support
|
119 |
-
add_action( 'rest_api_init', array( __CLASS__, 'register_rest_route' ) );
|
120 |
-
}
|
121 |
-
// end init
|
122 |
-
|
123 |
-
/**
|
124 |
-
* Ajax Tracking
|
125 |
-
*/
|
126 |
-
public static function slimtrack_ajax() {
|
127 |
-
// If the website is using a caching plugin, the tracking code might still be there, even if the user turned off tracking
|
128 |
-
if ( self::$settings[ 'is_tracking' ] != 'on' ) {
|
129 |
-
self::$stat[ 'id' ] = -204;
|
130 |
-
self::_set_error_array( __( 'Tracker is turned off, but client-side tracking code is still running.', 'wp-slimstat' ), true );
|
131 |
-
self::slimstat_save_options();
|
132 |
-
exit( self::_get_id_with_checksum( self::$stat[ 'id' ] ) );
|
133 |
-
}
|
134 |
-
|
135 |
-
// This function also initializes self::$data_js and removes the checksum from self::$data_js['id']
|
136 |
-
self::_check_data_integrity( self::$raw_post_array );
|
137 |
-
|
138 |
-
// Is this a request to record a new pageview?
|
139 |
-
if ( self::$data_js[ 'op' ] == 'add' || self::$data_js[ 'op' ] == 'update' ) {
|
140 |
-
|
141 |
-
// Track client-side information (screen resolution, plugins, etc)
|
142 |
-
if ( !empty( self::$data_js[ 'bw' ] ) ) {
|
143 |
-
self::$stat[ 'resolution' ] = strip_tags( trim( self::$data_js[ 'bw' ] . 'x' . self::$data_js[ 'bh' ] ) );
|
144 |
-
}
|
145 |
-
if ( !empty( self::$data_js[ 'sw' ] ) ) {
|
146 |
-
self::$stat[ 'screen_width' ] = intval( self::$data_js[ 'sw' ] );
|
147 |
-
}
|
148 |
-
if ( !empty( self::$data_js[ 'sh' ] ) ) {
|
149 |
-
self::$stat[ 'screen_height' ] = intval( self::$data_js[ 'sh' ] );
|
150 |
-
}
|
151 |
-
if ( !empty( self::$data_js[ 'pl' ] ) ) {
|
152 |
-
self::$stat[ 'plugins' ] = strip_tags( trim( self::$data_js[ 'pl' ] ) );
|
153 |
-
}
|
154 |
-
if ( !empty( self::$data_js[ 'sl' ] ) && self::$data_js[ 'sl' ] > 0 && self::$data_js[ 'sl' ] < 60000 ) {
|
155 |
-
self::$stat[ 'server_latency' ] = intval( self::$data_js[ 'sl' ] );
|
156 |
-
}
|
157 |
-
if ( !empty( self::$data_js[ 'pp' ] ) && self::$data_js[ 'pp' ] > 0 && self::$data_js[ 'pp' ] < 60000 ) {
|
158 |
-
self::$stat[ 'page_performance' ] = intval( self::$data_js[ 'pp' ] );
|
159 |
-
}
|
160 |
-
}
|
161 |
-
|
162 |
-
if ( self::$data_js[ 'op' ] == 'add' ) {
|
163 |
-
self::slimtrack();
|
164 |
-
}
|
165 |
-
else if ( self::$data_js[ 'op' ] == 'update' ) {
|
166 |
-
// Update an existing pageview with client-based information (resolution, plugins installed, etc)
|
167 |
-
self::_set_visit_id( true );
|
168 |
-
|
169 |
-
// ID of the pageview to update
|
170 |
-
self::$stat[ 'id' ] = abs( intval( self::$data_js[ 'id' ] ) );
|
171 |
-
|
172 |
-
// Visitor is still on this page, record the timestamp in the corresponding field
|
173 |
-
self::toggle_date_i18n_filters( false );
|
174 |
-
self::$stat['dt_out'] = date_i18n( 'U' );
|
175 |
-
self::toggle_date_i18n_filters( true );
|
176 |
-
|
177 |
-
// Are we tracking an outbound click?
|
178 |
-
if ( !empty( self::$data_js[ 'res' ] ) ) {
|
179 |
-
$outbound_resource = strip_tags( trim( base64_decode( self::$data_js[ 'res' ] ) ) );
|
180 |
-
$outbound_host = parse_url( $outbound_resource, PHP_URL_HOST );
|
181 |
-
$site_host = parse_url( get_site_url(), PHP_URL_HOST );
|
182 |
-
if ( $outbound_host != $site_host ) {
|
183 |
-
$existing_outbound_resource = self::$wpdb->get_var( self::$wpdb->prepare( "
|
184 |
-
SELECT outbound_resource
|
185 |
-
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
186 |
-
WHERE id = %d", self::$stat[ 'id' ]
|
187 |
-
) );
|
188 |
-
|
189 |
-
self::$stat[ 'outbound_resource' ] = $outbound_resource;
|
190 |
-
if ( !empty( $existing_outbound_resource ) ) {
|
191 |
-
self::$stat[ 'outbound_resource' ] = $existing_outbound_resource . ';;;' .$outbound_resource;
|
192 |
-
}
|
193 |
-
}
|
194 |
-
}
|
195 |
-
|
196 |
-
self::update_row( self::$stat, $GLOBALS[ 'wpdb' ]->prefix . 'slim_stats' );
|
197 |
-
}
|
198 |
-
|
199 |
-
// Are we tracking events, coordinates and other details?
|
200 |
-
if ( self::$data_js[ 'op' ] == 'event' || !empty( self::$data_js[ 'pos' ] ) ) {
|
201 |
-
self::$stat[ 'id' ] = abs( intval( self::$data_js[ 'id' ] ) );
|
202 |
-
|
203 |
-
self::toggle_date_i18n_filters( false );
|
204 |
-
$event_info = array(
|
205 |
-
'position' => strip_tags( trim( self::$data_js[ 'pos' ] ) ),
|
206 |
-
'id' => self::$stat[ 'id' ],
|
207 |
-
'dt' => date_i18n( 'U' )
|
208 |
-
);
|
209 |
-
self::toggle_date_i18n_filters( true );
|
210 |
-
|
211 |
-
if ( !empty( self::$data_js[ 'ty' ] ) ) {
|
212 |
-
$event_info[ 'type' ] = abs( intval( self::$data_js[ 'ty' ] ) );
|
213 |
-
}
|
214 |
-
if ( !empty( self::$data_js[ 'des' ] ) ) {
|
215 |
-
$event_info[ 'event_description' ] = strip_tags( trim( base64_decode( self::$data_js[ 'des' ] ) ) );
|
216 |
-
}
|
217 |
-
if ( !empty( self::$data_js[ 'no' ] ) ) {
|
218 |
-
$event_info[ 'notes' ] = strip_tags( trim( base64_decode( self::$data_js[ 'no' ] ) ) );
|
219 |
-
}
|
220 |
-
|
221 |
-
self::insert_row( $event_info, $GLOBALS[ 'wpdb' ]->prefix . 'slim_events' );
|
222 |
-
}
|
223 |
-
|
224 |
-
// Was this pageview tracked?
|
225 |
-
if ( self::$stat[ 'id' ] <= 0 ) {
|
226 |
-
$abs_error_code = abs( self::$stat[ 'id' ] );
|
227 |
-
do_action( 'slimstat_track_exit_' . $abs_error_code, self::$stat );
|
228 |
-
self::slimstat_save_options();
|
229 |
-
exit( self::_get_id_with_checksum( self::$stat[ 'id' ] ) );
|
230 |
-
}
|
231 |
-
|
232 |
-
// Send the ID back to Javascript to track future interactions
|
233 |
-
do_action( 'slimstat_track_success' );
|
234 |
-
|
235 |
-
// If we tracked an internal download, we return the original ID, not the new one
|
236 |
-
exit( self::_get_id_with_checksum( self::$stat[ 'id' ] ) );
|
237 |
-
}
|
238 |
-
|
239 |
-
/**
|
240 |
-
* Core tracking functionality
|
241 |
-
*/
|
242 |
-
public static function slimtrack( $_argument = '' ) {
|
243 |
-
// If the website is using a caching plugin, the tracking code might still be there, even if the user turned off tracking
|
244 |
-
if ( self::$settings[ 'is_tracking' ] != 'on' ) {
|
245 |
-
self::$stat[ 'id' ] = -204;
|
246 |
-
self::_set_error_array( __( 'Tracker is turned off, but client-side tracking code is still running.', 'wp-slimstat' ), true );
|
247 |
-
return $_argument;
|
248 |
-
}
|
249 |
-
|
250 |
-
self::toggle_date_i18n_filters( false );
|
251 |
-
self::$stat[ 'dt' ] = date_i18n( 'U' );
|
252 |
-
self::$stat[ 'notes' ] = array();
|
253 |
-
self::toggle_date_i18n_filters( true );
|
254 |
-
|
255 |
-
// Allow third-party tools to initialize the stat array
|
256 |
-
self::$stat = apply_filters( 'slimstat_filter_pageview_stat_init', self::$stat );
|
257 |
-
|
258 |
-
// Third-party tools can decide that this pageview should not be tracked, by setting its datestamp to zero
|
259 |
-
if ( empty( self::$stat ) || empty( self::$stat[ 'dt' ] ) ) {
|
260 |
-
self::$stat[ 'id' ] = -300;
|
261 |
-
self::_set_error_array( __( 'Pageview filtered by third-party code', 'wp-slimstat' ), true );
|
262 |
-
return $_argument;
|
263 |
-
}
|
264 |
-
|
265 |
-
// User's IP address
|
266 |
-
list ( self::$stat[ 'ip' ], self::$stat[ 'other_ip' ] ) = self::_get_remote_ip();
|
267 |
-
|
268 |
-
if ( empty( self::$stat[ 'ip' ] ) || self::$stat[ 'ip' ] == '0.0.0.0' ) {
|
269 |
-
self::$stat[ 'id' ] = -202;
|
270 |
-
self::_set_error_array( __( 'Empty or not supported IP address format (IPv6)', 'wp-slimstat' ), false );
|
271 |
-
return $_argument;
|
272 |
-
}
|
273 |
-
|
274 |
-
// Referrer URL
|
275 |
-
if ( !empty( self::$data_js[ 'ref' ] ) ) {
|
276 |
-
self::$stat[ 'referer' ] = base64_decode( self::$data_js[ 'ref' ] );
|
277 |
-
}
|
278 |
-
else if ( !empty( $_SERVER[ 'HTTP_REFERER' ] ) ) {
|
279 |
-
self::$stat[ 'referer' ] = $_SERVER[ 'HTTP_REFERER' ];
|
280 |
-
}
|
281 |
-
|
282 |
-
if ( !empty( self::$stat[ 'referer' ] ) ) {
|
283 |
-
|
284 |
-
// Is this a 'seriously malformed' URL?
|
285 |
-
$referer = parse_url( self::$stat[ 'referer' ] );
|
286 |
-
if ( !$referer ) {
|
287 |
-
self::_set_error_array( sprintf( __( 'Malformed referrer URL: %s (IP: %s)', 'wp-slimstat' ), self::$stat[ 'referer' ], self::$stat[ 'ip' ] ), false, 201 );
|
288 |
-
self::$stat[ 'notes' ][] = sprintf( __( 'Malformed referrer URL: %s', 'wp-slimstat' ), self::$stat[ 'referer' ] );
|
289 |
-
unset( self::$stat[ 'referer' ] );
|
290 |
-
}
|
291 |
-
|
292 |
-
if ( !empty( $referer[ 'scheme' ] ) && !in_array( strtolower( $referer[ 'scheme' ] ), array( 'http', 'https', 'android-app' ) ) ) {
|
293 |
-
self::_set_error_array( sprintf( __( 'Attempted XSS Injection: %s (IP: %s)', 'wp-slimstat' ), self::$stat[ 'referer' ], self::$stat[ 'ip' ] ), false, 203 );
|
294 |
-
self::$stat[ 'notes' ][] = sprintf( __( 'Attempted XSS Injection: %s', 'wp-slimstat' ), self::$stat[ 'referer' ] );
|
295 |
-
unset( self::$stat[ 'referer' ] );
|
296 |
-
}
|
297 |
-
|
298 |
-
if ( !empty( self::$stat[ 'referer' ] ) ) {
|
299 |
-
$parsed_site_url_host = parse_url( get_site_url(), PHP_URL_HOST );
|
300 |
-
if ( !empty( $referer[ 'host' ] ) && $referer[ 'host' ] == $parsed_site_url_host && self::$settings[ 'track_same_domain_referers' ] != 'on' ) {
|
301 |
-
unset( self::$stat[ 'referer' ] );
|
302 |
-
}
|
303 |
-
else {
|
304 |
-
// Fix Google Images referring domain
|
305 |
-
if ( strpos( self::$stat[ 'referer' ], 'www.google' ) !== false ) {
|
306 |
-
if ( strpos( self::$stat[ 'referer' ], '/imgres?' ) !== false ) {
|
307 |
-
self::$stat[ 'referer' ] = str_replace( 'www.google', 'images.google', self::$stat[ 'referer' ] );
|
308 |
-
}
|
309 |
-
if ( strpos( self::$stat[ 'referer' ], '/url?' ) !== false ) {
|
310 |
-
self::$stat[ 'referer' ] = str_replace( '/url?', '/search?', self::$stat[ 'referer' ] );
|
311 |
-
}
|
312 |
-
}
|
313 |
-
|
314 |
-
// Is this referer blacklisted?
|
315 |
-
if ( !empty( self::$settings[ 'ignore_referers' ] ) ) {
|
316 |
-
$return_error_code = array(
|
317 |
-
-301,
|
318 |
-
sprintf( __( 'Referrer %s is blacklisted', 'wp-slimstat' ), self::$stat[ 'referer' ] ),
|
319 |
-
true
|
320 |
-
);
|
321 |
-
if ( self::_is_blacklisted( self::$stat[ 'referer' ], self::$settings[ 'ignore_referers' ], $return_error_code ) ) {
|
322 |
-
return $_argument;
|
323 |
-
}
|
324 |
-
}
|
325 |
-
}
|
326 |
-
}
|
327 |
-
}
|
328 |
-
|
329 |
-
$content_info = self::_get_content_info();
|
330 |
-
|
331 |
-
// Is this content type blacklisted?
|
332 |
-
if ( !empty( self::$settings[ 'ignore_content_types' ] ) ) {
|
333 |
-
$return_error_code = array(
|
334 |
-
-313,
|
335 |
-
sprintf( __( 'Content Type %s is blacklisted', 'wp-slimstat' ), $content_info[ 'content_type' ] ),
|
336 |
-
true
|
337 |
-
);
|
338 |
-
if ( self::_is_blacklisted( $content_info[ 'content_type' ], self::$settings[ 'ignore_content_types' ], $return_error_code ) ) {
|
339 |
-
return $_argument;
|
340 |
-
}
|
341 |
-
}
|
342 |
-
|
343 |
-
// Did we receive data from an Ajax request?
|
344 |
-
if ( !empty( self::$data_js[ 'id' ] ) ) {
|
345 |
-
|
346 |
-
// Are we tracking a new pageview? (pos is empty = no event was triggered)
|
347 |
-
if ( empty( self::$data_js[ 'pos' ] ) ) {
|
348 |
-
$content_info = unserialize( base64_decode( self::$data_js[ 'id' ] ) );
|
349 |
-
if ( $content_info === false || empty( $content_info[ 'content_type' ] ) ) {
|
350 |
-
$content_info = array();
|
351 |
-
}
|
352 |
-
}
|
353 |
-
|
354 |
-
// If pos is not empty and slimtrack was called, it means we are tracking a new internal download
|
355 |
-
else if ( !empty( self::$data_js[ 'res' ] ) ) {
|
356 |
-
$download_url = base64_decode( self::$data_js[ 'res' ] );
|
357 |
-
if ( is_string( $download_url ) ) {
|
358 |
-
if ( !empty( self::$data_js[ 'ty' ] ) && self::$data_js[ 'ty' ] == 1 ) {
|
359 |
-
unset( self::$stat[ 'id' ] );
|
360 |
-
$content_info = array( 'content_type' => 'download' );
|
361 |
-
}
|
362 |
-
}
|
363 |
-
}
|
364 |
-
}
|
365 |
-
|
366 |
-
self::$stat = self::$stat + $content_info;
|
367 |
-
|
368 |
-
// We want to record both hits and searches (performed through the site search form)
|
369 |
-
if ( is_array( self::$data_js ) && isset( self::$data_js[ 'res' ] ) ) {
|
370 |
-
$decoded_permalink = base64_decode( self::$data_js[ 'res' ] );
|
371 |
-
$parsed_permalink = parse_url( $decoded_permalink );
|
372 |
-
if ( !empty( $referer ) ) {
|
373 |
-
self::$stat[ 'searchterms' ] = self::_get_search_terms( $referer );
|
374 |
-
}
|
375 |
-
|
376 |
-
// Was this an internal search?
|
377 |
-
if ( empty( self::$stat[ 'searchterms' ] ) ) {
|
378 |
-
self::$stat[ 'searchterms' ] = self::_get_search_terms( $parsed_permalink );
|
379 |
-
}
|
380 |
-
|
381 |
-
if ( self::$stat[ 'content_type' ] == 'external' ) {
|
382 |
-
self::$stat['resource'] = $decoded_permalink;
|
383 |
-
}
|
384 |
-
else {
|
385 |
-
self::$stat['resource'] = !is_array( $parsed_permalink ) ? __( 'Malformed URL', 'wp-slimstat' ) : urldecode( $parsed_permalink[ 'path' ] ) . ( !empty( $parsed_permalink[ 'query' ] ) ? '?' . urldecode( $parsed_permalink[ 'query' ] ) : '' );
|
386 |
-
}
|
387 |
-
}
|
388 |
-
elseif ( empty( $_REQUEST[ 's' ] ) ) {
|
389 |
-
if ( !empty( $referer ) ) {
|
390 |
-
self::$stat[ 'searchterms' ] = self::_get_search_terms( $referer );
|
391 |
-
}
|
392 |
-
self::$stat[ 'resource' ] = self::get_request_uri();
|
393 |
-
}
|
394 |
-
else {
|
395 |
-
self::$stat[ 'resource' ] = parse_url( self::get_request_uri(), PHP_URL_PATH );
|
396 |
-
self::$stat[ 'searchterms' ] = str_replace( '\\', '', $_REQUEST[ 's' ] );
|
397 |
-
self::$stat[ 'referer' ] = self::get_request_uri();
|
398 |
-
if ( isset( $GLOBALS['wp_query']->found_posts ) ) {
|
399 |
-
self::$stat[ 'notes' ][] = 'results:' . intval( $GLOBALS['wp_query']->found_posts );
|
400 |
-
}
|
401 |
-
}
|
402 |
-
|
403 |
-
// Don't store empty values in the database
|
404 |
-
if ( empty( self::$stat[ 'searchterms' ] ) ) {
|
405 |
-
unset( self::$stat[ 'searchterms' ] );
|
406 |
-
}
|
407 |
-
|
408 |
-
// Do not track report pages in the admin
|
409 |
-
if ( ( !empty( self::$stat[ 'resource' ] ) && strpos( self::$stat[ 'resource' ], 'wp-admin/admin-ajax.php' ) !== false ) || ( !empty( $_GET[ 'page' ] ) && strpos( $_GET[ 'page' ], 'slimview' ) !== false ) ) {
|
410 |
-
self::$stat = array();
|
411 |
-
return $_argument;
|
412 |
-
}
|
413 |
-
|
414 |
-
// Is this resource blacklisted?
|
415 |
-
if ( !empty( self::$settings[ 'ignore_resources' ] ) ) {
|
416 |
-
$return_error_code = array(
|
417 |
-
-302,
|
418 |
-
sprintf( __( 'Permalink %s is blacklisted', 'wp-slimstat' ), self::$stat[ 'resource' ] ),
|
419 |
-
true
|
420 |
-
);
|
421 |
-
if ( self::_is_blacklisted( self::$stat[ 'resource' ], self::$settings[ 'ignore_resources' ], $return_error_code ) ) {
|
422 |
-
return $_argument;
|
423 |
-
}
|
424 |
-
}
|
425 |
-
|
426 |
-
// Should we ignore this user?
|
427 |
-
if ( !empty( $GLOBALS[ 'current_user' ]->ID ) ) {
|
428 |
-
// Don't track logged-in users, if the corresponding option is enabled
|
429 |
-
if ( self::$settings[ 'track_users' ] == 'no' ) {
|
430 |
-
self::$stat[ 'id' ] = -303;
|
431 |
-
self::_set_error_array( sprintf( __( 'Logged in user %s not tracked', 'wp-slimstat' ), $GLOBALS[ 'current_user' ]->data->user_login ), true );
|
432 |
-
return $_argument;
|
433 |
-
}
|
434 |
-
|
435 |
-
// Don't track users with given capabilities
|
436 |
-
foreach ( self::string_to_array( self::$settings[ 'ignore_capabilities' ] ) as $a_capability ) {
|
437 |
-
if ( array_key_exists( strtolower( $a_capability ), $GLOBALS[ 'current_user' ]->allcaps ) ) {
|
438 |
-
self::$stat[ 'id' ] = -304;
|
439 |
-
self::_set_error_array( sprintf( __( 'User with capability %s not tracked', 'wp-slimstat' ), $a_capability ), true );
|
440 |
-
return $_argument;
|
441 |
-
}
|
442 |
-
}
|
443 |
-
|
444 |
-
// Is this user blacklisted?
|
445 |
-
if ( !empty( self::$settings[ 'ignore_users' ] ) ) {
|
446 |
-
$return_error_code = array(
|
447 |
-
-305,
|
448 |
-
sprintf( __( 'User %s is blacklisted', 'wp-slimstat' ), $GLOBALS[ 'current_user' ]->data->user_login ),
|
449 |
-
true
|
450 |
-
);
|
451 |
-
if ( self::_is_blacklisted( $GLOBALS[ 'current_user' ]->data->user_login, self::$settings[ 'ignore_users' ], $return_error_code ) ) {
|
452 |
-
return $_argument;
|
453 |
-
}
|
454 |
-
}
|
455 |
-
|
456 |
-
self::$stat[ 'username' ] = $GLOBALS[ 'current_user' ]->data->user_login;
|
457 |
-
self::$stat[ 'notes' ][] = 'user:' . $GLOBALS[ 'current_user' ]->data->ID;
|
458 |
-
$not_spam = true;
|
459 |
-
}
|
460 |
-
elseif ( isset( $_COOKIE[ 'comment_author_' . COOKIEHASH ] ) ) {
|
461 |
-
// Is this a spammer?
|
462 |
-
$spam_comment = self::$wpdb->get_row( self::$wpdb->prepare( "
|
463 |
-
SELECT comment_author, COUNT(*) comment_count
|
464 |
-
FROM `" . DB_NAME . "`.{$GLOBALS['wpdb']->comments}
|
465 |
-
WHERE comment_author_IP = %s AND comment_approved = 'spam'
|
466 |
-
GROUP BY comment_author
|
467 |
-
LIMIT 0,1", self::$stat[ 'ip' ] ), ARRAY_A );
|
468 |
-
|
469 |
-
if ( !empty( $spam_comment[ 'comment_count' ] ) ) {
|
470 |
-
if ( self::$settings[ 'ignore_spammers' ] == 'on' ){
|
471 |
-
self::$stat[ 'id' ] = -306;
|
472 |
-
self::_set_error_array( sprintf( __( 'Spammer %s not tracked', 'wp-slimstat' ), $spam_comment[ 'comment_author' ] ), true );
|
473 |
-
return $_argument;
|
474 |
-
}
|
475 |
-
else{
|
476 |
-
self::$stat[ 'notes' ][] = 'spam:yes';
|
477 |
-
self::$stat[ 'username' ] = $spam_comment[ 'comment_author' ];
|
478 |
-
}
|
479 |
-
}
|
480 |
-
else
|
481 |
-
self::$stat[ 'username' ] = $_COOKIE[ 'comment_author_' . COOKIEHASH ];
|
482 |
-
}
|
483 |
-
|
484 |
-
// Should we ignore this IP address?
|
485 |
-
foreach ( self::string_to_array( self::$settings[ 'ignore_ip' ] ) as $a_ip_range ) {
|
486 |
-
$ip_to_ignore = $a_ip_range;
|
487 |
-
|
488 |
-
if ( strpos( $ip_to_ignore, '/' ) !== false ) {
|
489 |
-
list( $ip_to_ignore, $cidr_mask ) = explode( '/', trim( $ip_to_ignore ) );
|
490 |
-
}
|
491 |
-
else{
|
492 |
-
$cidr_mask = self::get_mask_length( $ip_to_ignore );
|
493 |
-
}
|
494 |
-
|
495 |
-
$long_masked_ip_to_ignore = substr( self::dtr_pton( $ip_to_ignore ), 0, $cidr_mask );
|
496 |
-
$long_masked_user_ip = substr( self::dtr_pton( self::$stat[ 'ip' ] ), 0, $cidr_mask );
|
497 |
-
$long_masked_user_other_ip = substr( self::dtr_pton( self::$stat[ 'other_ip' ] ), 0 , $cidr_mask );
|
498 |
-
|
499 |
-
if ( $long_masked_user_ip === $long_masked_ip_to_ignore || $long_masked_user_other_ip === $long_masked_ip_to_ignore ) {
|
500 |
-
self::$stat[ 'id' ] = -307;
|
501 |
-
self::_set_error_array( sprintf( __( 'IP address %s is blacklisted', 'wp-slimstat' ), self::$stat[ 'ip' ] . ( !empty( self::$stat[ 'other_ip' ] ) ? ' (' . self::$stat[ 'other_ip' ] . ')' : '' ) ), true );
|
502 |
-
return $_argument;
|
503 |
-
}
|
504 |
-
}
|
505 |
-
|
506 |
-
// Language
|
507 |
-
self::$stat[ 'language' ] = self::_get_language();
|
508 |
-
|
509 |
-
// Geolocation
|
510 |
-
include_once ( plugin_dir_path( __FILE__ ) . 'maxmind.php' );
|
511 |
-
$geolocation_data = maxmind_geolite2_connector::get_geolocation_info( self::$stat[ 'ip' ] );
|
512 |
-
|
513 |
-
// Invalid MaxMind data file
|
514 |
-
|
515 |
-
if ( !empty( $geolocation_data[ 'country' ][ 'iso_code' ] ) ) {
|
516 |
-
|
517 |
-
if ( $geolocation_data[ 'country' ][ 'iso_code' ] == 'xx' ) {
|
518 |
-
self::_set_error_array( __( 'Your MaxMind data file is invalid. Please uninstall it using the button in Settings > Maintenance.', 'wp-slimstat' ), false, 205 );
|
519 |
-
}
|
520 |
-
else {
|
521 |
-
self::$stat[ 'country' ] = strtolower( $geolocation_data[ 'country' ][ 'iso_code' ] );
|
522 |
-
|
523 |
-
|
524 |
-
if ( !empty( $geolocation_data[ 'city' ][ 'names' ][ 'en' ] ) ) {
|
525 |
-
self::$stat[ 'city' ] = $geolocation_data[ 'city' ][ 'names' ][ 'en' ];
|
526 |
-
}
|
527 |
-
|
528 |
-
if ( !empty( $geolocation_data[ 'subdivisions' ][ 0 ][ 'iso_code' ] ) && !empty( self::$stat[ 'city' ] ) ) {
|
529 |
-
self::$stat[ 'city' ] .= ' (' . $geolocation_data[ 'subdivisions' ][ 0 ][ 'iso_code' ] . ')';
|
530 |
-
}
|
531 |
-
|
532 |
-
if ( !empty( $geolocation_data[ 'location' ][ 'latitude' ] ) && !empty( $geolocation_data[ 'location' ][ 'longitude' ] ) ) {
|
533 |
-
self::$stat[ 'location' ] = $geolocation_data[ 'location' ][ 'latitude' ] . ',' . $geolocation_data[ 'location' ][ 'longitude' ];
|
534 |
-
}
|
535 |
-
}
|
536 |
-
}
|
537 |
-
|
538 |
-
unset( $geolocation_data );
|
539 |
-
|
540 |
-
// Anonymize IP Address?
|
541 |
-
if ( self::$settings[ 'anonymize_ip' ] == 'on' ) {
|
542 |
-
// IPv4 or IPv6
|
543 |
-
$needle = '.';
|
544 |
-
$replace = '.0';
|
545 |
-
if ( self::get_mask_length( self::$stat['ip'] ) == 128 ) {
|
546 |
-
$needle = ':';
|
547 |
-
$replace = ':0000';
|
548 |
-
}
|
549 |
-
|
550 |
-
self::$stat[ 'ip' ] = substr( self::$stat[ 'ip' ], 0, strrpos( self::$stat[ 'ip' ], $needle ) ) . $replace;
|
551 |
-
|
552 |
-
if ( !empty( self::$stat[ 'other_ip' ] ) ) {
|
553 |
-
self::$stat[ 'other_ip' ] = substr( self::$stat[ 'other_ip' ], 0, strrpos( self::$stat[ 'other_ip' ], $needle ) ) . $replace;
|
554 |
-
}
|
555 |
-
}
|
556 |
-
|
557 |
-
// Is this country blacklisted?
|
558 |
-
if ( !empty( self::$stat[ 'country' ] ) && !empty( self::$settings[ 'ignore_countries' ] ) && stripos( self::$settings[ 'ignore_countries' ], self::$stat[ 'country' ] ) !== false ) {
|
559 |
-
self::$stat['id'] = -308;
|
560 |
-
self::_set_error_array( sprintf( __('Country %s is blacklisted', 'wp-slimstat'), self::$stat[ 'country' ] ), true );
|
561 |
-
return $_argument;
|
562 |
-
}
|
563 |
-
|
564 |
-
// Mark or ignore Firefox/Safari prefetching requests (X-Moz: Prefetch and X-purpose: Preview)
|
565 |
-
if ( ( isset( $_SERVER[ 'HTTP_X_MOZ' ] ) && ( strtolower( $_SERVER[ 'HTTP_X_MOZ' ] ) == 'prefetch' ) ) ||
|
566 |
-
( isset( $_SERVER[ 'HTTP_X_PURPOSE' ] ) && ( strtolower( $_SERVER[ 'HTTP_X_PURPOSE' ] ) == 'preview' ) ) ) {
|
567 |
-
if ( self::$settings[ 'ignore_prefetch' ] == 'on' ) {
|
568 |
-
self::$stat[ 'id' ] = -309;
|
569 |
-
self::_set_error_array( __( 'Prefetch requests are ignored', 'wp-slimstat' ), true );
|
570 |
-
return $_argument;
|
571 |
-
}
|
572 |
-
else{
|
573 |
-
self::$stat[ 'notes' ][] = 'pre:yes';
|
574 |
-
}
|
575 |
-
}
|
576 |
-
|
577 |
-
// Detect user agent
|
578 |
-
if ( empty( self::$browser ) ) {
|
579 |
-
self::$browser = slim_browser::get_browser();
|
580 |
-
}
|
581 |
-
|
582 |
-
// Are we ignoring bots?
|
583 |
-
if ( ( self::$settings[ 'javascript_mode' ] == 'on' || self::$settings[ 'ignore_bots' ] == 'on' ) && self::$browser[ 'browser_type' ] == 1 ) {
|
584 |
-
self::$stat[ 'id' ] = -310;
|
585 |
-
self::_set_error_array( __( 'Bot not tracked', 'wp-slimstat' ), true );
|
586 |
-
return $_argument;
|
587 |
-
}
|
588 |
-
|
589 |
-
// Is this browser blacklisted?
|
590 |
-
if ( !empty( self::$settings[ 'ignore_browsers' ] ) ) {
|
591 |
-
$return_error_code = array(
|
592 |
-
-311,
|
593 |
-
sprintf( __( 'Browser %s is blacklisted', 'wp-slimstat' ), self::$browser[ 'browser' ] ),
|
594 |
-
true
|
595 |
-
);
|
596 |
-
if ( self::_is_blacklisted( array( self::$browser[ 'browser' ], self::$browser[ 'user_agent' ] ), self::$settings[ 'ignore_browsers' ], $return_error_code ) ) {
|
597 |
-
return $_argument;
|
598 |
-
}
|
599 |
-
}
|
600 |
-
|
601 |
-
// Is this operating system blacklisted?
|
602 |
-
if ( !empty( self::$settings[ 'ignore_platforms' ] ) ) {
|
603 |
-
$return_error_code = array(
|
604 |
-
-312,
|
605 |
-
sprintf( __( 'Operating System %s is blacklisted', 'wp-slimstat' ), self::$browser[ 'platform' ] ),
|
606 |
-
true
|
607 |
-
);
|
608 |
-
if ( self::_is_blacklisted( self::$browser[ 'platform' ], self::$settings[ 'ignore_platforms' ], $return_error_code ) ) {
|
609 |
-
return $_argument;
|
610 |
-
}
|
611 |
-
}
|
612 |
-
|
613 |
-
self::$stat = self::$stat + self::$browser;
|
614 |
-
|
615 |
-
// This function can be called in "simulate" mode: no data will be actually saved in the database
|
616 |
-
if ( is_array( $_argument ) && isset( $_argument[ 'slimtrack_simulate' ] ) ) {
|
617 |
-
$_argument[ 'slimtrack_would_track' ] = true;
|
618 |
-
return ( $_argument );
|
619 |
-
}
|
620 |
-
|
621 |
-
// Do we need to assign a visit_id to this user?
|
622 |
-
$cookie_has_been_set = self::_set_visit_id( false );
|
623 |
-
|
624 |
-
// Allow third-party tools to modify all the data we've gathered so far
|
625 |
-
self::$stat = apply_filters( 'slimstat_filter_pageview_stat', self::$stat );
|
626 |
-
do_action( 'slimstat_track_pageview', self::$stat );
|
627 |
-
|
628 |
-
// Third-party tools can decide that this pageview should not be tracked, by setting its datestamp to zero
|
629 |
-
if (empty(self::$stat) || empty(self::$stat['dt'])){
|
630 |
-
self::$stat['id'] = -300;
|
631 |
-
self::_set_error_array( __( 'Pageview filtered by third-party code', 'wp-slimstat' ), true );
|
632 |
-
return $_argument;
|
633 |
-
}
|
634 |
-
|
635 |
-
// Implode the notes
|
636 |
-
if ( !empty( self::$stat[ 'notes' ] ) ) {
|
637 |
-
self::$stat[ 'notes' ] = implode( ';', self::$stat[ 'notes' ] );
|
638 |
-
}
|
639 |
-
else {
|
640 |
-
unset( self::$stat[ 'notes' ] );
|
641 |
-
}
|
642 |
-
|
643 |
-
// Now let's save this information in the database
|
644 |
-
self::$stat[ 'id' ] = self::insert_row( self::$stat, $GLOBALS[ 'wpdb' ]->prefix . 'slim_stats' );
|
645 |
-
|
646 |
-
// Something went wrong during the insert
|
647 |
-
if ( empty( self::$stat[ 'id' ] ) ) {
|
648 |
-
|
649 |
-
// Attempt to init the environment (plugin just activated on a blog in a MU network?)
|
650 |
-
include_once ( plugin_dir_path( __FILE__ ) . 'admin/wp-slimstat-admin.php' );
|
651 |
-
wp_slimstat_admin::init_environment( true );
|
652 |
-
|
653 |
-
// Now let's try again
|
654 |
-
self::$stat['id'] = self::insert_row(self::$stat, $GLOBALS['wpdb']->prefix.'slim_stats');
|
655 |
-
|
656 |
-
if ( empty( self::$stat[ 'id' ] ) ) {
|
657 |
-
self::$stat[ 'id' ] = -200;
|
658 |
-
self::_set_error_array( self::$wpdb->last_error, false );
|
659 |
-
return $_argument;
|
660 |
-
}
|
661 |
-
}
|
662 |
-
|
663 |
-
// Is this a new visitor?
|
664 |
-
$set_cookie = apply_filters( 'slimstat_set_visit_cookie', ( !empty( self::$settings[ 'set_tracker_cookie' ] ) && self::$settings[ 'set_tracker_cookie' ] == 'on' ) );
|
665 |
-
if ( $set_cookie ) {
|
666 |
-
if ( empty( self::$stat[ 'visit_id' ] ) && !empty( self::$stat[ 'id' ] ) ) {
|
667 |
-
// Set a cookie to track this visit (Google and other non-human engines will just ignore it)
|
668 |
-
@setcookie(
|
669 |
-
'slimstat_tracking_code',
|
670 |
-
self::_get_id_with_checksum( self::$stat[ 'id' ] . 'id' ),
|
671 |
-
time() + 2678400, // one month
|
672 |
-
COOKIEPATH
|
673 |
-
);
|
674 |
-
}
|
675 |
-
elseif ( !$cookie_has_been_set && self::$settings[ 'extend_session' ] == 'on' && self::$stat[ 'visit_id' ] > 0 ) {
|
676 |
-
@setcookie(
|
677 |
-
'slimstat_tracking_code',
|
678 |
-
self::_get_id_with_checksum( self::$stat[ 'visit_id' ] ),
|
679 |
-
time() + self::$settings[ 'session_duration' ],
|
680 |
-
COOKIEPATH
|
681 |
-
);
|
682 |
-
}
|
683 |
-
}
|
684 |
-
|
685 |
-
return $_argument;
|
686 |
-
}
|
687 |
-
// end slimtrack
|
688 |
-
|
689 |
-
/**
|
690 |
-
* Decodes the permalink
|
691 |
-
*/
|
692 |
-
public static function get_request_uri(){
|
693 |
-
if (isset($_SERVER['REQUEST_URI'])){
|
694 |
-
return urldecode($_SERVER['REQUEST_URI']);
|
695 |
-
}
|
696 |
-
elseif (isset($_SERVER['SCRIPT_NAME'])){
|
697 |
-
return isset($_SERVER['QUERY_STRING'])?$_SERVER['SCRIPT_NAME']."?".$_SERVER['QUERY_STRING']:$_SERVER['SCRIPT_NAME'];
|
698 |
-
}
|
699 |
-
else{
|
700 |
-
return isset($_SERVER['QUERY_STRING'])?$_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING']:$_SERVER['PHP_SELF'];
|
701 |
-
}
|
702 |
-
}
|
703 |
-
// end get_request_uri
|
704 |
-
|
705 |
-
/**
|
706 |
-
* Stores the information (array) in the appropriate table and returns the corresponding ID
|
707 |
-
*/
|
708 |
-
public static function insert_row($_data = array(), $_table = ''){
|
709 |
-
if ( empty( $_data ) || empty( $_table ) ) {
|
710 |
-
return -1;
|
711 |
-
}
|
712 |
-
|
713 |
-
// Remove unwanted characters (SQL injections, anyone?)
|
714 |
-
$data_keys = array();
|
715 |
-
foreach (array_keys($_data) as $a_key){
|
716 |
-
$data_keys[] = sanitize_key($a_key);
|
717 |
-
}
|
718 |
-
|
719 |
-
self::$wpdb->query(self::$wpdb->prepare("
|
720 |
-
INSERT IGNORE INTO $_table (".implode(", ", $data_keys).')
|
721 |
-
VALUES ('.substr(str_repeat('%s,', count($_data)), 0, -1).")", $_data));
|
722 |
-
|
723 |
-
return intval(self::$wpdb->insert_id);
|
724 |
-
}
|
725 |
-
// end insert_row
|
726 |
-
|
727 |
-
/**
|
728 |
-
* Updates an existing row
|
729 |
-
*/
|
730 |
-
public static function update_row($_data = array(), $_table = ''){
|
731 |
-
if (empty($_data) || empty($_table)){
|
732 |
-
return -1;
|
733 |
-
}
|
734 |
-
|
735 |
-
// Move the ID at the end of the array
|
736 |
-
$id = $_data['id'];
|
737 |
-
unset($_data['id']);
|
738 |
-
|
739 |
-
// Remove unwanted characters (SQL injections, anyone?)
|
740 |
-
$data_keys = array();
|
741 |
-
foreach (array_keys($_data) as $a_key){
|
742 |
-
$data_keys[] = sanitize_key($a_key);
|
743 |
-
}
|
744 |
-
|
745 |
-
// Add the id at the end
|
746 |
-
$_data['id'] = $id;
|
747 |
-
|
748 |
-
self::$wpdb->query(self::$wpdb->prepare("
|
749 |
-
UPDATE IGNORE $_table
|
750 |
-
SET ".implode(' = %s, ', $data_keys)." = %s
|
751 |
-
WHERE id = %d", $_data));
|
752 |
-
|
753 |
-
return 0;
|
754 |
-
}
|
755 |
-
|
756 |
-
/**
|
757 |
-
* Tries to find the user's REAL IP address
|
758 |
-
*/
|
759 |
-
protected static function _get_remote_ip(){
|
760 |
-
$ip_array = array( '', '' );
|
761 |
-
|
762 |
-
if ( !empty( $_SERVER[ 'REMOTE_ADDR' ] ) && filter_var( $_SERVER[ 'REMOTE_ADDR' ], FILTER_VALIDATE_IP ) !== false ) {
|
763 |
-
$ip_array[ 0 ] = $_SERVER[ 'REMOTE_ADDR' ];
|
764 |
-
}
|
765 |
-
|
766 |
-
$originating_ip_headers = array( 'X-Forwarded-For', 'HTTP_X_FORWARDED_FOR', 'CF-Connecting-IP', 'HTTP_CLIENT_IP', 'HTTP_X_REAL_IP', 'HTTP_FORWARDED', 'HTTP_X_FORWARDED' );
|
767 |
-
foreach ( $originating_ip_headers as $a_header ) {
|
768 |
-
if ( !empty( $_SERVER[ $a_header ] ) ) {
|
769 |
-
foreach ( explode( ',', $_SERVER[ $a_header ] ) as $a_ip ) {
|
770 |
-
if ( filter_var( $a_ip, FILTER_VALIDATE_IP ) !== false && $a_ip != $ip_array[ 0 ] ) {
|
771 |
-
$ip_array[ 1 ] = $a_ip;
|
772 |
-
break;
|
773 |
-
}
|
774 |
-
}
|
775 |
-
}
|
776 |
-
}
|
777 |
-
|
778 |
-
return $ip_array;
|
779 |
-
}
|
780 |
-
// end _get_remote_ip
|
781 |
-
|
782 |
-
/**
|
783 |
-
* Extracts the accepted language from browser headers
|
784 |
-
*/
|
785 |
-
protected static function _get_language(){
|
786 |
-
if(isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])){
|
787 |
-
|
788 |
-
// Capture up to the first delimiter (, found in Safari)
|
789 |
-
preg_match("/([^,;]*)/", $_SERVER["HTTP_ACCEPT_LANGUAGE"], $array_languages);
|
790 |
-
|
791 |
-
// Fix some codes, the correct syntax is with minus (-) not underscore (_)
|
792 |
-
return str_replace( "_", "-", strtolower( $array_languages[0] ) );
|
793 |
-
}
|
794 |
-
return 'xx'; // Indeterminable language
|
795 |
-
}
|
796 |
-
// end _get_language
|
797 |
-
|
798 |
-
/**
|
799 |
-
* Sniffs out referrals from search engines and tries to determine the query string
|
800 |
-
*/
|
801 |
-
protected static function _get_search_terms( $_url = array() ) {
|
802 |
-
if ( empty( $_url ) || !isset( $_url[ 'host' ] ) ) {
|
803 |
-
return '';
|
804 |
-
}
|
805 |
-
|
806 |
-
// Engines with different character encodings should always be listed here, regardless of their query string format
|
807 |
-
$query_formats = array(
|
808 |
-
'baidu.com' => 'wd',
|
809 |
-
'bing' => 'q',
|
810 |
-
'dogpile.com' => 'q',
|
811 |
-
'duckduckgo' => 'q',
|
812 |
-
'eniro' => 'search_word',
|
813 |
-
'exalead.com' => 'q',
|
814 |
-
'excite' => 'q',
|
815 |
-
'gigablast' => 'q',
|
816 |
-
'google' => 'q',
|
817 |
-
'hotbot' => 'q',
|
818 |
-
'maktoob' => 'p',
|
819 |
-
'mamma' => 'q',
|
820 |
-
'naver' => 'query',
|
821 |
-
'qwant' => 'q',
|
822 |
-
'rambler' => 'query',
|
823 |
-
'seznam' => 'oq',
|
824 |
-
'soso.com' => 'query',
|
825 |
-
'virgilio' => 'qs',
|
826 |
-
'voila' => 'rdata',
|
827 |
-
'yahoo' => 'p',
|
828 |
-
'yam' => 'k',
|
829 |
-
'yandex' => 'text',
|
830 |
-
'yell' => 'keywords',
|
831 |
-
'yippy' => 'query',
|
832 |
-
'youdao' => 'q'
|
833 |
-
);
|
834 |
-
|
835 |
-
$charsets = array( 'baidu' => 'EUC-CN' );
|
836 |
-
$regex_match = implode( '|', array_keys( $query_formats ) );
|
837 |
-
$searchterms = '';
|
838 |
-
|
839 |
-
if ( !empty( $_url[ 'query' ] ) ) {
|
840 |
-
parse_str( $_url[ 'query' ], $query );
|
841 |
-
}
|
842 |
-
|
843 |
-
if ( !empty( $_url[ 'host' ] ) ) {
|
844 |
-
preg_match( "~($regex_match).~i", $_url[ 'host' ], $matches );
|
845 |
-
}
|
846 |
-
|
847 |
-
if ( !empty( $matches[ 1 ] ) ) {
|
848 |
-
// Let's remember that this is a search engine, regardless of the URL containing searchterms (thank you, NSA)
|
849 |
-
$searchterms = '_';
|
850 |
-
if ( !empty( $query[ $query_formats[ $matches[ 1 ] ] ] ) ) {
|
851 |
-
$searchterms = str_replace( '\\', '', trim( urldecode( $query[ $query_formats[ $matches[ 1 ] ] ] ) ) );
|
852 |
-
// Test for encodings different from UTF-8
|
853 |
-
if ( function_exists( 'mb_check_encoding' ) && !mb_check_encoding( $query[ $query_formats[ $matches[ 1 ] ] ], 'UTF-8' ) && !empty( $charsets[ $matches[ 1 ] ] ) ) {
|
854 |
-
$searchterms = mb_convert_encoding( urldecode( $query[ $query_formats[ $matches[ 1 ] ] ] ), 'UTF-8', $charsets[ $matches[ 1 ] ] );
|
855 |
-
}
|
856 |
-
}
|
857 |
-
}
|
858 |
-
else {
|
859 |
-
// We weren't lucky, but there's still hope
|
860 |
-
foreach( array( 'q','s','k','qt' ) as $a_format ) {
|
861 |
-
if ( !empty( $query[ $a_format ] ) ) {
|
862 |
-
$searchterms = str_replace( '\\', '', trim( urldecode( $query[ $a_format ] ) ) );
|
863 |
-
break;
|
864 |
-
}
|
865 |
-
}
|
866 |
-
}
|
867 |
-
|
868 |
-
return $searchterms;
|
869 |
-
}
|
870 |
-
// end _get_search_terms
|
871 |
-
|
872 |
-
/**
|
873 |
-
* Returns details about the resource being accessed
|
874 |
-
*/
|
875 |
-
protected static function _get_content_info(){
|
876 |
-
$content_info = array( 'content_type' => 'unknown' );
|
877 |
-
|
878 |
-
// Mark 404 pages
|
879 |
-
if ( is_404() ) {
|
880 |
-
$content_info[ 'content_type' ] = '404';
|
881 |
-
}
|
882 |
-
|
883 |
-
// Type
|
884 |
-
else if ( is_single() ) {
|
885 |
-
if ( ( $post_type = get_post_type() ) != 'post' ) {
|
886 |
-
$post_type = 'cpt:' . $post_type;
|
887 |
-
}
|
888 |
-
|
889 |
-
$content_info[ 'content_type' ] = $post_type;
|
890 |
-
$content_info_array = array();
|
891 |
-
foreach ( get_object_taxonomies( $GLOBALS[ 'post' ] ) as $a_taxonomy ) {
|
892 |
-
$terms = get_the_terms( $GLOBALS[ 'post' ]->ID, $a_taxonomy );
|
893 |
-
if ( is_array( $terms ) ) {
|
894 |
-
foreach ( $terms as $a_term ) {
|
895 |
-
$content_info_array[] = $a_term->term_id;
|
896 |
-
}
|
897 |
-
$content_info[ 'category' ] = implode( ',', $content_info_array );
|
898 |
-
}
|
899 |
-
}
|
900 |
-
$content_info[ 'content_id' ] = $GLOBALS[ 'post' ]->ID;
|
901 |
-
}
|
902 |
-
else if ( is_page() ) {
|
903 |
-
$content_info[ 'content_type' ] = 'page';
|
904 |
-
$content_info[ 'content_id' ] = $GLOBALS[ 'post' ]->ID;
|
905 |
-
}
|
906 |
-
elseif (is_attachment()){
|
907 |
-
$content_info['content_type'] = 'attachment';
|
908 |
-
}
|
909 |
-
elseif (is_singular()){
|
910 |
-
$content_info['content_type'] = 'singular';
|
911 |
-
}
|
912 |
-
elseif (is_post_type_archive()){
|
913 |
-
$content_info['content_type'] = 'post_type_archive';
|
914 |
-
}
|
915 |
-
elseif (is_tag()){
|
916 |
-
$content_info['content_type'] = 'tag';
|
917 |
-
$list_tags = get_the_tags();
|
918 |
-
if (is_array($list_tags)){
|
919 |
-
$tag_info = array_pop($list_tags);
|
920 |
-
if (!empty($tag_info)) $content_info['category'] = "$tag_info->term_id";
|
921 |
-
}
|
922 |
-
}
|
923 |
-
elseif (is_tax()){
|
924 |
-
$content_info['content_type'] = 'taxonomy';
|
925 |
-
}
|
926 |
-
elseif (is_category()){
|
927 |
-
$content_info['content_type'] = 'category';
|
928 |
-
$list_categories = get_the_category();
|
929 |
-
if (is_array($list_categories)){
|
930 |
-
$cat_info = array_pop($list_categories);
|
931 |
-
if (!empty($cat_info)) $content_info['category'] = "$cat_info->term_id";
|
932 |
-
}
|
933 |
-
}
|
934 |
-
else if (is_date()){
|
935 |
-
$content_info['content_type']= 'date';
|
936 |
-
}
|
937 |
-
else if (is_author()){
|
938 |
-
$content_info['content_type'] = 'author';
|
939 |
-
}
|
940 |
-
else if ( is_archive() ) {
|
941 |
-
$content_info['content_type'] = 'archive';
|
942 |
-
}
|
943 |
-
else if ( is_search() ) {
|
944 |
-
$content_info[ 'content_type' ] = 'search';
|
945 |
-
}
|
946 |
-
else if ( is_feed() ) {
|
947 |
-
$content_info[ 'content_type' ] = 'feed';
|
948 |
-
}
|
949 |
-
else if ( is_home() || is_front_page() ) {
|
950 |
-
$content_info['content_type'] = 'home';
|
951 |
-
}
|
952 |
-
else if ( !empty( $GLOBALS[ 'pagenow' ] ) && $GLOBALS[ 'pagenow' ] == 'wp-login.php' ) {
|
953 |
-
$content_info[ 'content_type' ] = 'login';
|
954 |
-
}
|
955 |
-
else if ( !empty( $GLOBALS['pagenow'] ) && $GLOBALS['pagenow'] == 'wp-register.php' ) {
|
956 |
-
$content_info[ 'content_type' ] = 'registration';
|
957 |
-
}
|
958 |
-
// WordPress sets is_admin() to true for all ajax requests ( front-end or admin-side )
|
959 |
-
elseif ( is_admin() && ( !defined( 'DOING_AJAX' ) || !DOING_AJAX ) ) {
|
960 |
-
$content_info[ 'content_type' ] = 'admin';
|
961 |
-
}
|
962 |
-
|
963 |
-
if (is_paged()){
|
964 |
-
$content_info[ 'content_type' ] .= ',paged';
|
965 |
-
}
|
966 |
-
|
967 |
-
// Author
|
968 |
-
if ( is_singular() ) {
|
969 |
-
$author = get_the_author_meta( 'user_login', $GLOBALS[ 'post' ]->post_author );
|
970 |
-
if ( !empty( $author ) ) {
|
971 |
-
$content_info[ 'author' ] = $author;
|
972 |
-
}
|
973 |
-
}
|
974 |
-
|
975 |
-
return $content_info;
|
976 |
-
}
|
977 |
-
// end _get_content_info
|
978 |
-
|
979 |
-
/**
|
980 |
-
* Reads the cookie to get the visit_id and sets the variable accordingly
|
981 |
-
*/
|
982 |
-
protected static function _set_visit_id($_force_assign = false){
|
983 |
-
$is_new_session = true;
|
984 |
-
$identifier = 0;
|
985 |
-
|
986 |
-
if ( isset( $_COOKIE[ 'slimstat_tracking_code' ] ) ) {
|
987 |
-
// Make sure only authorized information is recorded
|
988 |
-
$identifier = self::_separate_id_from_checksum( $_COOKIE[ 'slimstat_tracking_code' ] );
|
989 |
-
if ( $identifier === false ) {
|
990 |
-
return false;
|
991 |
-
}
|
992 |
-
|
993 |
-
$is_new_session = ( strpos( $identifier, 'id' ) !== false );
|
994 |
-
$identifier = intval( $identifier );
|
995 |
-
}
|
996 |
-
|
997 |
-
// User doesn't have an active session
|
998 |
-
if ( $is_new_session && ( $_force_assign || self::$settings[ 'javascript_mode' ] == 'on' ) ) {
|
999 |
-
if ( empty( self::$settings[ 'session_duration' ] ) ) {
|
1000 |
-
self::$settings[ 'session_duration' ] = 1800;
|
1001 |
-
}
|
1002 |
-
|
1003 |
-
self::$stat[ 'visit_id' ] = get_transient( 'slimstat_visit_id' );
|
1004 |
-
if ( self::$stat[ 'visit_id' ] === false ) {
|
1005 |
-
self::$stat[ 'visit_id' ] = intval( self::$wpdb->get_var( "SELECT MAX( visit_id ) FROM {$GLOBALS[ 'wpdb' ]->prefix}slim_stats" ) );
|
1006 |
-
}
|
1007 |
-
self::$stat[ 'visit_id' ]++;
|
1008 |
-
set_transient( 'slimstat_visit_id', self::$stat[ 'visit_id' ] );
|
1009 |
-
|
1010 |
-
$set_cookie = apply_filters( 'slimstat_set_visit_cookie', ( !empty( self::$settings[ 'set_tracker_cookie' ] ) && self::$settings[ 'set_tracker_cookie' ] == 'on' ) );
|
1011 |
-
if ( $set_cookie ) {
|
1012 |
-
@setcookie(
|
1013 |
-
'slimstat_tracking_code',
|
1014 |
-
self::_get_id_with_checksum( self::$stat[ 'visit_id' ] ),
|
1015 |
-
time() + self::$settings[ 'session_duration' ],
|
1016 |
-
COOKIEPATH
|
1017 |
-
);
|
1018 |
-
}
|
1019 |
-
|
1020 |
-
}
|
1021 |
-
elseif ( $identifier > 0 ) {
|
1022 |
-
self::$stat[ 'visit_id' ] = $identifier;
|
1023 |
-
}
|
1024 |
-
|
1025 |
-
if ( $is_new_session && $identifier > 0 ) {
|
1026 |
-
self::$wpdb->query( self::$wpdb->prepare( "
|
1027 |
-
UPDATE {$GLOBALS['wpdb']->prefix}slim_stats
|
1028 |
-
SET visit_id = %d
|
1029 |
-
WHERE id = %d AND visit_id = 0", self::$stat[ 'visit_id' ], $identifier
|
1030 |
-
) );
|
1031 |
-
}
|
1032 |
-
return ( $is_new_session && ( $_force_assign || self::$settings[ 'javascript_mode' ] == 'on' ) );
|
1033 |
-
}
|
1034 |
-
// end _set_visit_id
|
1035 |
-
|
1036 |
-
/**
|
1037 |
-
* Makes sure that the data received from the client is well-formed (and that nobody is trying to do bad stuff)
|
1038 |
-
*/
|
1039 |
-
protected static function _check_data_integrity( $_data = '' ) {
|
1040 |
-
// Parse the information we received
|
1041 |
-
self::$data_js = apply_filters( 'slimstat_filter_pageview_data_js', $_data );
|
1042 |
-
|
1043 |
-
// Do we have an id for this request?
|
1044 |
-
if ( empty( self::$data_js[ 'id' ] ) || empty( self::$data_js[ 'op' ] ) ) {
|
1045 |
-
do_action( 'slimstat_track_exit_102' );
|
1046 |
-
self::$stat[ 'id' ] = -100;
|
1047 |
-
self::_set_error_array( __( 'Invalid payload string. Try clearing your WordPress cache.', 'wp-slimstat' ), false );
|
1048 |
-
self::slimstat_save_options();
|
1049 |
-
exit( self::_get_id_with_checksum( self::$stat[ 'id' ] ) );
|
1050 |
-
}
|
1051 |
-
|
1052 |
-
// Make sure that the control code is valid
|
1053 |
-
self::$data_js[ 'id' ] = self::_separate_id_from_checksum( self::$data_js[ 'id' ] );
|
1054 |
-
|
1055 |
-
if ( self::$data_js['id'] === false ) {
|
1056 |
-
do_action( 'slimstat_track_exit_103' );
|
1057 |
-
self::$stat[ 'id' ] = -101;
|
1058 |
-
self::_set_error_array( __( 'Invalid data signature. Try clearing your WordPress cache.', 'wp-slimstat' ), false );
|
1059 |
-
self::slimstat_save_options();
|
1060 |
-
exit( self::_get_id_with_checksum( self::$stat[ 'id' ] ) );
|
1061 |
-
}
|
1062 |
-
|
1063 |
-
$intval_id = intval( self::$data_js[ 'id' ] );
|
1064 |
-
if ( $intval_id < 0 ) {
|
1065 |
-
do_action( 'slimstat_track_exit_' . abs( $intval_id ) );
|
1066 |
-
self::$stat[ 'id' ] = $intval_id;
|
1067 |
-
self::slimstat_save_options();
|
1068 |
-
exit( self::_get_id_with_checksum( self::$stat[ 'id' ] ) );
|
1069 |
-
}
|
1070 |
-
}
|
1071 |
-
// end _check_data_integrity
|
1072 |
-
|
1073 |
-
protected static function _set_error_array( $_error_message = '', $_is_notice = false, $_error_code = 0 ) {
|
1074 |
-
$error_code = empty( $_error_code ) ? abs( self::$stat[ 'id' ] ) : $_error_code;
|
1075 |
-
self::toggle_date_i18n_filters( false );
|
1076 |
-
if ( $_is_notice ) {
|
1077 |
-
self::$settings[ 'last_tracker_notice' ] = array( $error_code, $_error_message, date_i18n( 'U' ) );
|
1078 |
-
}
|
1079 |
-
else {
|
1080 |
-
self::$settings[ 'last_tracker_error' ] = array( $error_code, $_error_message, date_i18n( 'U' ) );
|
1081 |
-
}
|
1082 |
-
self::toggle_date_i18n_filters( true );
|
1083 |
-
}
|
1084 |
-
|
1085 |
-
protected static function _get_id_with_checksum( $_id = 0 ) {
|
1086 |
-
return $_id . '.' . md5( $_id . self::$settings[ 'secret' ] );
|
1087 |
-
}
|
1088 |
-
|
1089 |
-
protected static function _separate_id_from_checksum( $_id_with_checksum = '' ) {
|
1090 |
-
list( $id, $checksum ) = explode( '.', $_id_with_checksum );
|
1091 |
-
|
1092 |
-
if ( $checksum === md5( $id . self::$settings[ 'secret' ] ) ) {
|
1093 |
-
return $id;
|
1094 |
-
}
|
1095 |
-
|
1096 |
-
return false;
|
1097 |
-
}
|
1098 |
-
|
1099 |
-
protected static function _is_blacklisted( $_needles = array(), $_haystack_string = '', $_return_error_code = array( 0, '', false ) ) {
|
1100 |
-
foreach ( self::string_to_array( $_haystack_string ) as $a_item ) {
|
1101 |
-
$pattern = str_replace( array( '\*', '\!' ) , array( '(.*)', '.' ), preg_quote( $a_item, '@' ) );
|
1102 |
-
|
1103 |
-
if ( !is_array( $_needles ) ) {
|
1104 |
-
$_needles = array( $_needles );
|
1105 |
-
}
|
1106 |
-
|
1107 |
-
foreach ( $_needles as $a_needle ) {
|
1108 |
-
if ( preg_match( "@^$pattern$@i", $a_needle ) ) {
|
1109 |
-
|
1110 |
-
self::$stat[ 'id' ] = $_return_error_code[ 0 ];
|
1111 |
-
self::_set_error_array( $_return_error_code[ 1 ], $_return_error_code[ 2 ] );
|
1112 |
-
return true;
|
1113 |
-
}
|
1114 |
-
}
|
1115 |
-
}
|
1116 |
-
|
1117 |
-
return false;
|
1118 |
-
}
|
1119 |
-
|
1120 |
-
public static function is_local_ip_address( $ip_address = '' ) {
|
1121 |
-
if ( !filter_var( $ip_address, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) {
|
1122 |
-
return true;
|
1123 |
-
}
|
1124 |
-
|
1125 |
-
return false;
|
1126 |
-
}
|
1127 |
-
|
1128 |
-
public static function dtr_pton( $ip ){
|
1129 |
-
if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) {
|
1130 |
-
$unpacked = unpack( 'A4', inet_pton( $ip ) );
|
1131 |
-
}
|
1132 |
-
else if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) && defined( 'AF_INET6' ) ) {
|
1133 |
-
$unpacked = unpack( 'A16', inet_pton( $ip ) );
|
1134 |
-
}
|
1135 |
-
|
1136 |
-
$binary_ip = '';
|
1137 |
-
if ( !empty( $unpacked ) ) {
|
1138 |
-
$unpacked = str_split( $unpacked[ 1 ] );
|
1139 |
-
foreach ( $unpacked as $char ) {
|
1140 |
-
$binary_ip .= str_pad( decbin( ord( $char ) ), 8, '0', STR_PAD_LEFT );
|
1141 |
-
}
|
1142 |
-
}
|
1143 |
-
|
1144 |
-
return $binary_ip;
|
1145 |
-
}
|
1146 |
-
|
1147 |
-
public static function get_mask_length( $ip ){
|
1148 |
-
if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) {
|
1149 |
-
return 32;
|
1150 |
-
}
|
1151 |
-
else if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
|
1152 |
-
return 128;
|
1153 |
-
}
|
1154 |
-
|
1155 |
-
return false;
|
1156 |
-
}
|
1157 |
-
|
1158 |
-
/**
|
1159 |
-
* Opens given domains during CORS requests to admin-ajax.php
|
1160 |
-
*/
|
1161 |
-
public static function open_cors_admin_ajax( $_allowed_origins = array() ) {
|
1162 |
-
$exploded_domains = self::string_to_array( self::$settings[ 'external_domains' ] );
|
1163 |
-
|
1164 |
-
if ( !empty( $exploded_domains ) && !empty( $exploded_domains[ 0 ] ) ) {
|
1165 |
-
$_allowed_origins = array_merge( $_allowed_origins, $exploded_domains );
|
1166 |
-
}
|
1167 |
-
|
1168 |
-
return $_allowed_origins;
|
1169 |
-
}
|
1170 |
-
|
1171 |
-
/**
|
1172 |
-
* Downloads the MaxMind geolocation database from their repository
|
1173 |
-
*/
|
1174 |
-
public static function download_maxmind_database() {
|
1175 |
-
// Create the folder, if it doesn't exist
|
1176 |
-
if ( !file_exists( dirname( self::$maxmind_path ) ) ) {
|
1177 |
-
mkdir( dirname( self::$maxmind_path ) );
|
1178 |
-
}
|
1179 |
-
|
1180 |
-
if ( file_exists( self::$maxmind_path ) ) {
|
1181 |
-
if ( is_file( self::$maxmind_path ) ) {
|
1182 |
-
$is_deleted = @unlink( self::$maxmind_path );
|
1183 |
-
}
|
1184 |
-
else {
|
1185 |
-
// This should not happen, but hey...
|
1186 |
-
$is_deleted = @rmdir( self::$maxmind_path );
|
1187 |
-
}
|
1188 |
-
|
1189 |
-
if ( !$is_deleted ) {
|
1190 |
-
return __( "The geolocation database cannot be updated. Please check your server's file permissions and try again.", 'wp-slimstat' );
|
1191 |
-
}
|
1192 |
-
}
|
1193 |
-
|
1194 |
-
// Download the most recent database directly from MaxMind's repository
|
1195 |
-
if ( self::$settings[ 'geolocation_country' ] == 'on' ) {
|
1196 |
-
$maxmind_tmp = self::download_url( 'http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz' );
|
1197 |
-
}
|
1198 |
-
else {
|
1199 |
-
$maxmind_tmp = self::download_url( 'http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz' );
|
1200 |
-
}
|
1201 |
-
|
1202 |
-
if ( is_wp_error( $maxmind_tmp ) ) {
|
1203 |
-
return __( 'There was an error downloading the MaxMind Geolite DB:', 'wp-slimstat' ) . ' ' . $maxmind_tmp->get_error_message();
|
1204 |
-
}
|
1205 |
-
|
1206 |
-
$zh = false;
|
1207 |
-
|
1208 |
-
if ( !function_exists( 'gzopen' ) ) {
|
1209 |
-
if ( function_exists( 'gzopen64' ) ) {
|
1210 |
-
if ( false === ( $zh = gzopen64( $maxmind_tmp, 'rb' ) ) ) {
|
1211 |
-
return __( 'There was an error opening the zipped MaxMind Geolite DB.', 'wp-slimstat' );
|
1212 |
-
}
|
1213 |
-
}
|
1214 |
-
else {
|
1215 |
-
return __( 'Function gzopen not defined. Aborting.', 'wp-slimstat' );
|
1216 |
-
}
|
1217 |
-
}
|
1218 |
-
else{
|
1219 |
-
if ( false === ( $zh = gzopen( $maxmind_tmp, 'rb' ) ) ) {
|
1220 |
-
return __( 'There was an error opening the zipped MaxMind Geolite DB.', 'wp-slimstat' );
|
1221 |
-
}
|
1222 |
-
}
|
1223 |
-
|
1224 |
-
if ( false === ( $fh = fopen( self::$maxmind_path, 'wb' ) ) ) {
|
1225 |
-
return __( 'There was an error opening the MaxMind Geolite DB.', 'wp-slimstat' );
|
1226 |
-
}
|
1227 |
-
|
1228 |
-
while ( ( $data = gzread( $zh, 4096 ) ) != false ) {
|
1229 |
-
fwrite( $fh, $data );
|
1230 |
-
}
|
1231 |
-
|
1232 |
-
@gzclose( $zh );
|
1233 |
-
@fclose( $fh );
|
1234 |
-
|
1235 |
-
if ( !is_file( self::$maxmind_path ) ) {
|
1236 |
-
// Something went wrong, maybe a folder was created instead of a regular file
|
1237 |
-
@rmdir( self::$maxmind_path );
|
1238 |
-
return __( 'There was an error creating the MaxMind Geolite DB.', 'wp-slimstat' );
|
1239 |
-
}
|
1240 |
-
|
1241 |
-
@unlink( $maxmind_tmp );
|
1242 |
-
|
1243 |
-
return '';
|
1244 |
-
}
|
1245 |
-
|
1246 |
-
public static function download_url( $url ) {
|
1247 |
-
// Include the FILE API, if it's not defined
|
1248 |
-
if ( !function_exists( 'download_url' ) ) {
|
1249 |
-
require_once( ABSPATH . 'wp-admin/includes/file.php' );
|
1250 |
-
}
|
1251 |
-
|
1252 |
-
if ( !$url ) {
|
1253 |
-
return new WP_Error('http_no_url', __('Invalid URL Provided.'));
|
1254 |
-
}
|
1255 |
-
|
1256 |
-
$url_filename = basename( parse_url( $url, PHP_URL_PATH ) );
|
1257 |
-
|
1258 |
-
$tmpfname = wp_tempnam( $url_filename );
|
1259 |
-
if ( ! $tmpfname ) {
|
1260 |
-
return new WP_Error('http_no_file', __('Could not create Temporary file.'));
|
1261 |
-
}
|
1262 |
-
|
1263 |
-
$response = wp_safe_remote_get( $url, array( 'timeout' => 300, 'stream' => true, 'filename' => $tmpfname, 'user-agent' => 'Slimstat Analytics/' . self::$version . '; ' . home_url() ) );
|
1264 |
-
|
1265 |
-
if ( is_wp_error( $response ) ) {
|
1266 |
-
unlink( $tmpfname );
|
1267 |
-
return $response;
|
1268 |
-
}
|
1269 |
-
|
1270 |
-
if ( 200 != wp_remote_retrieve_response_code( $response ) ){
|
1271 |
-
unlink( $tmpfname );
|
1272 |
-
return new WP_Error( 'http_404', trim( wp_remote_retrieve_response_message( $response ) ) );
|
1273 |
-
}
|
1274 |
-
|
1275 |
-
return $tmpfname;
|
1276 |
-
}
|
1277 |
-
|
1278 |
-
public static function slimstat_shortcode( $_attributes = '', $_content = '' ) {
|
1279 |
-
extract( shortcode_atts( array(
|
1280 |
-
'f' => '', // recent, popular, count, widget
|
1281 |
-
'w' => '', // column to use (for recent, popular and count) or widget to use
|
1282 |
-
's' => ' ', // separator
|
1283 |
-
'o' => 0 // offset for counters
|
1284 |
-
), $_attributes));
|
1285 |
-
|
1286 |
-
$output = $where = $as_column = '';
|
1287 |
-
$s = "<span class='slimstat-item-separator'>$s</span>";
|
1288 |
-
|
1289 |
-
// Load the localization files (for languages, operating systems, etc)
|
1290 |
-
load_plugin_textdomain( 'wp-slimstat', WP_PLUGIN_DIR .'/wp-slimstat/languages', '/wp-slimstat/languages' );
|
1291 |
-
|
1292 |
-
// Look for required fields
|
1293 |
-
if ( empty( $f ) || empty( $w ) ) {
|
1294 |
-
return '<!-- Slimstat Shortcode Error: missing parameter -->';
|
1295 |
-
}
|
1296 |
-
|
1297 |
-
// Include the Reports Library, but don't initialize the database, since we will do that separately later
|
1298 |
-
include_once( dirname(__FILE__) . '/admin/view/wp-slimstat-reports.php' );
|
1299 |
-
wp_slimstat_reports::init();
|
1300 |
-
|
1301 |
-
// Init the database library with the appropriate filters
|
1302 |
-
if ( strpos ( $_content, 'WHERE:' ) !== false ) {
|
1303 |
-
$where = html_entity_decode( str_replace( 'WHERE:', '', $_content ), ENT_QUOTES, 'UTF-8' );
|
1304 |
-
// wp_slimstat_db::init();
|
1305 |
-
}
|
1306 |
-
else{
|
1307 |
-
wp_slimstat_db::init( html_entity_decode( $_content, ENT_QUOTES, 'UTF-8' ) );
|
1308 |
-
}
|
1309 |
-
|
1310 |
-
switch( $f ) {
|
1311 |
-
case 'count':
|
1312 |
-
case 'count-all':
|
1313 |
-
$output = wp_slimstat_db::count_records( $w, $where, strpos( $f, 'all') === false ) + $o;
|
1314 |
-
break;
|
1315 |
-
|
1316 |
-
case 'widget':
|
1317 |
-
if ( empty( wp_slimstat_reports::$reports_info[ $w ] ) ) {
|
1318 |
-
return __( 'Undefined report ID', 'wp-slimstat' );
|
1319 |
-
}
|
1320 |
-
|
1321 |
-
wp_register_style( 'wp-slimstat-frontend', plugins_url( '/admin/css/slimstat.frontend.css', __FILE__ ) );
|
1322 |
-
wp_enqueue_style( 'wp-slimstat-frontend' );
|
1323 |
-
|
1324 |
-
ob_start();
|
1325 |
-
echo wp_slimstat_reports::report_header( $w );
|
1326 |
-
call_user_func( wp_slimstat_reports::$reports_info[ $w ][ 'callback' ], wp_slimstat_reports::$reports_info[ $w ][ 'callback_args' ] );
|
1327 |
-
wp_slimstat_reports::report_footer();
|
1328 |
-
$output = ob_get_contents();
|
1329 |
-
ob_end_clean();
|
1330 |
-
break;
|
1331 |
-
|
1332 |
-
case 'recent':
|
1333 |
-
case 'recent-all':
|
1334 |
-
case 'top':
|
1335 |
-
case 'top-all':
|
1336 |
-
$function = 'get_' . str_replace( '-all', '', $f );
|
1337 |
-
|
1338 |
-
if ( $w == '*' ) {
|
1339 |
-
$w = 'id';
|
1340 |
-
}
|
1341 |
-
|
1342 |
-
$w = self::string_to_array( $w );
|
1343 |
-
|
1344 |
-
// Some columns are 'special' and need be removed from the list
|
1345 |
-
$w_clean = array_diff( $w, array( 'count', 'display_name', 'hostname', 'post_link', 'post_link_no_qs', 'dt' ) );
|
1346 |
-
|
1347 |
-
// The special value 'display_name' requires the username to be retrieved
|
1348 |
-
if ( in_array( 'display_name', $w ) ) {
|
1349 |
-
$w_clean[] = 'username';
|
1350 |
-
}
|
1351 |
-
|
1352 |
-
// The special value 'post_list' requires the resource to be retrieved
|
1353 |
-
if ( in_array( 'post_link', $w ) ) {
|
1354 |
-
$w_clean[] = 'resource';
|
1355 |
-
}
|
1356 |
-
|
1357 |
-
// The special value 'post_list_no_qs' requires a substring to be calculated
|
1358 |
-
if ( in_array( 'post_link_no_qs', $w ) ) {
|
1359 |
-
$w_clean = array( 'SUBSTRING_INDEX( resource, "' . ( !get_option( 'permalink_structure' ) ? '&' : '?' ) . '", 1 )' );
|
1360 |
-
$as_column = 'resource_calculated';
|
1361 |
-
}
|
1362 |
-
|
1363 |
-
// Retrieve the data
|
1364 |
-
$results = wp_slimstat_db::$function( implode( ', ', $w_clean ), $where, '', strpos( $f, 'all' ) === false, $as_column );
|
1365 |
-
|
1366 |
-
// No data? No problem!
|
1367 |
-
if ( empty( $results ) ) {
|
1368 |
-
return '<!-- Slimstat Shortcode: No Data -->';
|
1369 |
-
}
|
1370 |
-
|
1371 |
-
// Are nice permalinks enabled?
|
1372 |
-
$permalinks_enabled = get_option( 'permalink_structure' );
|
1373 |
-
|
1374 |
-
// Format results
|
1375 |
-
$output = array();
|
1376 |
-
foreach( $results as $result_idx => $a_result ) {
|
1377 |
-
foreach( $w as $a_column ) {
|
1378 |
-
$output[ $result_idx ][ $a_column ] = "<span class='col-$a_column'>";
|
1379 |
-
|
1380 |
-
switch( $a_column ) {
|
1381 |
-
case 'count':
|
1382 |
-
$output[ $result_idx ][ $a_column ] .= $a_result[ 'counthits' ];
|
1383 |
-
break;
|
1384 |
-
|
1385 |
-
case 'country':
|
1386 |
-
$output[ $result_idx ][ $a_column ] .= __( 'c-' . $a_result[ $a_column ], 'wp-slimstat' );
|
1387 |
-
break;
|
1388 |
-
|
1389 |
-
case 'display_name':
|
1390 |
-
$user_details = get_user_by( 'login', $a_result[ 'username' ] );
|
1391 |
-
if ( !empty( $user_details ) ) {
|
1392 |
-
$output[ $result_idx ][ $a_column ] .= $user_details->display_name;
|
1393 |
-
}
|
1394 |
-
else {
|
1395 |
-
$output[ $result_idx ][ $a_column ] .= $a_result[ 'username' ];
|
1396 |
-
}
|
1397 |
-
|
1398 |
-
break;
|
1399 |
-
|
1400 |
-
case 'dt':
|
1401 |
-
$output[ $result_idx ][ $a_column ] .= date_i18n( self::$settings[ 'date_format' ] . ' ' . self::$settings[ 'time_format' ], $a_result[ 'dt' ] );
|
1402 |
-
break;
|
1403 |
-
|
1404 |
-
case 'hostname':
|
1405 |
-
$output[ $result_idx ][ $a_column ] .= gethostbyaddr( $a_result[ 'ip' ] );
|
1406 |
-
break;
|
1407 |
-
|
1408 |
-
case 'language':
|
1409 |
-
$output[ $result_idx ][ $a_column ] .= __( 'l-' . $a_result[ $a_column ], 'wp-slimstat' );
|
1410 |
-
break;
|
1411 |
-
|
1412 |
-
case 'platform':
|
1413 |
-
$output[ $result_idx ][ $a_column ] .= __( $a_result[ $a_column ], 'wp-slimstat' );
|
1414 |
-
break;
|
1415 |
-
|
1416 |
-
case 'post_link':
|
1417 |
-
case 'post_link_no_qs':
|
1418 |
-
$resource_key = ( $a_column == 'post_link' ) ? 'resource' : 'resource_calculated';
|
1419 |
-
$post_id = url_to_postid( $a_result[ $resource_key ] );
|
1420 |
-
if ( $post_id > 0 ) {
|
1421 |
-
$output[ $result_idx ][ $a_column ] .= "<a href='{$a_result[ $resource_key ]}'>" . get_the_title( $post_id ) . '</a>';
|
1422 |
-
}
|
1423 |
-
else {
|
1424 |
-
$output[ $result_idx ][ $a_column ] .= "<a href='{$a_result[ $resource_key ]}'>{$a_result[ $resource_key ]}</a>";
|
1425 |
-
}
|
1426 |
-
break;
|
1427 |
-
|
1428 |
-
default:
|
1429 |
-
$output[ $result_idx ][ $a_column ] .= $a_result[ $a_column ];
|
1430 |
-
break;
|
1431 |
-
}
|
1432 |
-
$output[ $result_idx ][ $a_column ] .= '</span>';
|
1433 |
-
}
|
1434 |
-
$output[ $result_idx ] = '<li>' . implode( $s, $output[ $result_idx ] ). '</li>';
|
1435 |
-
}
|
1436 |
-
|
1437 |
-
$output = '<ul class="slimstat-shortcode ' . $f . implode( '-', $w ). '">' . implode( '', $output ) . '</ul>';
|
1438 |
-
break;
|
1439 |
-
|
1440 |
-
default:
|
1441 |
-
break;
|
1442 |
-
}
|
1443 |
-
|
1444 |
-
return $output;
|
1445 |
-
}
|
1446 |
-
|
1447 |
-
public static function rest_api_response( $_request = array() ) {
|
1448 |
-
$filters = '';
|
1449 |
-
if ( !empty( $_request[ 'filters' ] ) ) {
|
1450 |
-
$filters = $_request[ 'filters' ];
|
1451 |
-
}
|
1452 |
-
|
1453 |
-
if ( empty( $_request[ 'dimension' ] ) ) {
|
1454 |
-
return new WP_Error( 'rest_invalid', esc_html__( 'The dimension parameter is required. Please review your request and try again.', 'wp-slimstat' ), array( 'status' => 400 ) );
|
1455 |
-
}
|
1456 |
-
|
1457 |
-
if ( empty( $_request[ 'function' ] ) ) {
|
1458 |
-
return new WP_Error( 'rest_invalid', esc_html__( 'The function parameter is required. Please review your request and try again.', 'wp-slimstat' ), array( 'status' => 400 ) );
|
1459 |
-
}
|
1460 |
-
|
1461 |
-
include_once( dirname(__FILE__) . '/admin/view/wp-slimstat-db.php' );
|
1462 |
-
wp_slimstat_db::init( $filters );
|
1463 |
-
|
1464 |
-
$response = array(
|
1465 |
-
'function' => htmlentities( $_request[ 'function' ], ENT_QUOTES, 'UTF-8' ),
|
1466 |
-
'dimension' => htmlentities( $_request[ 'dimension' ], ENT_QUOTES, 'UTF-8' ),
|
1467 |
-
|
1468 |
-
'data' => 0
|
1469 |
-
);
|
1470 |
-
|
1471 |
-
switch( $_request[ 'function' ] ) {
|
1472 |
-
case 'count':
|
1473 |
-
case 'count-all':
|
1474 |
-
$response[ 'data' ] = wp_slimstat_db::count_records( $_request[ 'dimension' ], '', strpos( $_request[ 'function' ], '-all') === false );
|
1475 |
-
break;
|
1476 |
-
|
1477 |
-
case 'recent':
|
1478 |
-
case 'recent-all':
|
1479 |
-
case 'top':
|
1480 |
-
case 'top-all':
|
1481 |
-
$function = 'get_' . str_replace( '-all', '', $_request[ 'function' ] );
|
1482 |
-
|
1483 |
-
// Retrieve the data
|
1484 |
-
$response[ 'data' ] = array_values( wp_slimstat_db::$function( $_request[ 'dimension' ], '', '', strpos( $_request[ 'function' ], '-all' ) === false ) );
|
1485 |
-
break;
|
1486 |
-
|
1487 |
-
default:
|
1488 |
-
// This should never happen, because of the 'enum' condition for this parameter. But never say never...
|
1489 |
-
$response[ 'data' ] = new WP_Error( 'rest_invalid', esc_html__( 'Valid function values are count, count-all, recent, recent-all, top and top-all. Please review your request and try again.', 'wp-slimstat' ), array( 'status' => 400 ) );
|
1490 |
-
break;
|
1491 |
-
}
|
1492 |
-
|
1493 |
-
return rest_ensure_response( $response );
|
1494 |
-
}
|
1495 |
-
|
1496 |
-
public static function rest_api_authorization( $_request = array() ) {
|
1497 |
-
if ( empty( $_request[ 'token' ] ) ) {
|
1498 |
-
return new WP_Error( 'rest_invalid', esc_html__( 'Please specify a valid token in order to access this REST API.', 'wp-slimstat' ), array( 'status' => 400 ) );
|
1499 |
-
}
|
1500 |
-
|
1501 |
-
if ( !in_array( $_request[ 'token' ], self::string_to_array( self::$settings['rest_api_tokens'] ) ) ) {
|
1502 |
-
return false;
|
1503 |
-
}
|
1504 |
-
|
1505 |
-
return true;
|
1506 |
-
}
|
1507 |
-
|
1508 |
-
public static function register_rest_route() {
|
1509 |
-
register_rest_route( 'slimstat/v1', '/get', array(
|
1510 |
-
'methods' => WP_REST_Server::READABLE,
|
1511 |
-
'callback' => array( __CLASS__, 'rest_api_response' ),
|
1512 |
-
'permission_callback' => array( __CLASS__, 'rest_api_authorization' ),
|
1513 |
-
'args' => array(
|
1514 |
-
'token' => array(
|
1515 |
-
'description' => __( 'You will need to specify a valid token to be able to query the data. Tokens are defined in Slimstat > Settings > Access Control.', 'wp-slimstat' ),
|
1516 |
-
'type' => 'string'
|
1517 |
-
),
|
1518 |
-
'function' => array(
|
1519 |
-
'description' => __( 'This parameter specifies the type of QUERY for the dimension. Valid values are: count, count-all, recent, recent-all, top and top-all.', 'wp-slimstat' ),
|
1520 |
-
'type' => 'string',
|
1521 |
-
'enum' => array( 'count', 'count-all', 'recent', 'recent-all', 'top', 'top-all' )
|
1522 |
-
),
|
1523 |
-
'dimension' => array(
|
1524 |
-
'description' => __( 'This parameter indicates what dimension to return: * (all data), ip, resource, browser, operating system, etc. You can only specify one dimension at a time.', 'wp-slimstat' ),
|
1525 |
-
'type' => 'string',
|
1526 |
-
'enum' => array( '*', 'id', 'ip', 'username', 'country', 'referer', 'resource', 'searchterms', 'browser', 'platform', 'language', 'resolution', 'content_type', 'content_id', 'outbound_resource' )
|
1527 |
-
),
|
1528 |
-
'filters' => array(
|
1529 |
-
'description' => __( 'This parameter is used to filter a given dimension (resources, browsers, operating systems, etc) so that it satisfies certain conditions (i.e.: browser contains Chrome). Please make sure to urlencode this value, and to use the usual filter format: browser contains Chrome&&&referer contains slim (encoded: browser%20contains%20Chrome%26%26%26referer%20contains%20slim)', 'wp-slimstat' ),
|
1530 |
-
'type' => 'string'
|
1531 |
-
)
|
1532 |
-
)
|
1533 |
-
) );
|
1534 |
-
}
|
1535 |
-
|
1536 |
-
/**
|
1537 |
-
* Converts a series of comma separated values into an array
|
1538 |
-
*/
|
1539 |
-
public static function string_to_array( $_option = '' ) {
|
1540 |
-
if ( empty( $_option ) || !is_string( $_option ) ) {
|
1541 |
-
return array();
|
1542 |
-
}
|
1543 |
-
else {
|
1544 |
-
return array_filter( array_map( 'trim', explode( ',', $_option ) ) );
|
1545 |
-
}
|
1546 |
-
}
|
1547 |
-
|
1548 |
-
/**
|
1549 |
-
* Toggles WordPress filters on date_i18n function
|
1550 |
-
*/
|
1551 |
-
public static function toggle_date_i18n_filters( $_turn_on = true ) {
|
1552 |
-
if ( $_turn_on && !empty( self::$date_i18n_filters ) && is_array( self::$date_i18n_filters ) ) {
|
1553 |
-
foreach ( self::$date_i18n_filters as $i18n_priority => $i18n_func_list ) {
|
1554 |
-
foreach ( $i18n_func_list as $func_name => $func_args ) {
|
1555 |
-
if ( !empty( $func_args[ 'function' ] ) && is_string( $func_args[ 'function' ] ) ) {
|
1556 |
-
add_filter( 'date_i8n', $func_args[ 'function' ], $i18n_priority, intval( $func_args[ 'accepted_args' ] ) );
|
1557 |
-
}
|
1558 |
-
}
|
1559 |
-
}
|
1560 |
-
}
|
1561 |
-
else if ( !empty( $GLOBALS[ 'wp_filter' ][ 'date_i18n' ][ 'callbacks' ] ) && is_array( $GLOBALS[ 'wp_filter' ][ 'date_i18n' ][ 'callbacks' ] ) ) {
|
1562 |
-
self::$date_i18n_filters = $GLOBALS[ 'wp_filter' ][ 'date_i18n' ][ 'callbacks' ];
|
1563 |
-
remove_all_filters( 'date_i18n' );
|
1564 |
-
}
|
1565 |
-
}
|
1566 |
-
|
1567 |
-
/**
|
1568 |
-
* Imports all the 'old' options into the new array, and saves them
|
1569 |
-
*/
|
1570 |
-
public static function init_options(){
|
1571 |
-
return array(
|
1572 |
-
'version' => self::$version,
|
1573 |
-
'secret' => wp_hash( uniqid( time(), true ) ),
|
1574 |
-
'show_admin_notice' => 0,
|
1575 |
-
'browscap_last_modified' => 0,
|
1576 |
-
|
1577 |
-
// General
|
1578 |
-
'is_tracking' => 'on',
|
1579 |
-
'javascript_mode' => 'on',
|
1580 |
-
'enable_javascript' => 'on',
|
1581 |
-
'track_admin_pages' => 'no',
|
1582 |
-
'use_separate_menu' => 'on',
|
1583 |
-
'add_posts_column' => 'no',
|
1584 |
-
'posts_column_day_interval' => 30,
|
1585 |
-
'posts_column_pageviews' => 'on',
|
1586 |
-
'add_dashboard_widgets' => 'on',
|
1587 |
-
'hide_addons' => 'no',
|
1588 |
-
'auto_purge' => 0,
|
1589 |
-
'auto_purge_delete' => 'on',
|
1590 |
-
|
1591 |
-
// Tracker
|
1592 |
-
'do_not_track_outbound_classes_rel_href' => 'noslimstat,ab-item',
|
1593 |
-
'extensions_to_track' => 'pdf,doc,xls,zip',
|
1594 |
-
'track_same_domain_referers' => 'on',
|
1595 |
-
'geolocation_country' => 'on',
|
1596 |
-
'session_duration' => 1800,
|
1597 |
-
'extend_session' => 'no',
|
1598 |
-
'set_tracker_cookie' => 'on',
|
1599 |
-
'enable_cdn' => 'on',
|
1600 |
-
'ajax_relative_path' => 'no',
|
1601 |
-
'external_domains' => '',
|
1602 |
-
|
1603 |
-
// Filters
|
1604 |
-
'track_users' => 'on',
|
1605 |
-
'ignore_spammers' => 'on',
|
1606 |
-
'ignore_bots' => 'no',
|
1607 |
-
'ignore_prefetch' => 'on',
|
1608 |
-
'anonymize_ip' => 'no',
|
1609 |
-
|
1610 |
-
'ignore_users' => '',
|
1611 |
-
'ignore_ip' => '',
|
1612 |
-
'ignore_countries' => '',
|
1613 |
-
'ignore_browsers' => '',
|
1614 |
-
'ignore_platforms' => '',
|
1615 |
-
'ignore_capabilities' => '',
|
1616 |
-
|
1617 |
-
'ignore_resources' => '',
|
1618 |
-
'ignore_referers' => '',
|
1619 |
-
'ignore_content_types' => '',
|
1620 |
-
|
1621 |
-
// Reports
|
1622 |
-
'use_european_separators' => 'on',
|
1623 |
-
'date_format' => 'm-d-y',
|
1624 |
-
'time_format' => 'h:i a',
|
1625 |
-
'show_display_name' => 'no',
|
1626 |
-
'convert_resource_urls_to_titles' => 'on',
|
1627 |
-
'convert_ip_addresses' => 'no',
|
1628 |
-
'async_load' => 'no',
|
1629 |
-
'use_current_month_timespan' => 'no',
|
1630 |
-
'expand_details' => 'no',
|
1631 |
-
'rows_to_show' => '20',
|
1632 |
-
'limit_results' => '1000',
|
1633 |
-
'ip_lookup_service' => 'http://www.infosniper.net/?ip_address=',
|
1634 |
-
'mozcom_access_id' => '',
|
1635 |
-
'mozcom_secret_key' => '',
|
1636 |
-
'refresh_interval' => '60',
|
1637 |
-
'number_results_raw_data' => '50',
|
1638 |
-
'max_dots_on_map' => '50',
|
1639 |
-
'custom_css' => '',
|
1640 |
-
'chart_colors' => '',
|
1641 |
-
'
|
1642 |
-
'
|
1643 |
-
|
1644 |
-
|
1645 |
-
|
1646 |
-
'
|
1647 |
-
'
|
1648 |
-
'
|
1649 |
-
'
|
1650 |
-
'
|
1651 |
-
|
1652 |
-
|
1653 |
-
|
1654 |
-
'
|
1655 |
-
'
|
1656 |
-
'
|
1657 |
-
|
1658 |
-
|
1659 |
-
|
1660 |
-
|
1661 |
-
|
1662 |
-
|
1663 |
-
|
1664 |
-
|
1665 |
-
|
1666 |
-
|
1667 |
-
|
1668 |
-
|
1669 |
-
|
1670 |
-
|
1671 |
-
|
1672 |
-
|
1673 |
-
|
1674 |
-
|
1675 |
-
|
1676 |
-
|
1677 |
-
|
1678 |
-
|
1679 |
-
|
1680 |
-
|
1681 |
-
|
1682 |
-
|
1683 |
-
|
1684 |
-
|
1685 |
-
|
1686 |
-
|
1687 |
-
|
1688 |
-
|
1689 |
-
|
1690 |
-
|
1691 |
-
|
1692 |
-
|
1693 |
-
|
1694 |
-
|
1695 |
-
|
1696 |
-
|
1697 |
-
|
1698 |
-
|
1699 |
-
|
1700 |
-
|
1701 |
-
|
1702 |
-
|
1703 |
-
|
1704 |
-
|
1705 |
-
|
1706 |
-
|
1707 |
-
|
1708 |
-
|
1709 |
-
|
1710 |
-
|
1711 |
-
|
1712 |
-
|
1713 |
-
|
1714 |
-
if
|
1715 |
-
|
1716 |
-
|
1717 |
-
|
1718 |
-
|
1719 |
-
|
1720 |
-
|
1721 |
-
|
1722 |
-
|
1723 |
-
|
1724 |
-
|
1725 |
-
|
1726 |
-
|
1727 |
-
|
1728 |
-
|
1729 |
-
|
1730 |
-
|
1731 |
-
|
1732 |
-
|
1733 |
-
$
|
1734 |
-
|
1735 |
-
|
1736 |
-
|
1737 |
-
|
1738 |
-
|
1739 |
-
|
1740 |
-
|
1741 |
-
|
1742 |
-
|
1743 |
-
|
1744 |
-
|
1745 |
-
|
1746 |
-
|
1747 |
-
|
1748 |
-
|
1749 |
-
|
1750 |
-
|
1751 |
-
|
1752 |
-
|
1753 |
-
|
1754 |
-
|
1755 |
-
|
1756 |
-
|
1757 |
-
|
1758 |
-
|
1759 |
-
|
1760 |
-
|
1761 |
-
|
1762 |
-
|
1763 |
-
|
1764 |
-
|
1765 |
-
|
1766 |
-
|
1767 |
-
|
1768 |
-
|
1769 |
-
|
1770 |
-
|
1771 |
-
|
1772 |
-
|
1773 |
-
|
1774 |
-
|
1775 |
-
|
1776 |
-
|
1777 |
-
|
1778 |
-
|
1779 |
-
|
1780 |
-
|
1781 |
-
|
1782 |
-
|
1783 |
-
|
1784 |
-
|
1785 |
-
|
1786 |
-
|
1787 |
-
|
1788 |
-
|
1789 |
-
self::$wpdb->query("DELETE
|
1790 |
-
|
1791 |
-
|
1792 |
-
|
1793 |
-
|
1794 |
-
self::$wpdb->query( "OPTIMIZE TABLE {$GLOBALS[ 'wpdb' ]->prefix}
|
1795 |
-
self::$wpdb->query( "OPTIMIZE TABLE {$GLOBALS[ 'wpdb' ]->prefix}
|
1796 |
-
self::$wpdb->query( "OPTIMIZE TABLE {$GLOBALS[ 'wpdb' ]->prefix}
|
1797 |
-
|
1798 |
-
|
1799 |
-
|
1800 |
-
|
1801 |
-
|
1802 |
-
|
1803 |
-
|
1804 |
-
|
1805 |
-
|
1806 |
-
|
1807 |
-
|
1808 |
-
|
1809 |
-
|
1810 |
-
|
1811 |
-
|
1812 |
-
|
1813 |
-
|
1814 |
-
|
1815 |
-
|
1816 |
-
|
1817 |
-
|
1818 |
-
|
1819 |
-
|
1820 |
-
|
1821 |
-
|
1822 |
-
|
1823 |
-
|
1824 |
-
|
1825 |
-
|
1826 |
-
|
1827 |
-
|
1828 |
-
|
1829 |
-
|
1830 |
-
|
1831 |
-
$
|
1832 |
-
|
1833 |
-
|
1834 |
-
|
1835 |
-
|
1836 |
-
|
1837 |
-
|
1838 |
-
|
1839 |
-
|
1840 |
-
|
1841 |
-
|
1842 |
-
|
1843 |
-
|
1844 |
-
|
1845 |
-
|
1846 |
-
|
1847 |
-
|
1848 |
-
|
1849 |
-
}
|
1850 |
-
|
1851 |
-
|
1852 |
-
|
1853 |
-
|
1854 |
-
|
1855 |
-
|
1856 |
-
|
1857 |
-
|
1858 |
-
|
1859 |
-
|
1860 |
-
'
|
1861 |
-
|
1862 |
-
|
1863 |
-
|
1864 |
-
|
1865 |
-
|
1866 |
-
*
|
1867 |
-
*
|
1868 |
-
* @param array $
|
1869 |
-
|
1870 |
-
|
1871 |
-
|
1872 |
-
|
1873 |
-
|
1874 |
-
|
1875 |
-
|
1876 |
-
|
1877 |
-
|
1878 |
-
|
1879 |
-
|
1880 |
-
|
1881 |
-
|
1882 |
-
|
1883 |
-
|
1884 |
-
|
1885 |
-
*
|
1886 |
-
*
|
1887 |
-
|
1888 |
-
|
1889 |
-
|
1890 |
-
|
1891 |
-
|
1892 |
-
|
1893 |
-
$
|
1894 |
-
$
|
1895 |
-
|
1896 |
-
|
1897 |
-
|
1898 |
-
|
1899 |
-
|
1900 |
-
|
1901 |
-
|
1902 |
-
<
|
1903 |
-
<
|
1904 |
-
|
1905 |
-
|
1906 |
-
|
1907 |
-
</
|
1908 |
-
|
1909 |
-
|
1910 |
-
<
|
1911 |
-
<
|
1912 |
-
<
|
1913 |
-
|
1914 |
-
|
1915 |
-
|
1916 |
-
|
1917 |
-
|
1918 |
-
|
1919 |
-
*
|
1920 |
-
*
|
1921 |
-
* @param array $
|
1922 |
-
|
1923 |
-
|
1924 |
-
|
1925 |
-
|
1926 |
-
|
1927 |
-
$instance[ '
|
1928 |
-
|
1929 |
-
|
1930 |
-
}
|
1931 |
-
|
1932 |
-
|
1933 |
-
|
1934 |
-
|
1935 |
-
|
1936 |
-
|
1937 |
-
|
1938 |
-
|
1939 |
-
|
1940 |
-
|
1941 |
-
|
1942 |
-
|
1943 |
-
|
1944 |
-
|
1945 |
-
|
1946 |
-
|
1947 |
-
|
1948 |
-
|
1949 |
-
|
1950 |
-
|
1951 |
-
|
1952 |
-
add_action( '
|
1953 |
-
|
1954 |
-
|
1955 |
-
|
1956 |
-
|
1957 |
-
|
1958 |
-
|
1959 |
-
|
1960 |
-
|
1961 |
-
|
1962 |
-
|
1963 |
-
|
1964 |
-
|
1965 |
-
|
1966 |
-
|
|
1 |
+
<?php
|
2 |
+
/*
|
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
|
7 |
+
Author: Jason Crouse
|
8 |
+
Author URI: http://www.wp-slimstat.com/
|
9 |
+
Text Domain: wp-slimstat
|
10 |
+
Domain Path: /languages
|
11 |
+
*/
|
12 |
+
|
13 |
+
if ( !empty( wp_slimstat::$settings ) ) {
|
14 |
+
return true;
|
15 |
+
}
|
16 |
+
|
17 |
+
class wp_slimstat {
|
18 |
+
public static $version = '4.7.7';
|
19 |
+
public static $settings = array();
|
20 |
+
|
21 |
+
public static $wpdb = '';
|
22 |
+
public static $upload_dir = '';
|
23 |
+
public static $maxmind_path = '';
|
24 |
+
|
25 |
+
public static $update_checker = array();
|
26 |
+
public static $raw_post_array = array();
|
27 |
+
|
28 |
+
protected static $data_js = array( 'id' => 0 );
|
29 |
+
protected static $stat = array();
|
30 |
+
protected static $settings_signature = '';
|
31 |
+
protected static $browser = array();
|
32 |
+
protected static $heuristic_key = 0;
|
33 |
+
protected static $date_i18n_filters = array();
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Initializes variables and actions
|
37 |
+
*/
|
38 |
+
public static function init() {
|
39 |
+
|
40 |
+
// Load all the settings
|
41 |
+
if ( is_network_admin() && ( empty($_GET[ 'page' ] ) || strpos( $_GET[ 'page' ], 'slimview' ) === false ) ) {
|
42 |
+
self::$settings = get_site_option( 'slimstat_options', array() );
|
43 |
+
}
|
44 |
+
else {
|
45 |
+
self::$settings = get_option( 'slimstat_options', array() );
|
46 |
+
}
|
47 |
+
|
48 |
+
self::$settings = array_merge( self::init_options(), self::$settings );
|
49 |
+
|
50 |
+
// Allow third party tools to edit the options
|
51 |
+
self::$settings = apply_filters( 'slimstat_init_options', self::$settings );
|
52 |
+
|
53 |
+
// Determine the options' signature: if it hasn't changed, there's no need to update/save them in the database
|
54 |
+
self::$settings_signature = md5( serialize( self::$settings ) );
|
55 |
+
|
56 |
+
// Allow third-party tools to use a custom database for Slimstat
|
57 |
+
self::$wpdb = apply_filters( 'slimstat_custom_wpdb', $GLOBALS[ 'wpdb' ] );
|
58 |
+
|
59 |
+
// Hook a DB clean-up routine to the daily cronjob
|
60 |
+
add_action( 'wp_slimstat_purge', array( __CLASS__, 'wp_slimstat_purge' ) );
|
61 |
+
|
62 |
+
// Allow external domains on CORS requests
|
63 |
+
add_filter( 'allowed_http_origins', array(__CLASS__, 'open_cors_admin_ajax' ) );
|
64 |
+
|
65 |
+
// Define the folder where to store the geolocation database (shared among sites in a network, by default)
|
66 |
+
self::$upload_dir = wp_upload_dir();
|
67 |
+
self::$upload_dir = self::$upload_dir[ 'basedir' ];
|
68 |
+
if ( is_multisite() && ! ( is_main_network() && is_main_site() && defined( 'MULTISITE' ) ) ) {
|
69 |
+
self::$upload_dir = str_replace( '/sites/' . get_current_blog_id(), '', self::$upload_dir );
|
70 |
+
}
|
71 |
+
self::$upload_dir .= '/wp-slimstat';
|
72 |
+
self::$upload_dir = apply_filters( 'slimstat_maxmind_path', self::$upload_dir );
|
73 |
+
|
74 |
+
self::$maxmind_path = self::$upload_dir . '/maxmind.mmdb';
|
75 |
+
|
76 |
+
// Enable the tracker (both server- and client-side)
|
77 |
+
if ( !is_admin() || self::$settings[ 'track_admin_pages' ] == 'on' ) {
|
78 |
+
|
79 |
+
// Allow add-ons to turn off the tracker based on other conditions
|
80 |
+
$is_tracking_filter = apply_filters( 'slimstat_filter_pre_tracking', strpos( self::get_request_uri(), 'wp-admin/admin-ajax.php' ) === false );
|
81 |
+
$is_tracking_filter_js = apply_filters( 'slimstat_filter_pre_tracking_js', true );
|
82 |
+
|
83 |
+
// Is server-side tracking active?
|
84 |
+
if ( self::$settings[ 'javascript_mode' ] != 'on' && self::$settings[ 'is_tracking' ] == 'on' && $is_tracking_filter ) {
|
85 |
+
add_action( is_admin() ? 'admin_init' : 'wp', array( __CLASS__, 'slimtrack' ), 5 );
|
86 |
+
|
87 |
+
if ( self::$settings[ 'track_users' ] == 'on' ) {
|
88 |
+
add_action( 'login_init', array( __CLASS__, 'slimtrack' ), 10 );
|
89 |
+
}
|
90 |
+
}
|
91 |
+
|
92 |
+
// Slimstat tracks screen resolutions, outbound links and other client-side information using a client-side tracker
|
93 |
+
add_action( is_admin() ? 'admin_enqueue_scripts' : 'wp_enqueue_scripts' , array( __CLASS__, 'wp_slimstat_enqueue_tracking_script' ), 15 );
|
94 |
+
if ( self::$settings[ 'track_users' ] == 'on' ) {
|
95 |
+
add_action( 'login_enqueue_scripts', array( __CLASS__, 'wp_slimstat_enqueue_tracking_script' ), 10 );
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
// Shortcodes
|
100 |
+
add_shortcode('slimstat', array(__CLASS__, 'slimstat_shortcode'), 15);
|
101 |
+
|
102 |
+
// Load the admin library
|
103 |
+
if ( is_user_logged_in() ) {
|
104 |
+
include_once ( plugin_dir_path( __FILE__ ) . 'admin/wp-slimstat-admin.php' );
|
105 |
+
add_action( 'init', array( 'wp_slimstat_admin', 'init' ), 60 );
|
106 |
+
}
|
107 |
+
|
108 |
+
// Include our browser detector library
|
109 |
+
include_once( plugin_dir_path( __FILE__ ) . 'browscap/browser.php' );
|
110 |
+
add_action( 'init', array( 'slim_browser', 'init' ) );
|
111 |
+
|
112 |
+
// If add-ons are installed, check for updates
|
113 |
+
add_action( 'wp_loaded', array( __CLASS__, 'update_checker' ) );
|
114 |
+
|
115 |
+
// Update the options before shutting down
|
116 |
+
add_action( 'shutdown', array( __CLASS__, 'slimstat_save_options' ), 100 );
|
117 |
+
|
118 |
+
// REST API Support
|
119 |
+
add_action( 'rest_api_init', array( __CLASS__, 'register_rest_route' ) );
|
120 |
+
}
|
121 |
+
// end init
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Ajax Tracking
|
125 |
+
*/
|
126 |
+
public static function slimtrack_ajax() {
|
127 |
+
// If the website is using a caching plugin, the tracking code might still be there, even if the user turned off tracking
|
128 |
+
if ( self::$settings[ 'is_tracking' ] != 'on' ) {
|
129 |
+
self::$stat[ 'id' ] = -204;
|
130 |
+
self::_set_error_array( __( 'Tracker is turned off, but client-side tracking code is still running.', 'wp-slimstat' ), true );
|
131 |
+
self::slimstat_save_options();
|
132 |
+
exit( self::_get_id_with_checksum( self::$stat[ 'id' ] ) );
|
133 |
+
}
|
134 |
+
|
135 |
+
// This function also initializes self::$data_js and removes the checksum from self::$data_js['id']
|
136 |
+
self::_check_data_integrity( self::$raw_post_array );
|
137 |
+
|
138 |
+
// Is this a request to record a new pageview?
|
139 |
+
if ( self::$data_js[ 'op' ] == 'add' || self::$data_js[ 'op' ] == 'update' ) {
|
140 |
+
|
141 |
+
// Track client-side information (screen resolution, plugins, etc)
|
142 |
+
if ( !empty( self::$data_js[ 'bw' ] ) ) {
|
143 |
+
self::$stat[ 'resolution' ] = strip_tags( trim( self::$data_js[ 'bw' ] . 'x' . self::$data_js[ 'bh' ] ) );
|
144 |
+
}
|
145 |
+
if ( !empty( self::$data_js[ 'sw' ] ) ) {
|
146 |
+
self::$stat[ 'screen_width' ] = intval( self::$data_js[ 'sw' ] );
|
147 |
+
}
|
148 |
+
if ( !empty( self::$data_js[ 'sh' ] ) ) {
|
149 |
+
self::$stat[ 'screen_height' ] = intval( self::$data_js[ 'sh' ] );
|
150 |
+
}
|
151 |
+
if ( !empty( self::$data_js[ 'pl' ] ) ) {
|
152 |
+
self::$stat[ 'plugins' ] = strip_tags( trim( self::$data_js[ 'pl' ] ) );
|
153 |
+
}
|
154 |
+
if ( !empty( self::$data_js[ 'sl' ] ) && self::$data_js[ 'sl' ] > 0 && self::$data_js[ 'sl' ] < 60000 ) {
|
155 |
+
self::$stat[ 'server_latency' ] = intval( self::$data_js[ 'sl' ] );
|
156 |
+
}
|
157 |
+
if ( !empty( self::$data_js[ 'pp' ] ) && self::$data_js[ 'pp' ] > 0 && self::$data_js[ 'pp' ] < 60000 ) {
|
158 |
+
self::$stat[ 'page_performance' ] = intval( self::$data_js[ 'pp' ] );
|
159 |
+
}
|
160 |
+
}
|
161 |
+
|
162 |
+
if ( self::$data_js[ 'op' ] == 'add' ) {
|
163 |
+
self::slimtrack();
|
164 |
+
}
|
165 |
+
else if ( self::$data_js[ 'op' ] == 'update' ) {
|
166 |
+
// Update an existing pageview with client-based information (resolution, plugins installed, etc)
|
167 |
+
self::_set_visit_id( true );
|
168 |
+
|
169 |
+
// ID of the pageview to update
|
170 |
+
self::$stat[ 'id' ] = abs( intval( self::$data_js[ 'id' ] ) );
|
171 |
+
|
172 |
+
// Visitor is still on this page, record the timestamp in the corresponding field
|
173 |
+
self::toggle_date_i18n_filters( false );
|
174 |
+
self::$stat['dt_out'] = date_i18n( 'U' );
|
175 |
+
self::toggle_date_i18n_filters( true );
|
176 |
+
|
177 |
+
// Are we tracking an outbound click?
|
178 |
+
if ( !empty( self::$data_js[ 'res' ] ) ) {
|
179 |
+
$outbound_resource = strip_tags( trim( base64_decode( self::$data_js[ 'res' ] ) ) );
|
180 |
+
$outbound_host = parse_url( $outbound_resource, PHP_URL_HOST );
|
181 |
+
$site_host = parse_url( get_site_url(), PHP_URL_HOST );
|
182 |
+
if ( $outbound_host != $site_host ) {
|
183 |
+
$existing_outbound_resource = self::$wpdb->get_var( self::$wpdb->prepare( "
|
184 |
+
SELECT outbound_resource
|
185 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
186 |
+
WHERE id = %d", self::$stat[ 'id' ]
|
187 |
+
) );
|
188 |
+
|
189 |
+
self::$stat[ 'outbound_resource' ] = $outbound_resource;
|
190 |
+
if ( !empty( $existing_outbound_resource ) ) {
|
191 |
+
self::$stat[ 'outbound_resource' ] = $existing_outbound_resource . ';;;' .$outbound_resource;
|
192 |
+
}
|
193 |
+
}
|
194 |
+
}
|
195 |
+
|
196 |
+
self::update_row( self::$stat, $GLOBALS[ 'wpdb' ]->prefix . 'slim_stats' );
|
197 |
+
}
|
198 |
+
|
199 |
+
// Are we tracking events, coordinates and other details?
|
200 |
+
if ( self::$data_js[ 'op' ] == 'event' || !empty( self::$data_js[ 'pos' ] ) ) {
|
201 |
+
self::$stat[ 'id' ] = abs( intval( self::$data_js[ 'id' ] ) );
|
202 |
+
|
203 |
+
self::toggle_date_i18n_filters( false );
|
204 |
+
$event_info = array(
|
205 |
+
'position' => strip_tags( trim( self::$data_js[ 'pos' ] ) ),
|
206 |
+
'id' => self::$stat[ 'id' ],
|
207 |
+
'dt' => date_i18n( 'U' )
|
208 |
+
);
|
209 |
+
self::toggle_date_i18n_filters( true );
|
210 |
+
|
211 |
+
if ( !empty( self::$data_js[ 'ty' ] ) ) {
|
212 |
+
$event_info[ 'type' ] = abs( intval( self::$data_js[ 'ty' ] ) );
|
213 |
+
}
|
214 |
+
if ( !empty( self::$data_js[ 'des' ] ) ) {
|
215 |
+
$event_info[ 'event_description' ] = strip_tags( trim( base64_decode( self::$data_js[ 'des' ] ) ) );
|
216 |
+
}
|
217 |
+
if ( !empty( self::$data_js[ 'no' ] ) ) {
|
218 |
+
$event_info[ 'notes' ] = strip_tags( trim( base64_decode( self::$data_js[ 'no' ] ) ) );
|
219 |
+
}
|
220 |
+
|
221 |
+
self::insert_row( $event_info, $GLOBALS[ 'wpdb' ]->prefix . 'slim_events' );
|
222 |
+
}
|
223 |
+
|
224 |
+
// Was this pageview tracked?
|
225 |
+
if ( self::$stat[ 'id' ] <= 0 ) {
|
226 |
+
$abs_error_code = abs( self::$stat[ 'id' ] );
|
227 |
+
do_action( 'slimstat_track_exit_' . $abs_error_code, self::$stat );
|
228 |
+
self::slimstat_save_options();
|
229 |
+
exit( self::_get_id_with_checksum( self::$stat[ 'id' ] ) );
|
230 |
+
}
|
231 |
+
|
232 |
+
// Send the ID back to Javascript to track future interactions
|
233 |
+
do_action( 'slimstat_track_success' );
|
234 |
+
|
235 |
+
// If we tracked an internal download, we return the original ID, not the new one
|
236 |
+
exit( self::_get_id_with_checksum( self::$stat[ 'id' ] ) );
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Core tracking functionality
|
241 |
+
*/
|
242 |
+
public static function slimtrack( $_argument = '' ) {
|
243 |
+
// If the website is using a caching plugin, the tracking code might still be there, even if the user turned off tracking
|
244 |
+
if ( self::$settings[ 'is_tracking' ] != 'on' ) {
|
245 |
+
self::$stat[ 'id' ] = -204;
|
246 |
+
self::_set_error_array( __( 'Tracker is turned off, but client-side tracking code is still running.', 'wp-slimstat' ), true );
|
247 |
+
return $_argument;
|
248 |
+
}
|
249 |
+
|
250 |
+
self::toggle_date_i18n_filters( false );
|
251 |
+
self::$stat[ 'dt' ] = date_i18n( 'U' );
|
252 |
+
self::$stat[ 'notes' ] = array();
|
253 |
+
self::toggle_date_i18n_filters( true );
|
254 |
+
|
255 |
+
// Allow third-party tools to initialize the stat array
|
256 |
+
self::$stat = apply_filters( 'slimstat_filter_pageview_stat_init', self::$stat );
|
257 |
+
|
258 |
+
// Third-party tools can decide that this pageview should not be tracked, by setting its datestamp to zero
|
259 |
+
if ( empty( self::$stat ) || empty( self::$stat[ 'dt' ] ) ) {
|
260 |
+
self::$stat[ 'id' ] = -300;
|
261 |
+
self::_set_error_array( __( 'Pageview filtered by third-party code', 'wp-slimstat' ), true );
|
262 |
+
return $_argument;
|
263 |
+
}
|
264 |
+
|
265 |
+
// User's IP address
|
266 |
+
list ( self::$stat[ 'ip' ], self::$stat[ 'other_ip' ] ) = self::_get_remote_ip();
|
267 |
+
|
268 |
+
if ( empty( self::$stat[ 'ip' ] ) || self::$stat[ 'ip' ] == '0.0.0.0' ) {
|
269 |
+
self::$stat[ 'id' ] = -202;
|
270 |
+
self::_set_error_array( __( 'Empty or not supported IP address format (IPv6)', 'wp-slimstat' ), false );
|
271 |
+
return $_argument;
|
272 |
+
}
|
273 |
+
|
274 |
+
// Referrer URL
|
275 |
+
if ( !empty( self::$data_js[ 'ref' ] ) ) {
|
276 |
+
self::$stat[ 'referer' ] = base64_decode( self::$data_js[ 'ref' ] );
|
277 |
+
}
|
278 |
+
else if ( !empty( $_SERVER[ 'HTTP_REFERER' ] ) ) {
|
279 |
+
self::$stat[ 'referer' ] = $_SERVER[ 'HTTP_REFERER' ];
|
280 |
+
}
|
281 |
+
|
282 |
+
if ( !empty( self::$stat[ 'referer' ] ) ) {
|
283 |
+
|
284 |
+
// Is this a 'seriously malformed' URL?
|
285 |
+
$referer = parse_url( self::$stat[ 'referer' ] );
|
286 |
+
if ( !$referer ) {
|
287 |
+
self::_set_error_array( sprintf( __( 'Malformed referrer URL: %s (IP: %s)', 'wp-slimstat' ), self::$stat[ 'referer' ], self::$stat[ 'ip' ] ), false, 201 );
|
288 |
+
self::$stat[ 'notes' ][] = sprintf( __( 'Malformed referrer URL: %s', 'wp-slimstat' ), self::$stat[ 'referer' ] );
|
289 |
+
unset( self::$stat[ 'referer' ] );
|
290 |
+
}
|
291 |
+
|
292 |
+
if ( !empty( $referer[ 'scheme' ] ) && !in_array( strtolower( $referer[ 'scheme' ] ), array( 'http', 'https', 'android-app' ) ) ) {
|
293 |
+
self::_set_error_array( sprintf( __( 'Attempted XSS Injection: %s (IP: %s)', 'wp-slimstat' ), self::$stat[ 'referer' ], self::$stat[ 'ip' ] ), false, 203 );
|
294 |
+
self::$stat[ 'notes' ][] = sprintf( __( 'Attempted XSS Injection: %s', 'wp-slimstat' ), self::$stat[ 'referer' ] );
|
295 |
+
unset( self::$stat[ 'referer' ] );
|
296 |
+
}
|
297 |
+
|
298 |
+
if ( !empty( self::$stat[ 'referer' ] ) ) {
|
299 |
+
$parsed_site_url_host = parse_url( get_site_url(), PHP_URL_HOST );
|
300 |
+
if ( !empty( $referer[ 'host' ] ) && $referer[ 'host' ] == $parsed_site_url_host && self::$settings[ 'track_same_domain_referers' ] != 'on' ) {
|
301 |
+
unset( self::$stat[ 'referer' ] );
|
302 |
+
}
|
303 |
+
else {
|
304 |
+
// Fix Google Images referring domain
|
305 |
+
if ( strpos( self::$stat[ 'referer' ], 'www.google' ) !== false ) {
|
306 |
+
if ( strpos( self::$stat[ 'referer' ], '/imgres?' ) !== false ) {
|
307 |
+
self::$stat[ 'referer' ] = str_replace( 'www.google', 'images.google', self::$stat[ 'referer' ] );
|
308 |
+
}
|
309 |
+
if ( strpos( self::$stat[ 'referer' ], '/url?' ) !== false ) {
|
310 |
+
self::$stat[ 'referer' ] = str_replace( '/url?', '/search?', self::$stat[ 'referer' ] );
|
311 |
+
}
|
312 |
+
}
|
313 |
+
|
314 |
+
// Is this referer blacklisted?
|
315 |
+
if ( !empty( self::$settings[ 'ignore_referers' ] ) ) {
|
316 |
+
$return_error_code = array(
|
317 |
+
-301,
|
318 |
+
sprintf( __( 'Referrer %s is blacklisted', 'wp-slimstat' ), self::$stat[ 'referer' ] ),
|
319 |
+
true
|
320 |
+
);
|
321 |
+
if ( self::_is_blacklisted( self::$stat[ 'referer' ], self::$settings[ 'ignore_referers' ], $return_error_code ) ) {
|
322 |
+
return $_argument;
|
323 |
+
}
|
324 |
+
}
|
325 |
+
}
|
326 |
+
}
|
327 |
+
}
|
328 |
+
|
329 |
+
$content_info = self::_get_content_info();
|
330 |
+
|
331 |
+
// Is this content type blacklisted?
|
332 |
+
if ( !empty( self::$settings[ 'ignore_content_types' ] ) ) {
|
333 |
+
$return_error_code = array(
|
334 |
+
-313,
|
335 |
+
sprintf( __( 'Content Type %s is blacklisted', 'wp-slimstat' ), $content_info[ 'content_type' ] ),
|
336 |
+
true
|
337 |
+
);
|
338 |
+
if ( self::_is_blacklisted( $content_info[ 'content_type' ], self::$settings[ 'ignore_content_types' ], $return_error_code ) ) {
|
339 |
+
return $_argument;
|
340 |
+
}
|
341 |
+
}
|
342 |
+
|
343 |
+
// Did we receive data from an Ajax request?
|
344 |
+
if ( !empty( self::$data_js[ 'id' ] ) ) {
|
345 |
+
|
346 |
+
// Are we tracking a new pageview? (pos is empty = no event was triggered)
|
347 |
+
if ( empty( self::$data_js[ 'pos' ] ) ) {
|
348 |
+
$content_info = unserialize( base64_decode( self::$data_js[ 'id' ] ) );
|
349 |
+
if ( $content_info === false || empty( $content_info[ 'content_type' ] ) ) {
|
350 |
+
$content_info = array();
|
351 |
+
}
|
352 |
+
}
|
353 |
+
|
354 |
+
// If pos is not empty and slimtrack was called, it means we are tracking a new internal download
|
355 |
+
else if ( !empty( self::$data_js[ 'res' ] ) ) {
|
356 |
+
$download_url = base64_decode( self::$data_js[ 'res' ] );
|
357 |
+
if ( is_string( $download_url ) ) {
|
358 |
+
if ( !empty( self::$data_js[ 'ty' ] ) && self::$data_js[ 'ty' ] == 1 ) {
|
359 |
+
unset( self::$stat[ 'id' ] );
|
360 |
+
$content_info = array( 'content_type' => 'download' );
|
361 |
+
}
|
362 |
+
}
|
363 |
+
}
|
364 |
+
}
|
365 |
+
|
366 |
+
self::$stat = self::$stat + $content_info;
|
367 |
+
|
368 |
+
// We want to record both hits and searches (performed through the site search form)
|
369 |
+
if ( is_array( self::$data_js ) && isset( self::$data_js[ 'res' ] ) ) {
|
370 |
+
$decoded_permalink = base64_decode( self::$data_js[ 'res' ] );
|
371 |
+
$parsed_permalink = parse_url( $decoded_permalink );
|
372 |
+
if ( !empty( $referer ) ) {
|
373 |
+
self::$stat[ 'searchterms' ] = self::_get_search_terms( $referer );
|
374 |
+
}
|
375 |
+
|
376 |
+
// Was this an internal search?
|
377 |
+
if ( empty( self::$stat[ 'searchterms' ] ) ) {
|
378 |
+
self::$stat[ 'searchterms' ] = self::_get_search_terms( $parsed_permalink );
|
379 |
+
}
|
380 |
+
|
381 |
+
if ( self::$stat[ 'content_type' ] == 'external' ) {
|
382 |
+
self::$stat['resource'] = $decoded_permalink;
|
383 |
+
}
|
384 |
+
else {
|
385 |
+
self::$stat['resource'] = !is_array( $parsed_permalink ) ? __( 'Malformed URL', 'wp-slimstat' ) : urldecode( $parsed_permalink[ 'path' ] ) . ( !empty( $parsed_permalink[ 'query' ] ) ? '?' . urldecode( $parsed_permalink[ 'query' ] ) : '' );
|
386 |
+
}
|
387 |
+
}
|
388 |
+
elseif ( empty( $_REQUEST[ 's' ] ) ) {
|
389 |
+
if ( !empty( $referer ) ) {
|
390 |
+
self::$stat[ 'searchterms' ] = self::_get_search_terms( $referer );
|
391 |
+
}
|
392 |
+
self::$stat[ 'resource' ] = self::get_request_uri();
|
393 |
+
}
|
394 |
+
else {
|
395 |
+
self::$stat[ 'resource' ] = parse_url( self::get_request_uri(), PHP_URL_PATH );
|
396 |
+
self::$stat[ 'searchterms' ] = str_replace( '\\', '', $_REQUEST[ 's' ] );
|
397 |
+
self::$stat[ 'referer' ] = self::get_request_uri();
|
398 |
+
if ( isset( $GLOBALS['wp_query']->found_posts ) ) {
|
399 |
+
self::$stat[ 'notes' ][] = 'results:' . intval( $GLOBALS['wp_query']->found_posts );
|
400 |
+
}
|
401 |
+
}
|
402 |
+
|
403 |
+
// Don't store empty values in the database
|
404 |
+
if ( empty( self::$stat[ 'searchterms' ] ) ) {
|
405 |
+
unset( self::$stat[ 'searchterms' ] );
|
406 |
+
}
|
407 |
+
|
408 |
+
// Do not track report pages in the admin
|
409 |
+
if ( ( !empty( self::$stat[ 'resource' ] ) && strpos( self::$stat[ 'resource' ], 'wp-admin/admin-ajax.php' ) !== false ) || ( !empty( $_GET[ 'page' ] ) && strpos( $_GET[ 'page' ], 'slimview' ) !== false ) ) {
|
410 |
+
self::$stat = array();
|
411 |
+
return $_argument;
|
412 |
+
}
|
413 |
+
|
414 |
+
// Is this resource blacklisted?
|
415 |
+
if ( !empty( self::$settings[ 'ignore_resources' ] ) ) {
|
416 |
+
$return_error_code = array(
|
417 |
+
-302,
|
418 |
+
sprintf( __( 'Permalink %s is blacklisted', 'wp-slimstat' ), self::$stat[ 'resource' ] ),
|
419 |
+
true
|
420 |
+
);
|
421 |
+
if ( self::_is_blacklisted( self::$stat[ 'resource' ], self::$settings[ 'ignore_resources' ], $return_error_code ) ) {
|
422 |
+
return $_argument;
|
423 |
+
}
|
424 |
+
}
|
425 |
+
|
426 |
+
// Should we ignore this user?
|
427 |
+
if ( !empty( $GLOBALS[ 'current_user' ]->ID ) ) {
|
428 |
+
// Don't track logged-in users, if the corresponding option is enabled
|
429 |
+
if ( self::$settings[ 'track_users' ] == 'no' ) {
|
430 |
+
self::$stat[ 'id' ] = -303;
|
431 |
+
self::_set_error_array( sprintf( __( 'Logged in user %s not tracked', 'wp-slimstat' ), $GLOBALS[ 'current_user' ]->data->user_login ), true );
|
432 |
+
return $_argument;
|
433 |
+
}
|
434 |
+
|
435 |
+
// Don't track users with given capabilities
|
436 |
+
foreach ( self::string_to_array( self::$settings[ 'ignore_capabilities' ] ) as $a_capability ) {
|
437 |
+
if ( array_key_exists( strtolower( $a_capability ), $GLOBALS[ 'current_user' ]->allcaps ) ) {
|
438 |
+
self::$stat[ 'id' ] = -304;
|
439 |
+
self::_set_error_array( sprintf( __( 'User with capability %s not tracked', 'wp-slimstat' ), $a_capability ), true );
|
440 |
+
return $_argument;
|
441 |
+
}
|
442 |
+
}
|
443 |
+
|
444 |
+
// Is this user blacklisted?
|
445 |
+
if ( !empty( self::$settings[ 'ignore_users' ] ) ) {
|
446 |
+
$return_error_code = array(
|
447 |
+
-305,
|
448 |
+
sprintf( __( 'User %s is blacklisted', 'wp-slimstat' ), $GLOBALS[ 'current_user' ]->data->user_login ),
|
449 |
+
true
|
450 |
+
);
|
451 |
+
if ( self::_is_blacklisted( $GLOBALS[ 'current_user' ]->data->user_login, self::$settings[ 'ignore_users' ], $return_error_code ) ) {
|
452 |
+
return $_argument;
|
453 |
+
}
|
454 |
+
}
|
455 |
+
|
456 |
+
self::$stat[ 'username' ] = $GLOBALS[ 'current_user' ]->data->user_login;
|
457 |
+
self::$stat[ 'notes' ][] = 'user:' . $GLOBALS[ 'current_user' ]->data->ID;
|
458 |
+
$not_spam = true;
|
459 |
+
}
|
460 |
+
elseif ( isset( $_COOKIE[ 'comment_author_' . COOKIEHASH ] ) ) {
|
461 |
+
// Is this a spammer?
|
462 |
+
$spam_comment = self::$wpdb->get_row( self::$wpdb->prepare( "
|
463 |
+
SELECT comment_author, COUNT(*) comment_count
|
464 |
+
FROM `" . DB_NAME . "`.{$GLOBALS['wpdb']->comments}
|
465 |
+
WHERE comment_author_IP = %s AND comment_approved = 'spam'
|
466 |
+
GROUP BY comment_author
|
467 |
+
LIMIT 0,1", self::$stat[ 'ip' ] ), ARRAY_A );
|
468 |
+
|
469 |
+
if ( !empty( $spam_comment[ 'comment_count' ] ) ) {
|
470 |
+
if ( self::$settings[ 'ignore_spammers' ] == 'on' ){
|
471 |
+
self::$stat[ 'id' ] = -306;
|
472 |
+
self::_set_error_array( sprintf( __( 'Spammer %s not tracked', 'wp-slimstat' ), $spam_comment[ 'comment_author' ] ), true );
|
473 |
+
return $_argument;
|
474 |
+
}
|
475 |
+
else{
|
476 |
+
self::$stat[ 'notes' ][] = 'spam:yes';
|
477 |
+
self::$stat[ 'username' ] = $spam_comment[ 'comment_author' ];
|
478 |
+
}
|
479 |
+
}
|
480 |
+
else
|
481 |
+
self::$stat[ 'username' ] = $_COOKIE[ 'comment_author_' . COOKIEHASH ];
|
482 |
+
}
|
483 |
+
|
484 |
+
// Should we ignore this IP address?
|
485 |
+
foreach ( self::string_to_array( self::$settings[ 'ignore_ip' ] ) as $a_ip_range ) {
|
486 |
+
$ip_to_ignore = $a_ip_range;
|
487 |
+
|
488 |
+
if ( strpos( $ip_to_ignore, '/' ) !== false ) {
|
489 |
+
list( $ip_to_ignore, $cidr_mask ) = explode( '/', trim( $ip_to_ignore ) );
|
490 |
+
}
|
491 |
+
else{
|
492 |
+
$cidr_mask = self::get_mask_length( $ip_to_ignore );
|
493 |
+
}
|
494 |
+
|
495 |
+
$long_masked_ip_to_ignore = substr( self::dtr_pton( $ip_to_ignore ), 0, $cidr_mask );
|
496 |
+
$long_masked_user_ip = substr( self::dtr_pton( self::$stat[ 'ip' ] ), 0, $cidr_mask );
|
497 |
+
$long_masked_user_other_ip = substr( self::dtr_pton( self::$stat[ 'other_ip' ] ), 0 , $cidr_mask );
|
498 |
+
|
499 |
+
if ( $long_masked_user_ip === $long_masked_ip_to_ignore || $long_masked_user_other_ip === $long_masked_ip_to_ignore ) {
|
500 |
+
self::$stat[ 'id' ] = -307;
|
501 |
+
self::_set_error_array( sprintf( __( 'IP address %s is blacklisted', 'wp-slimstat' ), self::$stat[ 'ip' ] . ( !empty( self::$stat[ 'other_ip' ] ) ? ' (' . self::$stat[ 'other_ip' ] . ')' : '' ) ), true );
|
502 |
+
return $_argument;
|
503 |
+
}
|
504 |
+
}
|
505 |
+
|
506 |
+
// Language
|
507 |
+
self::$stat[ 'language' ] = self::_get_language();
|
508 |
+
|
509 |
+
// Geolocation
|
510 |
+
include_once ( plugin_dir_path( __FILE__ ) . 'maxmind.php' );
|
511 |
+
$geolocation_data = maxmind_geolite2_connector::get_geolocation_info( self::$stat[ 'ip' ] );
|
512 |
+
|
513 |
+
// Invalid MaxMind data file
|
514 |
+
|
515 |
+
if ( !empty( $geolocation_data[ 'country' ][ 'iso_code' ] ) ) {
|
516 |
+
|
517 |
+
if ( $geolocation_data[ 'country' ][ 'iso_code' ] == 'xx' ) {
|
518 |
+
self::_set_error_array( __( 'Your MaxMind data file is invalid. Please uninstall it using the button in Settings > Maintenance.', 'wp-slimstat' ), false, 205 );
|
519 |
+
}
|
520 |
+
else {
|
521 |
+
self::$stat[ 'country' ] = strtolower( $geolocation_data[ 'country' ][ 'iso_code' ] );
|
522 |
+
|
523 |
+
|
524 |
+
if ( !empty( $geolocation_data[ 'city' ][ 'names' ][ 'en' ] ) ) {
|
525 |
+
self::$stat[ 'city' ] = $geolocation_data[ 'city' ][ 'names' ][ 'en' ];
|
526 |
+
}
|
527 |
+
|
528 |
+
if ( !empty( $geolocation_data[ 'subdivisions' ][ 0 ][ 'iso_code' ] ) && !empty( self::$stat[ 'city' ] ) ) {
|
529 |
+
self::$stat[ 'city' ] .= ' (' . $geolocation_data[ 'subdivisions' ][ 0 ][ 'iso_code' ] . ')';
|
530 |
+
}
|
531 |
+
|
532 |
+
if ( !empty( $geolocation_data[ 'location' ][ 'latitude' ] ) && !empty( $geolocation_data[ 'location' ][ 'longitude' ] ) ) {
|
533 |
+
self::$stat[ 'location' ] = $geolocation_data[ 'location' ][ 'latitude' ] . ',' . $geolocation_data[ 'location' ][ 'longitude' ];
|
534 |
+
}
|
535 |
+
}
|
536 |
+
}
|
537 |
+
|
538 |
+
unset( $geolocation_data );
|
539 |
+
|
540 |
+
// Anonymize IP Address?
|
541 |
+
if ( self::$settings[ 'anonymize_ip' ] == 'on' ) {
|
542 |
+
// IPv4 or IPv6
|
543 |
+
$needle = '.';
|
544 |
+
$replace = '.0';
|
545 |
+
if ( self::get_mask_length( self::$stat['ip'] ) == 128 ) {
|
546 |
+
$needle = ':';
|
547 |
+
$replace = ':0000';
|
548 |
+
}
|
549 |
+
|
550 |
+
self::$stat[ 'ip' ] = substr( self::$stat[ 'ip' ], 0, strrpos( self::$stat[ 'ip' ], $needle ) ) . $replace;
|
551 |
+
|
552 |
+
if ( !empty( self::$stat[ 'other_ip' ] ) ) {
|
553 |
+
self::$stat[ 'other_ip' ] = substr( self::$stat[ 'other_ip' ], 0, strrpos( self::$stat[ 'other_ip' ], $needle ) ) . $replace;
|
554 |
+
}
|
555 |
+
}
|
556 |
+
|
557 |
+
// Is this country blacklisted?
|
558 |
+
if ( !empty( self::$stat[ 'country' ] ) && !empty( self::$settings[ 'ignore_countries' ] ) && stripos( self::$settings[ 'ignore_countries' ], self::$stat[ 'country' ] ) !== false ) {
|
559 |
+
self::$stat['id'] = -308;
|
560 |
+
self::_set_error_array( sprintf( __('Country %s is blacklisted', 'wp-slimstat'), self::$stat[ 'country' ] ), true );
|
561 |
+
return $_argument;
|
562 |
+
}
|
563 |
+
|
564 |
+
// Mark or ignore Firefox/Safari prefetching requests (X-Moz: Prefetch and X-purpose: Preview)
|
565 |
+
if ( ( isset( $_SERVER[ 'HTTP_X_MOZ' ] ) && ( strtolower( $_SERVER[ 'HTTP_X_MOZ' ] ) == 'prefetch' ) ) ||
|
566 |
+
( isset( $_SERVER[ 'HTTP_X_PURPOSE' ] ) && ( strtolower( $_SERVER[ 'HTTP_X_PURPOSE' ] ) == 'preview' ) ) ) {
|
567 |
+
if ( self::$settings[ 'ignore_prefetch' ] == 'on' ) {
|
568 |
+
self::$stat[ 'id' ] = -309;
|
569 |
+
self::_set_error_array( __( 'Prefetch requests are ignored', 'wp-slimstat' ), true );
|
570 |
+
return $_argument;
|
571 |
+
}
|
572 |
+
else{
|
573 |
+
self::$stat[ 'notes' ][] = 'pre:yes';
|
574 |
+
}
|
575 |
+
}
|
576 |
+
|
577 |
+
// Detect user agent
|
578 |
+
if ( empty( self::$browser ) ) {
|
579 |
+
self::$browser = slim_browser::get_browser();
|
580 |
+
}
|
581 |
+
|
582 |
+
// Are we ignoring bots?
|
583 |
+
if ( ( self::$settings[ 'javascript_mode' ] == 'on' || self::$settings[ 'ignore_bots' ] == 'on' ) && self::$browser[ 'browser_type' ] == 1 ) {
|
584 |
+
self::$stat[ 'id' ] = -310;
|
585 |
+
self::_set_error_array( __( 'Bot not tracked', 'wp-slimstat' ), true );
|
586 |
+
return $_argument;
|
587 |
+
}
|
588 |
+
|
589 |
+
// Is this browser blacklisted?
|
590 |
+
if ( !empty( self::$settings[ 'ignore_browsers' ] ) ) {
|
591 |
+
$return_error_code = array(
|
592 |
+
-311,
|
593 |
+
sprintf( __( 'Browser %s is blacklisted', 'wp-slimstat' ), self::$browser[ 'browser' ] ),
|
594 |
+
true
|
595 |
+
);
|
596 |
+
if ( self::_is_blacklisted( array( self::$browser[ 'browser' ], self::$browser[ 'user_agent' ] ), self::$settings[ 'ignore_browsers' ], $return_error_code ) ) {
|
597 |
+
return $_argument;
|
598 |
+
}
|
599 |
+
}
|
600 |
+
|
601 |
+
// Is this operating system blacklisted?
|
602 |
+
if ( !empty( self::$settings[ 'ignore_platforms' ] ) ) {
|
603 |
+
$return_error_code = array(
|
604 |
+
-312,
|
605 |
+
sprintf( __( 'Operating System %s is blacklisted', 'wp-slimstat' ), self::$browser[ 'platform' ] ),
|
606 |
+
true
|
607 |
+
);
|
608 |
+
if ( self::_is_blacklisted( self::$browser[ 'platform' ], self::$settings[ 'ignore_platforms' ], $return_error_code ) ) {
|
609 |
+
return $_argument;
|
610 |
+
}
|
611 |
+
}
|
612 |
+
|
613 |
+
self::$stat = self::$stat + self::$browser;
|
614 |
+
|
615 |
+
// This function can be called in "simulate" mode: no data will be actually saved in the database
|
616 |
+
if ( is_array( $_argument ) && isset( $_argument[ 'slimtrack_simulate' ] ) ) {
|
617 |
+
$_argument[ 'slimtrack_would_track' ] = true;
|
618 |
+
return ( $_argument );
|
619 |
+
}
|
620 |
+
|
621 |
+
// Do we need to assign a visit_id to this user?
|
622 |
+
$cookie_has_been_set = self::_set_visit_id( false );
|
623 |
+
|
624 |
+
// Allow third-party tools to modify all the data we've gathered so far
|
625 |
+
self::$stat = apply_filters( 'slimstat_filter_pageview_stat', self::$stat );
|
626 |
+
do_action( 'slimstat_track_pageview', self::$stat );
|
627 |
+
|
628 |
+
// Third-party tools can decide that this pageview should not be tracked, by setting its datestamp to zero
|
629 |
+
if (empty(self::$stat) || empty(self::$stat['dt'])){
|
630 |
+
self::$stat['id'] = -300;
|
631 |
+
self::_set_error_array( __( 'Pageview filtered by third-party code', 'wp-slimstat' ), true );
|
632 |
+
return $_argument;
|
633 |
+
}
|
634 |
+
|
635 |
+
// Implode the notes
|
636 |
+
if ( !empty( self::$stat[ 'notes' ] ) ) {
|
637 |
+
self::$stat[ 'notes' ] = implode( ';', self::$stat[ 'notes' ] );
|
638 |
+
}
|
639 |
+
else {
|
640 |
+
unset( self::$stat[ 'notes' ] );
|
641 |
+
}
|
642 |
+
|
643 |
+
// Now let's save this information in the database
|
644 |
+
self::$stat[ 'id' ] = self::insert_row( self::$stat, $GLOBALS[ 'wpdb' ]->prefix . 'slim_stats' );
|
645 |
+
|
646 |
+
// Something went wrong during the insert
|
647 |
+
if ( empty( self::$stat[ 'id' ] ) ) {
|
648 |
+
|
649 |
+
// Attempt to init the environment (plugin just activated on a blog in a MU network?)
|
650 |
+
include_once ( plugin_dir_path( __FILE__ ) . 'admin/wp-slimstat-admin.php' );
|
651 |
+
wp_slimstat_admin::init_environment( true );
|
652 |
+
|
653 |
+
// Now let's try again
|
654 |
+
self::$stat['id'] = self::insert_row(self::$stat, $GLOBALS['wpdb']->prefix.'slim_stats');
|
655 |
+
|
656 |
+
if ( empty( self::$stat[ 'id' ] ) ) {
|
657 |
+
self::$stat[ 'id' ] = -200;
|
658 |
+
self::_set_error_array( self::$wpdb->last_error, false );
|
659 |
+
return $_argument;
|
660 |
+
}
|
661 |
+
}
|
662 |
+
|
663 |
+
// Is this a new visitor?
|
664 |
+
$set_cookie = apply_filters( 'slimstat_set_visit_cookie', ( !empty( self::$settings[ 'set_tracker_cookie' ] ) && self::$settings[ 'set_tracker_cookie' ] == 'on' ) );
|
665 |
+
if ( $set_cookie ) {
|
666 |
+
if ( empty( self::$stat[ 'visit_id' ] ) && !empty( self::$stat[ 'id' ] ) ) {
|
667 |
+
// Set a cookie to track this visit (Google and other non-human engines will just ignore it)
|
668 |
+
@setcookie(
|
669 |
+
'slimstat_tracking_code',
|
670 |
+
self::_get_id_with_checksum( self::$stat[ 'id' ] . 'id' ),
|
671 |
+
time() + 2678400, // one month
|
672 |
+
COOKIEPATH
|
673 |
+
);
|
674 |
+
}
|
675 |
+
elseif ( !$cookie_has_been_set && self::$settings[ 'extend_session' ] == 'on' && self::$stat[ 'visit_id' ] > 0 ) {
|
676 |
+
@setcookie(
|
677 |
+
'slimstat_tracking_code',
|
678 |
+
self::_get_id_with_checksum( self::$stat[ 'visit_id' ] ),
|
679 |
+
time() + self::$settings[ 'session_duration' ],
|
680 |
+
COOKIEPATH
|
681 |
+
);
|
682 |
+
}
|
683 |
+
}
|
684 |
+
|
685 |
+
return $_argument;
|
686 |
+
}
|
687 |
+
// end slimtrack
|
688 |
+
|
689 |
+
/**
|
690 |
+
* Decodes the permalink
|
691 |
+
*/
|
692 |
+
public static function get_request_uri(){
|
693 |
+
if (isset($_SERVER['REQUEST_URI'])){
|
694 |
+
return urldecode($_SERVER['REQUEST_URI']);
|
695 |
+
}
|
696 |
+
elseif (isset($_SERVER['SCRIPT_NAME'])){
|
697 |
+
return isset($_SERVER['QUERY_STRING'])?$_SERVER['SCRIPT_NAME']."?".$_SERVER['QUERY_STRING']:$_SERVER['SCRIPT_NAME'];
|
698 |
+
}
|
699 |
+
else{
|
700 |
+
return isset($_SERVER['QUERY_STRING'])?$_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING']:$_SERVER['PHP_SELF'];
|
701 |
+
}
|
702 |
+
}
|
703 |
+
// end get_request_uri
|
704 |
+
|
705 |
+
/**
|
706 |
+
* Stores the information (array) in the appropriate table and returns the corresponding ID
|
707 |
+
*/
|
708 |
+
public static function insert_row($_data = array(), $_table = ''){
|
709 |
+
if ( empty( $_data ) || empty( $_table ) ) {
|
710 |
+
return -1;
|
711 |
+
}
|
712 |
+
|
713 |
+
// Remove unwanted characters (SQL injections, anyone?)
|
714 |
+
$data_keys = array();
|
715 |
+
foreach (array_keys($_data) as $a_key){
|
716 |
+
$data_keys[] = sanitize_key($a_key);
|
717 |
+
}
|
718 |
+
|
719 |
+
self::$wpdb->query(self::$wpdb->prepare("
|
720 |
+
INSERT IGNORE INTO $_table (".implode(", ", $data_keys).')
|
721 |
+
VALUES ('.substr(str_repeat('%s,', count($_data)), 0, -1).")", $_data));
|
722 |
+
|
723 |
+
return intval(self::$wpdb->insert_id);
|
724 |
+
}
|
725 |
+
// end insert_row
|
726 |
+
|
727 |
+
/**
|
728 |
+
* Updates an existing row
|
729 |
+
*/
|
730 |
+
public static function update_row($_data = array(), $_table = ''){
|
731 |
+
if (empty($_data) || empty($_table)){
|
732 |
+
return -1;
|
733 |
+
}
|
734 |
+
|
735 |
+
// Move the ID at the end of the array
|
736 |
+
$id = $_data['id'];
|
737 |
+
unset($_data['id']);
|
738 |
+
|
739 |
+
// Remove unwanted characters (SQL injections, anyone?)
|
740 |
+
$data_keys = array();
|
741 |
+
foreach (array_keys($_data) as $a_key){
|
742 |
+
$data_keys[] = sanitize_key($a_key);
|
743 |
+
}
|
744 |
+
|
745 |
+
// Add the id at the end
|
746 |
+
$_data['id'] = $id;
|
747 |
+
|
748 |
+
self::$wpdb->query(self::$wpdb->prepare("
|
749 |
+
UPDATE IGNORE $_table
|
750 |
+
SET ".implode(' = %s, ', $data_keys)." = %s
|
751 |
+
WHERE id = %d", $_data));
|
752 |
+
|
753 |
+
return 0;
|
754 |
+
}
|
755 |
+
|
756 |
+
/**
|
757 |
+
* Tries to find the user's REAL IP address
|
758 |
+
*/
|
759 |
+
protected static function _get_remote_ip(){
|
760 |
+
$ip_array = array( '', '' );
|
761 |
+
|
762 |
+
if ( !empty( $_SERVER[ 'REMOTE_ADDR' ] ) && filter_var( $_SERVER[ 'REMOTE_ADDR' ], FILTER_VALIDATE_IP ) !== false ) {
|
763 |
+
$ip_array[ 0 ] = $_SERVER[ 'REMOTE_ADDR' ];
|
764 |
+
}
|
765 |
+
|
766 |
+
$originating_ip_headers = array( 'X-Forwarded-For', 'HTTP_X_FORWARDED_FOR', 'CF-Connecting-IP', 'HTTP_CLIENT_IP', 'HTTP_X_REAL_IP', 'HTTP_FORWARDED', 'HTTP_X_FORWARDED' );
|
767 |
+
foreach ( $originating_ip_headers as $a_header ) {
|
768 |
+
if ( !empty( $_SERVER[ $a_header ] ) ) {
|
769 |
+
foreach ( explode( ',', $_SERVER[ $a_header ] ) as $a_ip ) {
|
770 |
+
if ( filter_var( $a_ip, FILTER_VALIDATE_IP ) !== false && $a_ip != $ip_array[ 0 ] ) {
|
771 |
+
$ip_array[ 1 ] = $a_ip;
|
772 |
+
break;
|
773 |
+
}
|
774 |
+
}
|
775 |
+
}
|
776 |
+
}
|
777 |
+
|
778 |
+
return $ip_array;
|
779 |
+
}
|
780 |
+
// end _get_remote_ip
|
781 |
+
|
782 |
+
/**
|
783 |
+
* Extracts the accepted language from browser headers
|
784 |
+
*/
|
785 |
+
protected static function _get_language(){
|
786 |
+
if(isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])){
|
787 |
+
|
788 |
+
// Capture up to the first delimiter (, found in Safari)
|
789 |
+
preg_match("/([^,;]*)/", $_SERVER["HTTP_ACCEPT_LANGUAGE"], $array_languages);
|
790 |
+
|
791 |
+
// Fix some codes, the correct syntax is with minus (-) not underscore (_)
|
792 |
+
return str_replace( "_", "-", strtolower( $array_languages[0] ) );
|
793 |
+
}
|
794 |
+
return 'xx'; // Indeterminable language
|
795 |
+
}
|
796 |
+
// end _get_language
|
797 |
+
|
798 |
+
/**
|
799 |
+
* Sniffs out referrals from search engines and tries to determine the query string
|
800 |
+
*/
|
801 |
+
protected static function _get_search_terms( $_url = array() ) {
|
802 |
+
if ( empty( $_url ) || !isset( $_url[ 'host' ] ) ) {
|
803 |
+
return '';
|
804 |
+
}
|
805 |
+
|
806 |
+
// Engines with different character encodings should always be listed here, regardless of their query string format
|
807 |
+
$query_formats = array(
|
808 |
+
'baidu.com' => 'wd',
|
809 |
+
'bing' => 'q',
|
810 |
+
'dogpile.com' => 'q',
|
811 |
+
'duckduckgo' => 'q',
|
812 |
+
'eniro' => 'search_word',
|
813 |
+
'exalead.com' => 'q',
|
814 |
+
'excite' => 'q',
|
815 |
+
'gigablast' => 'q',
|
816 |
+
'google' => 'q',
|
817 |
+
'hotbot' => 'q',
|
818 |
+
'maktoob' => 'p',
|
819 |
+
'mamma' => 'q',
|
820 |
+
'naver' => 'query',
|
821 |
+
'qwant' => 'q',
|
822 |
+
'rambler' => 'query',
|
823 |
+
'seznam' => 'oq',
|
824 |
+
'soso.com' => 'query',
|
825 |
+
'virgilio' => 'qs',
|
826 |
+
'voila' => 'rdata',
|
827 |
+
'yahoo' => 'p',
|
828 |
+
'yam' => 'k',
|
829 |
+
'yandex' => 'text',
|
830 |
+
'yell' => 'keywords',
|
831 |
+
'yippy' => 'query',
|
832 |
+
'youdao' => 'q'
|
833 |
+
);
|
834 |
+
|
835 |
+
$charsets = array( 'baidu' => 'EUC-CN' );
|
836 |
+
$regex_match = implode( '|', array_keys( $query_formats ) );
|
837 |
+
$searchterms = '';
|
838 |
+
|
839 |
+
if ( !empty( $_url[ 'query' ] ) ) {
|
840 |
+
parse_str( $_url[ 'query' ], $query );
|
841 |
+
}
|
842 |
+
|
843 |
+
if ( !empty( $_url[ 'host' ] ) ) {
|
844 |
+
preg_match( "~($regex_match).~i", $_url[ 'host' ], $matches );
|
845 |
+
}
|
846 |
+
|
847 |
+
if ( !empty( $matches[ 1 ] ) ) {
|
848 |
+
// Let's remember that this is a search engine, regardless of the URL containing searchterms (thank you, NSA)
|
849 |
+
$searchterms = '_';
|
850 |
+
if ( !empty( $query[ $query_formats[ $matches[ 1 ] ] ] ) ) {
|
851 |
+
$searchterms = str_replace( '\\', '', trim( urldecode( $query[ $query_formats[ $matches[ 1 ] ] ] ) ) );
|
852 |
+
// Test for encodings different from UTF-8
|
853 |
+
if ( function_exists( 'mb_check_encoding' ) && !mb_check_encoding( $query[ $query_formats[ $matches[ 1 ] ] ], 'UTF-8' ) && !empty( $charsets[ $matches[ 1 ] ] ) ) {
|
854 |
+
$searchterms = mb_convert_encoding( urldecode( $query[ $query_formats[ $matches[ 1 ] ] ] ), 'UTF-8', $charsets[ $matches[ 1 ] ] );
|
855 |
+
}
|
856 |
+
}
|
857 |
+
}
|
858 |
+
else {
|
859 |
+
// We weren't lucky, but there's still hope
|
860 |
+
foreach( array( 'q','s','k','qt' ) as $a_format ) {
|
861 |
+
if ( !empty( $query[ $a_format ] ) ) {
|
862 |
+
$searchterms = str_replace( '\\', '', trim( urldecode( $query[ $a_format ] ) ) );
|
863 |
+
break;
|
864 |
+
}
|
865 |
+
}
|
866 |
+
}
|
867 |
+
|
868 |
+
return $searchterms;
|
869 |
+
}
|
870 |
+
// end _get_search_terms
|
871 |
+
|
872 |
+
/**
|
873 |
+
* Returns details about the resource being accessed
|
874 |
+
*/
|
875 |
+
protected static function _get_content_info(){
|
876 |
+
$content_info = array( 'content_type' => 'unknown' );
|
877 |
+
|
878 |
+
// Mark 404 pages
|
879 |
+
if ( is_404() ) {
|
880 |
+
$content_info[ 'content_type' ] = '404';
|
881 |
+
}
|
882 |
+
|
883 |
+
// Type
|
884 |
+
else if ( is_single() ) {
|
885 |
+
if ( ( $post_type = get_post_type() ) != 'post' ) {
|
886 |
+
$post_type = 'cpt:' . $post_type;
|
887 |
+
}
|
888 |
+
|
889 |
+
$content_info[ 'content_type' ] = $post_type;
|
890 |
+
$content_info_array = array();
|
891 |
+
foreach ( get_object_taxonomies( $GLOBALS[ 'post' ] ) as $a_taxonomy ) {
|
892 |
+
$terms = get_the_terms( $GLOBALS[ 'post' ]->ID, $a_taxonomy );
|
893 |
+
if ( is_array( $terms ) ) {
|
894 |
+
foreach ( $terms as $a_term ) {
|
895 |
+
$content_info_array[] = $a_term->term_id;
|
896 |
+
}
|
897 |
+
$content_info[ 'category' ] = implode( ',', $content_info_array );
|
898 |
+
}
|
899 |
+
}
|
900 |
+
$content_info[ 'content_id' ] = $GLOBALS[ 'post' ]->ID;
|
901 |
+
}
|
902 |
+
else if ( is_page() ) {
|
903 |
+
$content_info[ 'content_type' ] = 'page';
|
904 |
+
$content_info[ 'content_id' ] = $GLOBALS[ 'post' ]->ID;
|
905 |
+
}
|
906 |
+
elseif (is_attachment()){
|
907 |
+
$content_info['content_type'] = 'attachment';
|
908 |
+
}
|
909 |
+
elseif (is_singular()){
|
910 |
+
$content_info['content_type'] = 'singular';
|
911 |
+
}
|
912 |
+
elseif (is_post_type_archive()){
|
913 |
+
$content_info['content_type'] = 'post_type_archive';
|
914 |
+
}
|
915 |
+
elseif (is_tag()){
|
916 |
+
$content_info['content_type'] = 'tag';
|
917 |
+
$list_tags = get_the_tags();
|
918 |
+
if (is_array($list_tags)){
|
919 |
+
$tag_info = array_pop($list_tags);
|
920 |
+
if (!empty($tag_info)) $content_info['category'] = "$tag_info->term_id";
|
921 |
+
}
|
922 |
+
}
|
923 |
+
elseif (is_tax()){
|
924 |
+
$content_info['content_type'] = 'taxonomy';
|
925 |
+
}
|
926 |
+
elseif (is_category()){
|
927 |
+
$content_info['content_type'] = 'category';
|
928 |
+
$list_categories = get_the_category();
|
929 |
+
if (is_array($list_categories)){
|
930 |
+
$cat_info = array_pop($list_categories);
|
931 |
+
if (!empty($cat_info)) $content_info['category'] = "$cat_info->term_id";
|
932 |
+
}
|
933 |
+
}
|
934 |
+
else if (is_date()){
|
935 |
+
$content_info['content_type']= 'date';
|
936 |
+
}
|
937 |
+
else if (is_author()){
|
938 |
+
$content_info['content_type'] = 'author';
|
939 |
+
}
|
940 |
+
else if ( is_archive() ) {
|
941 |
+
$content_info['content_type'] = 'archive';
|
942 |
+
}
|
943 |
+
else if ( is_search() ) {
|
944 |
+
$content_info[ 'content_type' ] = 'search';
|
945 |
+
}
|
946 |
+
else if ( is_feed() ) {
|
947 |
+
$content_info[ 'content_type' ] = 'feed';
|
948 |
+
}
|
949 |
+
else if ( is_home() || is_front_page() ) {
|
950 |
+
$content_info['content_type'] = 'home';
|
951 |
+
}
|
952 |
+
else if ( !empty( $GLOBALS[ 'pagenow' ] ) && $GLOBALS[ 'pagenow' ] == 'wp-login.php' ) {
|
953 |
+
$content_info[ 'content_type' ] = 'login';
|
954 |
+
}
|
955 |
+
else if ( !empty( $GLOBALS['pagenow'] ) && $GLOBALS['pagenow'] == 'wp-register.php' ) {
|
956 |
+
$content_info[ 'content_type' ] = 'registration';
|
957 |
+
}
|
958 |
+
// WordPress sets is_admin() to true for all ajax requests ( front-end or admin-side )
|
959 |
+
elseif ( is_admin() && ( !defined( 'DOING_AJAX' ) || !DOING_AJAX ) ) {
|
960 |
+
$content_info[ 'content_type' ] = 'admin';
|
961 |
+
}
|
962 |
+
|
963 |
+
if (is_paged()){
|
964 |
+
$content_info[ 'content_type' ] .= ',paged';
|
965 |
+
}
|
966 |
+
|
967 |
+
// Author
|
968 |
+
if ( is_singular() ) {
|
969 |
+
$author = get_the_author_meta( 'user_login', $GLOBALS[ 'post' ]->post_author );
|
970 |
+
if ( !empty( $author ) ) {
|
971 |
+
$content_info[ 'author' ] = $author;
|
972 |
+
}
|
973 |
+
}
|
974 |
+
|
975 |
+
return $content_info;
|
976 |
+
}
|
977 |
+
// end _get_content_info
|
978 |
+
|
979 |
+
/**
|
980 |
+
* Reads the cookie to get the visit_id and sets the variable accordingly
|
981 |
+
*/
|
982 |
+
protected static function _set_visit_id($_force_assign = false){
|
983 |
+
$is_new_session = true;
|
984 |
+
$identifier = 0;
|
985 |
+
|
986 |
+
if ( isset( $_COOKIE[ 'slimstat_tracking_code' ] ) ) {
|
987 |
+
// Make sure only authorized information is recorded
|
988 |
+
$identifier = self::_separate_id_from_checksum( $_COOKIE[ 'slimstat_tracking_code' ] );
|
989 |
+
if ( $identifier === false ) {
|
990 |
+
return false;
|
991 |
+
}
|
992 |
+
|
993 |
+
$is_new_session = ( strpos( $identifier, 'id' ) !== false );
|
994 |
+
$identifier = intval( $identifier );
|
995 |
+
}
|
996 |
+
|
997 |
+
// User doesn't have an active session
|
998 |
+
if ( $is_new_session && ( $_force_assign || self::$settings[ 'javascript_mode' ] == 'on' ) ) {
|
999 |
+
if ( empty( self::$settings[ 'session_duration' ] ) ) {
|
1000 |
+
self::$settings[ 'session_duration' ] = 1800;
|
1001 |
+
}
|
1002 |
+
|
1003 |
+
self::$stat[ 'visit_id' ] = get_transient( 'slimstat_visit_id' );
|
1004 |
+
if ( self::$stat[ 'visit_id' ] === false ) {
|
1005 |
+
self::$stat[ 'visit_id' ] = intval( self::$wpdb->get_var( "SELECT MAX( visit_id ) FROM {$GLOBALS[ 'wpdb' ]->prefix}slim_stats" ) );
|
1006 |
+
}
|
1007 |
+
self::$stat[ 'visit_id' ]++;
|
1008 |
+
set_transient( 'slimstat_visit_id', self::$stat[ 'visit_id' ] );
|
1009 |
+
|
1010 |
+
$set_cookie = apply_filters( 'slimstat_set_visit_cookie', ( !empty( self::$settings[ 'set_tracker_cookie' ] ) && self::$settings[ 'set_tracker_cookie' ] == 'on' ) );
|
1011 |
+
if ( $set_cookie ) {
|
1012 |
+
@setcookie(
|
1013 |
+
'slimstat_tracking_code',
|
1014 |
+
self::_get_id_with_checksum( self::$stat[ 'visit_id' ] ),
|
1015 |
+
time() + self::$settings[ 'session_duration' ],
|
1016 |
+
COOKIEPATH
|
1017 |
+
);
|
1018 |
+
}
|
1019 |
+
|
1020 |
+
}
|
1021 |
+
elseif ( $identifier > 0 ) {
|
1022 |
+
self::$stat[ 'visit_id' ] = $identifier;
|
1023 |
+
}
|
1024 |
+
|
1025 |
+
if ( $is_new_session && $identifier > 0 ) {
|
1026 |
+
self::$wpdb->query( self::$wpdb->prepare( "
|
1027 |
+
UPDATE {$GLOBALS['wpdb']->prefix}slim_stats
|
1028 |
+
SET visit_id = %d
|
1029 |
+
WHERE id = %d AND visit_id = 0", self::$stat[ 'visit_id' ], $identifier
|
1030 |
+
) );
|
1031 |
+
}
|
1032 |
+
return ( $is_new_session && ( $_force_assign || self::$settings[ 'javascript_mode' ] == 'on' ) );
|
1033 |
+
}
|
1034 |
+
// end _set_visit_id
|
1035 |
+
|
1036 |
+
/**
|
1037 |
+
* Makes sure that the data received from the client is well-formed (and that nobody is trying to do bad stuff)
|
1038 |
+
*/
|
1039 |
+
protected static function _check_data_integrity( $_data = '' ) {
|
1040 |
+
// Parse the information we received
|
1041 |
+
self::$data_js = apply_filters( 'slimstat_filter_pageview_data_js', $_data );
|
1042 |
+
|
1043 |
+
// Do we have an id for this request?
|
1044 |
+
if ( empty( self::$data_js[ 'id' ] ) || empty( self::$data_js[ 'op' ] ) ) {
|
1045 |
+
do_action( 'slimstat_track_exit_102' );
|
1046 |
+
self::$stat[ 'id' ] = -100;
|
1047 |
+
self::_set_error_array( __( 'Invalid payload string. Try clearing your WordPress cache.', 'wp-slimstat' ), false );
|
1048 |
+
self::slimstat_save_options();
|
1049 |
+
exit( self::_get_id_with_checksum( self::$stat[ 'id' ] ) );
|
1050 |
+
}
|
1051 |
+
|
1052 |
+
// Make sure that the control code is valid
|
1053 |
+
self::$data_js[ 'id' ] = self::_separate_id_from_checksum( self::$data_js[ 'id' ] );
|
1054 |
+
|
1055 |
+
if ( self::$data_js['id'] === false ) {
|
1056 |
+
do_action( 'slimstat_track_exit_103' );
|
1057 |
+
self::$stat[ 'id' ] = -101;
|
1058 |
+
self::_set_error_array( __( 'Invalid data signature. Try clearing your WordPress cache.', 'wp-slimstat' ), false );
|
1059 |
+
self::slimstat_save_options();
|
1060 |
+
exit( self::_get_id_with_checksum( self::$stat[ 'id' ] ) );
|
1061 |
+
}
|
1062 |
+
|
1063 |
+
$intval_id = intval( self::$data_js[ 'id' ] );
|
1064 |
+
if ( $intval_id < 0 ) {
|
1065 |
+
do_action( 'slimstat_track_exit_' . abs( $intval_id ) );
|
1066 |
+
self::$stat[ 'id' ] = $intval_id;
|
1067 |
+
self::slimstat_save_options();
|
1068 |
+
exit( self::_get_id_with_checksum( self::$stat[ 'id' ] ) );
|
1069 |
+
}
|
1070 |
+
}
|
1071 |
+
// end _check_data_integrity
|
1072 |
+
|
1073 |
+
protected static function _set_error_array( $_error_message = '', $_is_notice = false, $_error_code = 0 ) {
|
1074 |
+
$error_code = empty( $_error_code ) ? abs( self::$stat[ 'id' ] ) : $_error_code;
|
1075 |
+
self::toggle_date_i18n_filters( false );
|
1076 |
+
if ( $_is_notice ) {
|
1077 |
+
self::$settings[ 'last_tracker_notice' ] = array( $error_code, $_error_message, date_i18n( 'U' ) );
|
1078 |
+
}
|
1079 |
+
else {
|
1080 |
+
self::$settings[ 'last_tracker_error' ] = array( $error_code, $_error_message, date_i18n( 'U' ) );
|
1081 |
+
}
|
1082 |
+
self::toggle_date_i18n_filters( true );
|
1083 |
+
}
|
1084 |
+
|
1085 |
+
protected static function _get_id_with_checksum( $_id = 0 ) {
|
1086 |
+
return $_id . '.' . md5( $_id . self::$settings[ 'secret' ] );
|
1087 |
+
}
|
1088 |
+
|
1089 |
+
protected static function _separate_id_from_checksum( $_id_with_checksum = '' ) {
|
1090 |
+
list( $id, $checksum ) = explode( '.', $_id_with_checksum );
|
1091 |
+
|
1092 |
+
if ( $checksum === md5( $id . self::$settings[ 'secret' ] ) ) {
|
1093 |
+
return $id;
|
1094 |
+
}
|
1095 |
+
|
1096 |
+
return false;
|
1097 |
+
}
|
1098 |
+
|
1099 |
+
protected static function _is_blacklisted( $_needles = array(), $_haystack_string = '', $_return_error_code = array( 0, '', false ) ) {
|
1100 |
+
foreach ( self::string_to_array( $_haystack_string ) as $a_item ) {
|
1101 |
+
$pattern = str_replace( array( '\*', '\!' ) , array( '(.*)', '.' ), preg_quote( $a_item, '@' ) );
|
1102 |
+
|
1103 |
+
if ( !is_array( $_needles ) ) {
|
1104 |
+
$_needles = array( $_needles );
|
1105 |
+
}
|
1106 |
+
|
1107 |
+
foreach ( $_needles as $a_needle ) {
|
1108 |
+
if ( preg_match( "@^$pattern$@i", $a_needle ) ) {
|
1109 |
+
|
1110 |
+
self::$stat[ 'id' ] = $_return_error_code[ 0 ];
|
1111 |
+
self::_set_error_array( $_return_error_code[ 1 ], $_return_error_code[ 2 ] );
|
1112 |
+
return true;
|
1113 |
+
}
|
1114 |
+
}
|
1115 |
+
}
|
1116 |
+
|
1117 |
+
return false;
|
1118 |
+
}
|
1119 |
+
|
1120 |
+
public static function is_local_ip_address( $ip_address = '' ) {
|
1121 |
+
if ( !filter_var( $ip_address, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) {
|
1122 |
+
return true;
|
1123 |
+
}
|
1124 |
+
|
1125 |
+
return false;
|
1126 |
+
}
|
1127 |
+
|
1128 |
+
public static function dtr_pton( $ip ){
|
1129 |
+
if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) {
|
1130 |
+
$unpacked = unpack( 'A4', inet_pton( $ip ) );
|
1131 |
+
}
|
1132 |
+
else if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) && defined( 'AF_INET6' ) ) {
|
1133 |
+
$unpacked = unpack( 'A16', inet_pton( $ip ) );
|
1134 |
+
}
|
1135 |
+
|
1136 |
+
$binary_ip = '';
|
1137 |
+
if ( !empty( $unpacked ) ) {
|
1138 |
+
$unpacked = str_split( $unpacked[ 1 ] );
|
1139 |
+
foreach ( $unpacked as $char ) {
|
1140 |
+
$binary_ip .= str_pad( decbin( ord( $char ) ), 8, '0', STR_PAD_LEFT );
|
1141 |
+
}
|
1142 |
+
}
|
1143 |
+
|
1144 |
+
return $binary_ip;
|
1145 |
+
}
|
1146 |
+
|
1147 |
+
public static function get_mask_length( $ip ){
|
1148 |
+
if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) {
|
1149 |
+
return 32;
|
1150 |
+
}
|
1151 |
+
else if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
|
1152 |
+
return 128;
|
1153 |
+
}
|
1154 |
+
|
1155 |
+
return false;
|
1156 |
+
}
|
1157 |
+
|
1158 |
+
/**
|
1159 |
+
* Opens given domains during CORS requests to admin-ajax.php
|
1160 |
+
*/
|
1161 |
+
public static function open_cors_admin_ajax( $_allowed_origins = array() ) {
|
1162 |
+
$exploded_domains = self::string_to_array( self::$settings[ 'external_domains' ] );
|
1163 |
+
|
1164 |
+
if ( !empty( $exploded_domains ) && !empty( $exploded_domains[ 0 ] ) ) {
|
1165 |
+
$_allowed_origins = array_merge( $_allowed_origins, $exploded_domains );
|
1166 |
+
}
|
1167 |
+
|
1168 |
+
return $_allowed_origins;
|
1169 |
+
}
|
1170 |
+
|
1171 |
+
/**
|
1172 |
+
* Downloads the MaxMind geolocation database from their repository
|
1173 |
+
*/
|
1174 |
+
public static function download_maxmind_database() {
|
1175 |
+
// Create the folder, if it doesn't exist
|
1176 |
+
if ( !file_exists( dirname( self::$maxmind_path ) ) ) {
|
1177 |
+
mkdir( dirname( self::$maxmind_path ) );
|
1178 |
+
}
|
1179 |
+
|
1180 |
+
if ( file_exists( self::$maxmind_path ) ) {
|
1181 |
+
if ( is_file( self::$maxmind_path ) ) {
|
1182 |
+
$is_deleted = @unlink( self::$maxmind_path );
|
1183 |
+
}
|
1184 |
+
else {
|
1185 |
+
// This should not happen, but hey...
|
1186 |
+
$is_deleted = @rmdir( self::$maxmind_path );
|
1187 |
+
}
|
1188 |
+
|
1189 |
+
if ( !$is_deleted ) {
|
1190 |
+
return __( "The geolocation database cannot be updated. Please check your server's file permissions and try again.", 'wp-slimstat' );
|
1191 |
+
}
|
1192 |
+
}
|
1193 |
+
|
1194 |
+
// Download the most recent database directly from MaxMind's repository
|
1195 |
+
if ( self::$settings[ 'geolocation_country' ] == 'on' ) {
|
1196 |
+
$maxmind_tmp = self::download_url( 'http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz' );
|
1197 |
+
}
|
1198 |
+
else {
|
1199 |
+
$maxmind_tmp = self::download_url( 'http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz' );
|
1200 |
+
}
|
1201 |
+
|
1202 |
+
if ( is_wp_error( $maxmind_tmp ) ) {
|
1203 |
+
return __( 'There was an error downloading the MaxMind Geolite DB:', 'wp-slimstat' ) . ' ' . $maxmind_tmp->get_error_message();
|
1204 |
+
}
|
1205 |
+
|
1206 |
+
$zh = false;
|
1207 |
+
|
1208 |
+
if ( !function_exists( 'gzopen' ) ) {
|
1209 |
+
if ( function_exists( 'gzopen64' ) ) {
|
1210 |
+
if ( false === ( $zh = gzopen64( $maxmind_tmp, 'rb' ) ) ) {
|
1211 |
+
return __( 'There was an error opening the zipped MaxMind Geolite DB.', 'wp-slimstat' );
|
1212 |
+
}
|
1213 |
+
}
|
1214 |
+
else {
|
1215 |
+
return __( 'Function gzopen not defined. Aborting.', 'wp-slimstat' );
|
1216 |
+
}
|
1217 |
+
}
|
1218 |
+
else{
|
1219 |
+
if ( false === ( $zh = gzopen( $maxmind_tmp, 'rb' ) ) ) {
|
1220 |
+
return __( 'There was an error opening the zipped MaxMind Geolite DB.', 'wp-slimstat' );
|
1221 |
+
}
|
1222 |
+
}
|
1223 |
+
|
1224 |
+
if ( false === ( $fh = fopen( self::$maxmind_path, 'wb' ) ) ) {
|
1225 |
+
return __( 'There was an error opening the MaxMind Geolite DB.', 'wp-slimstat' );
|
1226 |
+
}
|
1227 |
+
|
1228 |
+
while ( ( $data = gzread( $zh, 4096 ) ) != false ) {
|
1229 |
+
fwrite( $fh, $data );
|
1230 |
+
}
|
1231 |
+
|
1232 |
+
@gzclose( $zh );
|
1233 |
+
@fclose( $fh );
|
1234 |
+
|
1235 |
+
if ( !is_file( self::$maxmind_path ) ) {
|
1236 |
+
// Something went wrong, maybe a folder was created instead of a regular file
|
1237 |
+
@rmdir( self::$maxmind_path );
|
1238 |
+
return __( 'There was an error creating the MaxMind Geolite DB.', 'wp-slimstat' );
|
1239 |
+
}
|
1240 |
+
|
1241 |
+
@unlink( $maxmind_tmp );
|
1242 |
+
|
1243 |
+
return '';
|
1244 |
+
}
|
1245 |
+
|
1246 |
+
public static function download_url( $url ) {
|
1247 |
+
// Include the FILE API, if it's not defined
|
1248 |
+
if ( !function_exists( 'download_url' ) ) {
|
1249 |
+
require_once( ABSPATH . 'wp-admin/includes/file.php' );
|
1250 |
+
}
|
1251 |
+
|
1252 |
+
if ( !$url ) {
|
1253 |
+
return new WP_Error('http_no_url', __('Invalid URL Provided.'));
|
1254 |
+
}
|
1255 |
+
|
1256 |
+
$url_filename = basename( parse_url( $url, PHP_URL_PATH ) );
|
1257 |
+
|
1258 |
+
$tmpfname = wp_tempnam( $url_filename );
|
1259 |
+
if ( ! $tmpfname ) {
|
1260 |
+
return new WP_Error('http_no_file', __('Could not create Temporary file.'));
|
1261 |
+
}
|
1262 |
+
|
1263 |
+
$response = wp_safe_remote_get( $url, array( 'timeout' => 300, 'stream' => true, 'filename' => $tmpfname, 'user-agent' => 'Slimstat Analytics/' . self::$version . '; ' . home_url() ) );
|
1264 |
+
|
1265 |
+
if ( is_wp_error( $response ) ) {
|
1266 |
+
unlink( $tmpfname );
|
1267 |
+
return $response;
|
1268 |
+
}
|
1269 |
+
|
1270 |
+
if ( 200 != wp_remote_retrieve_response_code( $response ) ){
|
1271 |
+
unlink( $tmpfname );
|
1272 |
+
return new WP_Error( 'http_404', trim( wp_remote_retrieve_response_message( $response ) ) );
|
1273 |
+
}
|
1274 |
+
|
1275 |
+
return $tmpfname;
|
1276 |
+
}
|
1277 |
+
|
1278 |
+
public static function slimstat_shortcode( $_attributes = '', $_content = '' ) {
|
1279 |
+
extract( shortcode_atts( array(
|
1280 |
+
'f' => '', // recent, popular, count, widget
|
1281 |
+
'w' => '', // column to use (for recent, popular and count) or widget to use
|
1282 |
+
's' => ' ', // separator
|
1283 |
+
'o' => 0 // offset for counters
|
1284 |
+
), $_attributes));
|
1285 |
+
|
1286 |
+
$output = $where = $as_column = '';
|
1287 |
+
$s = "<span class='slimstat-item-separator'>$s</span>";
|
1288 |
+
|
1289 |
+
// Load the localization files (for languages, operating systems, etc)
|
1290 |
+
load_plugin_textdomain( 'wp-slimstat', WP_PLUGIN_DIR .'/wp-slimstat/languages', '/wp-slimstat/languages' );
|
1291 |
+
|
1292 |
+
// Look for required fields
|
1293 |
+
if ( empty( $f ) || empty( $w ) ) {
|
1294 |
+
return '<!-- Slimstat Shortcode Error: missing parameter -->';
|
1295 |
+
}
|
1296 |
+
|
1297 |
+
// Include the Reports Library, but don't initialize the database, since we will do that separately later
|
1298 |
+
include_once( dirname(__FILE__) . '/admin/view/wp-slimstat-reports.php' );
|
1299 |
+
wp_slimstat_reports::init();
|
1300 |
+
|
1301 |
+
// Init the database library with the appropriate filters
|
1302 |
+
if ( strpos ( $_content, 'WHERE:' ) !== false ) {
|
1303 |
+
$where = html_entity_decode( str_replace( 'WHERE:', '', $_content ), ENT_QUOTES, 'UTF-8' );
|
1304 |
+
// wp_slimstat_db::init();
|
1305 |
+
}
|
1306 |
+
else{
|
1307 |
+
wp_slimstat_db::init( html_entity_decode( $_content, ENT_QUOTES, 'UTF-8' ) );
|
1308 |
+
}
|
1309 |
+
|
1310 |
+
switch( $f ) {
|
1311 |
+
case 'count':
|
1312 |
+
case 'count-all':
|
1313 |
+
$output = wp_slimstat_db::count_records( $w, $where, strpos( $f, 'all') === false ) + $o;
|
1314 |
+
break;
|
1315 |
+
|
1316 |
+
case 'widget':
|
1317 |
+
if ( empty( wp_slimstat_reports::$reports_info[ $w ] ) ) {
|
1318 |
+
return __( 'Undefined report ID', 'wp-slimstat' );
|
1319 |
+
}
|
1320 |
+
|
1321 |
+
wp_register_style( 'wp-slimstat-frontend', plugins_url( '/admin/css/slimstat.frontend.css', __FILE__ ) );
|
1322 |
+
wp_enqueue_style( 'wp-slimstat-frontend' );
|
1323 |
+
|
1324 |
+
ob_start();
|
1325 |
+
echo wp_slimstat_reports::report_header( $w );
|
1326 |
+
call_user_func( wp_slimstat_reports::$reports_info[ $w ][ 'callback' ], wp_slimstat_reports::$reports_info[ $w ][ 'callback_args' ] );
|
1327 |
+
wp_slimstat_reports::report_footer();
|
1328 |
+
$output = ob_get_contents();
|
1329 |
+
ob_end_clean();
|
1330 |
+
break;
|
1331 |
+
|
1332 |
+
case 'recent':
|
1333 |
+
case 'recent-all':
|
1334 |
+
case 'top':
|
1335 |
+
case 'top-all':
|
1336 |
+
$function = 'get_' . str_replace( '-all', '', $f );
|
1337 |
+
|
1338 |
+
if ( $w == '*' ) {
|
1339 |
+
$w = 'id';
|
1340 |
+
}
|
1341 |
+
|
1342 |
+
$w = self::string_to_array( $w );
|
1343 |
+
|
1344 |
+
// Some columns are 'special' and need be removed from the list
|
1345 |
+
$w_clean = array_diff( $w, array( 'count', 'display_name', 'hostname', 'post_link', 'post_link_no_qs', 'dt' ) );
|
1346 |
+
|
1347 |
+
// The special value 'display_name' requires the username to be retrieved
|
1348 |
+
if ( in_array( 'display_name', $w ) ) {
|
1349 |
+
$w_clean[] = 'username';
|
1350 |
+
}
|
1351 |
+
|
1352 |
+
// The special value 'post_list' requires the resource to be retrieved
|
1353 |
+
if ( in_array( 'post_link', $w ) ) {
|
1354 |
+
$w_clean[] = 'resource';
|
1355 |
+
}
|
1356 |
+
|
1357 |
+
// The special value 'post_list_no_qs' requires a substring to be calculated
|
1358 |
+
if ( in_array( 'post_link_no_qs', $w ) ) {
|
1359 |
+
$w_clean = array( 'SUBSTRING_INDEX( resource, "' . ( !get_option( 'permalink_structure' ) ? '&' : '?' ) . '", 1 )' );
|
1360 |
+
$as_column = 'resource_calculated';
|
1361 |
+
}
|
1362 |
+
|
1363 |
+
// Retrieve the data
|
1364 |
+
$results = wp_slimstat_db::$function( implode( ', ', $w_clean ), $where, '', strpos( $f, 'all' ) === false, $as_column );
|
1365 |
+
|
1366 |
+
// No data? No problem!
|
1367 |
+
if ( empty( $results ) ) {
|
1368 |
+
return '<!-- Slimstat Shortcode: No Data -->';
|
1369 |
+
}
|
1370 |
+
|
1371 |
+
// Are nice permalinks enabled?
|
1372 |
+
$permalinks_enabled = get_option( 'permalink_structure' );
|
1373 |
+
|
1374 |
+
// Format results
|
1375 |
+
$output = array();
|
1376 |
+
foreach( $results as $result_idx => $a_result ) {
|
1377 |
+
foreach( $w as $a_column ) {
|
1378 |
+
$output[ $result_idx ][ $a_column ] = "<span class='col-$a_column'>";
|
1379 |
+
|
1380 |
+
switch( $a_column ) {
|
1381 |
+
case 'count':
|
1382 |
+
$output[ $result_idx ][ $a_column ] .= $a_result[ 'counthits' ];
|
1383 |
+
break;
|
1384 |
+
|
1385 |
+
case 'country':
|
1386 |
+
$output[ $result_idx ][ $a_column ] .= __( 'c-' . $a_result[ $a_column ], 'wp-slimstat' );
|
1387 |
+
break;
|
1388 |
+
|
1389 |
+
case 'display_name':
|
1390 |
+
$user_details = get_user_by( 'login', $a_result[ 'username' ] );
|
1391 |
+
if ( !empty( $user_details ) ) {
|
1392 |
+
$output[ $result_idx ][ $a_column ] .= $user_details->display_name;
|
1393 |
+
}
|
1394 |
+
else {
|
1395 |
+
$output[ $result_idx ][ $a_column ] .= $a_result[ 'username' ];
|
1396 |
+
}
|
1397 |
+
|
1398 |
+
break;
|
1399 |
+
|
1400 |
+
case 'dt':
|
1401 |
+
$output[ $result_idx ][ $a_column ] .= date_i18n( self::$settings[ 'date_format' ] . ' ' . self::$settings[ 'time_format' ], $a_result[ 'dt' ] );
|
1402 |
+
break;
|
1403 |
+
|
1404 |
+
case 'hostname':
|
1405 |
+
$output[ $result_idx ][ $a_column ] .= gethostbyaddr( $a_result[ 'ip' ] );
|
1406 |
+
break;
|
1407 |
+
|
1408 |
+
case 'language':
|
1409 |
+
$output[ $result_idx ][ $a_column ] .= __( 'l-' . $a_result[ $a_column ], 'wp-slimstat' );
|
1410 |
+
break;
|
1411 |
+
|
1412 |
+
case 'platform':
|
1413 |
+
$output[ $result_idx ][ $a_column ] .= __( $a_result[ $a_column ], 'wp-slimstat' );
|
1414 |
+
break;
|
1415 |
+
|
1416 |
+
case 'post_link':
|
1417 |
+
case 'post_link_no_qs':
|
1418 |
+
$resource_key = ( $a_column == 'post_link' ) ? 'resource' : 'resource_calculated';
|
1419 |
+
$post_id = url_to_postid( $a_result[ $resource_key ] );
|
1420 |
+
if ( $post_id > 0 ) {
|
1421 |
+
$output[ $result_idx ][ $a_column ] .= "<a href='{$a_result[ $resource_key ]}'>" . get_the_title( $post_id ) . '</a>';
|
1422 |
+
}
|
1423 |
+
else {
|
1424 |
+
$output[ $result_idx ][ $a_column ] .= "<a href='{$a_result[ $resource_key ]}'>{$a_result[ $resource_key ]}</a>";
|
1425 |
+
}
|
1426 |
+
break;
|
1427 |
+
|
1428 |
+
default:
|
1429 |
+
$output[ $result_idx ][ $a_column ] .= $a_result[ $a_column ];
|
1430 |
+
break;
|
1431 |
+
}
|
1432 |
+
$output[ $result_idx ][ $a_column ] .= '</span>';
|
1433 |
+
}
|
1434 |
+
$output[ $result_idx ] = '<li>' . implode( $s, $output[ $result_idx ] ). '</li>';
|
1435 |
+
}
|
1436 |
+
|
1437 |
+
$output = '<ul class="slimstat-shortcode ' . $f . implode( '-', $w ). '">' . implode( '', $output ) . '</ul>';
|
1438 |
+
break;
|
1439 |
+
|
1440 |
+
default:
|
1441 |
+
break;
|
1442 |
+
}
|
1443 |
+
|
1444 |
+
return $output;
|
1445 |
+
}
|
1446 |
+
|
1447 |
+
public static function rest_api_response( $_request = array() ) {
|
1448 |
+
$filters = '';
|
1449 |
+
if ( !empty( $_request[ 'filters' ] ) ) {
|
1450 |
+
$filters = $_request[ 'filters' ];
|
1451 |
+
}
|
1452 |
+
|
1453 |
+
if ( empty( $_request[ 'dimension' ] ) ) {
|
1454 |
+
return new WP_Error( 'rest_invalid', esc_html__( 'The dimension parameter is required. Please review your request and try again.', 'wp-slimstat' ), array( 'status' => 400 ) );
|
1455 |
+
}
|
1456 |
+
|
1457 |
+
if ( empty( $_request[ 'function' ] ) ) {
|
1458 |
+
return new WP_Error( 'rest_invalid', esc_html__( 'The function parameter is required. Please review your request and try again.', 'wp-slimstat' ), array( 'status' => 400 ) );
|
1459 |
+
}
|
1460 |
+
|
1461 |
+
include_once( dirname(__FILE__) . '/admin/view/wp-slimstat-db.php' );
|
1462 |
+
wp_slimstat_db::init( $filters );
|
1463 |
+
|
1464 |
+
$response = array(
|
1465 |
+
'function' => htmlentities( $_request[ 'function' ], ENT_QUOTES, 'UTF-8' ),
|
1466 |
+
'dimension' => htmlentities( $_request[ 'dimension' ], ENT_QUOTES, 'UTF-8' ),
|
1467 |
+
|
1468 |
+
'data' => 0
|
1469 |
+
);
|
1470 |
+
|
1471 |
+
switch( $_request[ 'function' ] ) {
|
1472 |
+
case 'count':
|
1473 |
+
case 'count-all':
|
1474 |
+
$response[ 'data' ] = wp_slimstat_db::count_records( $_request[ 'dimension' ], '', strpos( $_request[ 'function' ], '-all') === false );
|
1475 |
+
break;
|
1476 |
+
|
1477 |
+
case 'recent':
|
1478 |
+
case 'recent-all':
|
1479 |
+
case 'top':
|
1480 |
+
case 'top-all':
|
1481 |
+
$function = 'get_' . str_replace( '-all', '', $_request[ 'function' ] );
|
1482 |
+
|
1483 |
+
// Retrieve the data
|
1484 |
+
$response[ 'data' ] = array_values( wp_slimstat_db::$function( $_request[ 'dimension' ], '', '', strpos( $_request[ 'function' ], '-all' ) === false ) );
|
1485 |
+
break;
|
1486 |
+
|
1487 |
+
default:
|
1488 |
+
// This should never happen, because of the 'enum' condition for this parameter. But never say never...
|
1489 |
+
$response[ 'data' ] = new WP_Error( 'rest_invalid', esc_html__( 'Valid function values are count, count-all, recent, recent-all, top and top-all. Please review your request and try again.', 'wp-slimstat' ), array( 'status' => 400 ) );
|
1490 |
+
break;
|
1491 |
+
}
|
1492 |
+
|
1493 |
+
return rest_ensure_response( $response );
|
1494 |
+
}
|
1495 |
+
|
1496 |
+
public static function rest_api_authorization( $_request = array() ) {
|
1497 |
+
if ( empty( $_request[ 'token' ] ) ) {
|
1498 |
+
return new WP_Error( 'rest_invalid', esc_html__( 'Please specify a valid token in order to access this REST API.', 'wp-slimstat' ), array( 'status' => 400 ) );
|
1499 |
+
}
|
1500 |
+
|
1501 |
+
if ( !in_array( $_request[ 'token' ], self::string_to_array( self::$settings['rest_api_tokens'] ) ) ) {
|
1502 |
+
return false;
|
1503 |
+
}
|
1504 |
+
|
1505 |
+
return true;
|
1506 |
+
}
|
1507 |
+
|
1508 |
+
public static function register_rest_route() {
|
1509 |
+
register_rest_route( 'slimstat/v1', '/get', array(
|
1510 |
+
'methods' => WP_REST_Server::READABLE,
|
1511 |
+
'callback' => array( __CLASS__, 'rest_api_response' ),
|
1512 |
+
'permission_callback' => array( __CLASS__, 'rest_api_authorization' ),
|
1513 |
+
'args' => array(
|
1514 |
+
'token' => array(
|
1515 |
+
'description' => __( 'You will need to specify a valid token to be able to query the data. Tokens are defined in Slimstat > Settings > Access Control.', 'wp-slimstat' ),
|
1516 |
+
'type' => 'string'
|
1517 |
+
),
|
1518 |
+
'function' => array(
|
1519 |
+
'description' => __( 'This parameter specifies the type of QUERY for the dimension. Valid values are: count, count-all, recent, recent-all, top and top-all.', 'wp-slimstat' ),
|
1520 |
+
'type' => 'string',
|
1521 |
+
'enum' => array( 'count', 'count-all', 'recent', 'recent-all', 'top', 'top-all' )
|
1522 |
+
),
|
1523 |
+
'dimension' => array(
|
1524 |
+
'description' => __( 'This parameter indicates what dimension to return: * (all data), ip, resource, browser, operating system, etc. You can only specify one dimension at a time.', 'wp-slimstat' ),
|
1525 |
+
'type' => 'string',
|
1526 |
+
'enum' => array( '*', 'id', 'ip', 'username', 'country', 'referer', 'resource', 'searchterms', 'browser', 'platform', 'language', 'resolution', 'content_type', 'content_id', 'outbound_resource' )
|
1527 |
+
),
|
1528 |
+
'filters' => array(
|
1529 |
+
'description' => __( 'This parameter is used to filter a given dimension (resources, browsers, operating systems, etc) so that it satisfies certain conditions (i.e.: browser contains Chrome). Please make sure to urlencode this value, and to use the usual filter format: browser contains Chrome&&&referer contains slim (encoded: browser%20contains%20Chrome%26%26%26referer%20contains%20slim)', 'wp-slimstat' ),
|
1530 |
+
'type' => 'string'
|
1531 |
+
)
|
1532 |
+
)
|
1533 |
+
) );
|
1534 |
+
}
|
1535 |
+
|
1536 |
+
/**
|
1537 |
+
* Converts a series of comma separated values into an array
|
1538 |
+
*/
|
1539 |
+
public static function string_to_array( $_option = '' ) {
|
1540 |
+
if ( empty( $_option ) || !is_string( $_option ) ) {
|
1541 |
+
return array();
|
1542 |
+
}
|
1543 |
+
else {
|
1544 |
+
return array_filter( array_map( 'trim', explode( ',', $_option ) ) );
|
1545 |
+
}
|
1546 |
+
}
|
1547 |
+
|
1548 |
+
/**
|
1549 |
+
* Toggles WordPress filters on date_i18n function
|
1550 |
+
*/
|
1551 |
+
public static function toggle_date_i18n_filters( $_turn_on = true ) {
|
1552 |
+
if ( $_turn_on && !empty( self::$date_i18n_filters ) && is_array( self::$date_i18n_filters ) ) {
|
1553 |
+
foreach ( self::$date_i18n_filters as $i18n_priority => $i18n_func_list ) {
|
1554 |
+
foreach ( $i18n_func_list as $func_name => $func_args ) {
|
1555 |
+
if ( !empty( $func_args[ 'function' ] ) && is_string( $func_args[ 'function' ] ) ) {
|
1556 |
+
add_filter( 'date_i8n', $func_args[ 'function' ], $i18n_priority, intval( $func_args[ 'accepted_args' ] ) );
|
1557 |
+
}
|
1558 |
+
}
|
1559 |
+
}
|
1560 |
+
}
|
1561 |
+
else if ( !empty( $GLOBALS[ 'wp_filter' ][ 'date_i18n' ][ 'callbacks' ] ) && is_array( $GLOBALS[ 'wp_filter' ][ 'date_i18n' ][ 'callbacks' ] ) ) {
|
1562 |
+
self::$date_i18n_filters = $GLOBALS[ 'wp_filter' ][ 'date_i18n' ][ 'callbacks' ];
|
1563 |
+
remove_all_filters( 'date_i18n' );
|
1564 |
+
}
|
1565 |
+
}
|
1566 |
+
|
1567 |
+
/**
|
1568 |
+
* Imports all the 'old' options into the new array, and saves them
|
1569 |
+
*/
|
1570 |
+
public static function init_options(){
|
1571 |
+
return array(
|
1572 |
+
'version' => self::$version,
|
1573 |
+
'secret' => wp_hash( uniqid( time(), true ) ),
|
1574 |
+
'show_admin_notice' => 0,
|
1575 |
+
'browscap_last_modified' => 0,
|
1576 |
+
|
1577 |
+
// General
|
1578 |
+
'is_tracking' => 'on',
|
1579 |
+
'javascript_mode' => 'on',
|
1580 |
+
'enable_javascript' => 'on',
|
1581 |
+
'track_admin_pages' => 'no',
|
1582 |
+
'use_separate_menu' => 'on',
|
1583 |
+
'add_posts_column' => 'no',
|
1584 |
+
'posts_column_day_interval' => 30,
|
1585 |
+
'posts_column_pageviews' => 'on',
|
1586 |
+
'add_dashboard_widgets' => 'on',
|
1587 |
+
'hide_addons' => 'no',
|
1588 |
+
'auto_purge' => 0,
|
1589 |
+
'auto_purge_delete' => 'on',
|
1590 |
+
|
1591 |
+
// Tracker
|
1592 |
+
'do_not_track_outbound_classes_rel_href' => 'noslimstat,ab-item',
|
1593 |
+
'extensions_to_track' => 'pdf,doc,xls,zip',
|
1594 |
+
'track_same_domain_referers' => 'on',
|
1595 |
+
'geolocation_country' => 'on',
|
1596 |
+
'session_duration' => 1800,
|
1597 |
+
'extend_session' => 'no',
|
1598 |
+
'set_tracker_cookie' => 'on',
|
1599 |
+
'enable_cdn' => 'on',
|
1600 |
+
'ajax_relative_path' => 'no',
|
1601 |
+
'external_domains' => '',
|
1602 |
+
|
1603 |
+
// Filters
|
1604 |
+
'track_users' => 'on',
|
1605 |
+
'ignore_spammers' => 'on',
|
1606 |
+
'ignore_bots' => 'no',
|
1607 |
+
'ignore_prefetch' => 'on',
|
1608 |
+
'anonymize_ip' => 'no',
|
1609 |
+
|
1610 |
+
'ignore_users' => '',
|
1611 |
+
'ignore_ip' => '',
|
1612 |
+
'ignore_countries' => '',
|
1613 |
+
'ignore_browsers' => '',
|
1614 |
+
'ignore_platforms' => '',
|
1615 |
+
'ignore_capabilities' => '',
|
1616 |
+
|
1617 |
+
'ignore_resources' => '',
|
1618 |
+
'ignore_referers' => '',
|
1619 |
+
'ignore_content_types' => '',
|
1620 |
+
|
1621 |
+
// Reports
|
1622 |
+
'use_european_separators' => 'on',
|
1623 |
+
'date_format' => 'm-d-y',
|
1624 |
+
'time_format' => 'h:i a',
|
1625 |
+
'show_display_name' => 'no',
|
1626 |
+
'convert_resource_urls_to_titles' => 'on',
|
1627 |
+
'convert_ip_addresses' => 'no',
|
1628 |
+
'async_load' => 'no',
|
1629 |
+
'use_current_month_timespan' => 'no',
|
1630 |
+
'expand_details' => 'no',
|
1631 |
+
'rows_to_show' => '20',
|
1632 |
+
'limit_results' => '1000',
|
1633 |
+
'ip_lookup_service' => 'http://www.infosniper.net/?ip_address=',
|
1634 |
+
'mozcom_access_id' => '',
|
1635 |
+
'mozcom_secret_key' => '',
|
1636 |
+
'refresh_interval' => '60',
|
1637 |
+
'number_results_raw_data' => '50',
|
1638 |
+
'max_dots_on_map' => '50',
|
1639 |
+
'custom_css' => '',
|
1640 |
+
'chart_colors' => '',
|
1641 |
+
'comparison_chart' => 'on',
|
1642 |
+
'show_complete_user_agent_tooltip' => 'no',
|
1643 |
+
'enable_sov' => 'no',
|
1644 |
+
|
1645 |
+
// Access Control
|
1646 |
+
'restrict_authors_view' => 'on',
|
1647 |
+
'capability_can_view' => 'activate_plugins',
|
1648 |
+
'can_view' => '',
|
1649 |
+
'rest_api_tokens' => wp_hash( uniqid( time() - 3600, true ) ),
|
1650 |
+
'capability_can_admin' => 'activate_plugins',
|
1651 |
+
'can_admin' => '',
|
1652 |
+
|
1653 |
+
// Maintenance
|
1654 |
+
'last_tracker_error' => array( 0, '', 0 ),
|
1655 |
+
'show_sql_debug' => 'no',
|
1656 |
+
'no_maxmind_warning' => 'no',
|
1657 |
+
'no_browscap_warning' => 'no',
|
1658 |
+
|
1659 |
+
// Network-wide Settings
|
1660 |
+
'locked_options' => ''
|
1661 |
+
);
|
1662 |
+
}
|
1663 |
+
// end init_options
|
1664 |
+
|
1665 |
+
/**
|
1666 |
+
* Saves the options in the database, if necessary
|
1667 |
+
*/
|
1668 |
+
public static function slimstat_save_options() {
|
1669 |
+
// Allow third-party functions to manipulate the options right before they are saved
|
1670 |
+
self::$settings = apply_filters( 'slimstat_save_options', self::$settings );
|
1671 |
+
|
1672 |
+
if ( self::$settings_signature === md5( serialize( self::$settings ) ) ) {
|
1673 |
+
return true;
|
1674 |
+
}
|
1675 |
+
|
1676 |
+
if ( !is_network_admin() ) {
|
1677 |
+
update_option( 'slimstat_options', self::$settings );
|
1678 |
+
}
|
1679 |
+
else {
|
1680 |
+
update_site_option( 'slimstat_options', self::$settings );
|
1681 |
+
}
|
1682 |
+
|
1683 |
+
return true;
|
1684 |
+
}
|
1685 |
+
|
1686 |
+
/**
|
1687 |
+
* Enqueue a javascript to track users' screen resolution and other browser-based information
|
1688 |
+
*/
|
1689 |
+
public static function wp_slimstat_enqueue_tracking_script() {
|
1690 |
+
// Do not enqueue the script if the corresponding options are turned off
|
1691 |
+
$is_tracking_filter_js = apply_filters( 'slimstat_filter_pre_tracking_js', true );
|
1692 |
+
if ( ( self::$settings[ 'enable_javascript' ] != 'on' && self::$settings[ 'javascript_mode' ] != 'on' ) || self::$settings[ 'is_tracking' ] != 'on' || !$is_tracking_filter_js ) {
|
1693 |
+
return 0;
|
1694 |
+
}
|
1695 |
+
|
1696 |
+
// Register the script in WordPress
|
1697 |
+
$jstracker_suffix = ( defined( 'SCRIPT_DEBUG' ) && is_bool( SCRIPT_DEBUG ) && SCRIPT_DEBUG ) ? '' : '.min';
|
1698 |
+
|
1699 |
+
// Pass some information to the tracker
|
1700 |
+
$params = array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) );
|
1701 |
+
|
1702 |
+
if ( self::$settings[ 'ajax_relative_path' ] == 'on' ) {
|
1703 |
+
$params[ 'ajaxurl' ] = admin_url( 'admin-ajax.php', 'relative' );
|
1704 |
+
}
|
1705 |
+
|
1706 |
+
if ( !empty( self::$settings[ 'extensions_to_track' ] ) ) {
|
1707 |
+
$params[ 'extensions_to_track' ] = str_replace( ' ', '', self::$settings[ 'extensions_to_track' ] );
|
1708 |
+
}
|
1709 |
+
if ( !empty( self::$settings[ 'do_not_track_outbound_classes_rel_href' ] ) ) {
|
1710 |
+
$params[ 'outbound_classes_rel_href_to_not_track' ] = str_replace( ' ', '', self::$settings[ 'do_not_track_outbound_classes_rel_href' ] );
|
1711 |
+
}
|
1712 |
+
|
1713 |
+
if ( self::$settings[ 'javascript_mode' ] != 'on' ) {
|
1714 |
+
// Do not enqueue the tracker if this page view was not tracked for some reason
|
1715 |
+
if ( intval( self::$stat[ 'id' ] ) < 0 ) {
|
1716 |
+
return false;
|
1717 |
+
}
|
1718 |
+
|
1719 |
+
if ( !empty( self::$stat[ 'id' ] ) ) {
|
1720 |
+
$params[ 'id' ] = self::_get_id_with_checksum( self::$stat[ 'id' ] );
|
1721 |
+
}
|
1722 |
+
else {
|
1723 |
+
$params[ 'id' ] = self::_get_id_with_checksum( '-300' );
|
1724 |
+
}
|
1725 |
+
}
|
1726 |
+
else {
|
1727 |
+
// Check filters and blacklists to see if this page should be tracked
|
1728 |
+
$simulate = self::slimtrack( array( 'slimtrack_simulate' => true ) );
|
1729 |
+
if ( empty( $simulate[ 'slimtrack_would_track' ] ) ) {
|
1730 |
+
return false;
|
1731 |
+
}
|
1732 |
+
|
1733 |
+
$encoded_ci = base64_encode( serialize( self::_get_content_info() ) );
|
1734 |
+
$params[ 'ci' ] = self::_get_id_with_checksum( $encoded_ci );
|
1735 |
+
}
|
1736 |
+
|
1737 |
+
$params = apply_filters( 'slimstat_js_params', $params );
|
1738 |
+
|
1739 |
+
if ( self::$settings[ 'enable_cdn' ] == 'on' ) {
|
1740 |
+
$schema = is_ssl() ? 'https' : 'http';
|
1741 |
+
wp_register_script( 'wp_slimstat', $schema . '://cdn.jsdelivr.net/wp/wp-slimstat/tags/' . self::$version . '/wp-slimstat.min.js', array(), null, true );
|
1742 |
+
}
|
1743 |
+
else{
|
1744 |
+
wp_register_script( 'wp_slimstat', plugins_url( "/wp-slimstat{$jstracker_suffix}.js", __FILE__ ), array(), null, true );
|
1745 |
+
}
|
1746 |
+
|
1747 |
+
wp_enqueue_script( 'wp_slimstat' );
|
1748 |
+
wp_localize_script( 'wp_slimstat', 'SlimStatParams', $params );
|
1749 |
+
}
|
1750 |
+
|
1751 |
+
/**
|
1752 |
+
* Removes old entries from the main table and performs other daily tasks
|
1753 |
+
*/
|
1754 |
+
public static function wp_slimstat_purge() {
|
1755 |
+
$autopurge_interval = intval( self::$settings[ 'auto_purge' ] );
|
1756 |
+
|
1757 |
+
if ( $autopurge_interval <= 0 ) {
|
1758 |
+
return;
|
1759 |
+
}
|
1760 |
+
|
1761 |
+
self::toggle_date_i18n_filters( false );
|
1762 |
+
$days_ago = strtotime( date_i18n( 'Y-m-d H:i:s' ) . " -$autopurge_interval days" );
|
1763 |
+
self::toggle_date_i18n_filters( true );
|
1764 |
+
|
1765 |
+
// Copy entries to the archive table, if needed
|
1766 |
+
if ( self::$settings[ 'auto_purge_delete' ] != 'no' ) {
|
1767 |
+
$is_copy_done = self::$wpdb->query("
|
1768 |
+
INSERT INTO {$GLOBALS['wpdb']->prefix}slim_stats_archive (id, ip, other_ip, username, country, location, city, referer, resource, searchterms, plugins, notes, visit_id, server_latency, page_performance, browser, browser_version, browser_type, platform, language, user_agent, resolution, screen_width, screen_height, content_type, category, author, content_id, outbound_resource, dt_out, dt)
|
1769 |
+
SELECT id, ip, other_ip, username, country, location, city, referer, resource, searchterms, plugins, notes, visit_id, server_latency, page_performance, browser, browser_version, browser_type, platform, language, user_agent, resolution, screen_width, screen_height, content_type, category, author, content_id, outbound_resource, dt_out, dt
|
1770 |
+
FROM {$GLOBALS[ 'wpdb' ]->prefix}slim_stats
|
1771 |
+
WHERE dt < $days_ago");
|
1772 |
+
|
1773 |
+
if ( $is_copy_done !== false ) {
|
1774 |
+
self::$wpdb->query("DELETE ts FROM {$GLOBALS[ 'wpdb' ]->prefix}slim_stats ts WHERE ts.dt < $days_ago");
|
1775 |
+
}
|
1776 |
+
|
1777 |
+
$is_copy_done = self::$wpdb->query("
|
1778 |
+
INSERT INTO {$GLOBALS['wpdb']->prefix}slim_events_archive (type, event_description, notes, position, id, dt)
|
1779 |
+
SELECT type, event_description, notes, position, id, dt
|
1780 |
+
FROM {$GLOBALS[ 'wpdb' ]->prefix}slim_events
|
1781 |
+
WHERE dt < $days_ago");
|
1782 |
+
|
1783 |
+
if ( $is_copy_done !== false ) {
|
1784 |
+
self::$wpdb->query("DELETE te FROM {$GLOBALS[ 'wpdb' ]->prefix}slim_events te WHERE te.dt < $days_ago");
|
1785 |
+
}
|
1786 |
+
}
|
1787 |
+
else {
|
1788 |
+
// Delete old entries
|
1789 |
+
self::$wpdb->query("DELETE ts FROM {$GLOBALS[ 'wpdb' ]->prefix}slim_stats ts WHERE ts.dt < $days_ago");
|
1790 |
+
self::$wpdb->query("DELETE te FROM {$GLOBALS[ 'wpdb' ]->prefix}slim_events te WHERE te.dt < $days_ago");
|
1791 |
+
}
|
1792 |
+
|
1793 |
+
// Optimize tables
|
1794 |
+
self::$wpdb->query( "OPTIMIZE TABLE {$GLOBALS[ 'wpdb' ]->prefix}slim_stats" );
|
1795 |
+
self::$wpdb->query( "OPTIMIZE TABLE {$GLOBALS[ 'wpdb' ]->prefix}slim_stats_archive" );
|
1796 |
+
self::$wpdb->query( "OPTIMIZE TABLE {$GLOBALS[ 'wpdb' ]->prefix}slim_events" );
|
1797 |
+
self::$wpdb->query( "OPTIMIZE TABLE {$GLOBALS[ 'wpdb' ]->prefix}slim_events_archive" );
|
1798 |
+
}
|
1799 |
+
|
1800 |
+
/**
|
1801 |
+
* Checks for add-on updates
|
1802 |
+
*/
|
1803 |
+
public static function update_checker() {
|
1804 |
+
if ( empty( self::$update_checker ) || !is_admin() ) {
|
1805 |
+
return true;
|
1806 |
+
}
|
1807 |
+
|
1808 |
+
$update_checker_objects = array();
|
1809 |
+
|
1810 |
+
// This is only included if add-ons are installed
|
1811 |
+
include_once( plugin_dir_path( __FILE__ ) . 'admin/update-checker/plugin-update-checker.php' );
|
1812 |
+
|
1813 |
+
foreach ( self::$update_checker as $a_slug ) {
|
1814 |
+
$a_clean_slug = str_replace( array( 'wp_slimstat_', '_' ), array( '', '-' ), $a_slug );
|
1815 |
+
|
1816 |
+
if ( !empty( self::$settings[ 'addon_licenses' ][ 'wp-slimstat-' . $a_clean_slug ] ) ) {
|
1817 |
+
$update_checker_objects[ $a_clean_slug ] = Puc_v4_Factory::buildUpdateChecker( 'http://www.wp-slimstat.com/update-checker/?slug=' . $a_clean_slug . '&key=' . urlencode( self::$settings[ 'addon_licenses' ][ 'wp-slimstat-' . $a_clean_slug ] ), dirname( dirname( __FILE__ ) ) . '/wp-slimstat-' . $a_clean_slug . '/index.php', 'wp-slimstat-' . $a_clean_slug );
|
1818 |
+
|
1819 |
+
add_filter( "plugin_action_links_wp-slimstat-{$a_clean_slug}/index.php", array( __CLASS__, 'add_plugin_manual_download_link' ), 10, 2 );
|
1820 |
+
}
|
1821 |
+
}
|
1822 |
+
}
|
1823 |
+
|
1824 |
+
public static function add_plugin_manual_download_link( $_links = array(), $_plugin_file = '' ) {
|
1825 |
+
$a_clean_slug = str_replace( array( 'wp-slimstat-', '/index.php' ), array( '', '' ), $_plugin_file );
|
1826 |
+
|
1827 |
+
if ( false !== ( $download_url = get_transient( 'wp-slimstat-download-link-' . $a_clean_slug ) ) ) {
|
1828 |
+
$_links[] = '<a href="' . $download_url . '">Download ZIP</a>';
|
1829 |
+
}
|
1830 |
+
else {
|
1831 |
+
$url = 'http://www.wp-slimstat.com/update-checker/?slug=' . $a_clean_slug . '&key=' . urlencode( self::$settings[ 'addon_licenses' ][ 'wp-slimstat-' . $a_clean_slug ] );
|
1832 |
+
$response = wp_safe_remote_get( $url, array( 'timeout' => 300, 'user-agent' => 'Slimstat Analytics/' . self::$version . '; ' . home_url() ) );
|
1833 |
+
|
1834 |
+
if ( !is_wp_error( $response ) && 200 == wp_remote_retrieve_response_code( $response ) ) {
|
1835 |
+
$data = @json_decode( $response[ 'body' ] );
|
1836 |
+
|
1837 |
+
if ( is_object( $data ) ) {
|
1838 |
+
$_links[] = '<a href="' . $data->download_url . '">Download ZIP</a>';
|
1839 |
+
set_transient( 'wp-slimstat-download-link-' . $a_clean_slug, $data->download_url, 172800 ); // 48 hours
|
1840 |
+
}
|
1841 |
+
}
|
1842 |
+
}
|
1843 |
+
|
1844 |
+
return $_links;
|
1845 |
+
}
|
1846 |
+
|
1847 |
+
public static function register_widget() {
|
1848 |
+
return register_widget( "slimstat_widget" );
|
1849 |
+
}
|
1850 |
+
}
|
1851 |
+
// end of class declaration
|
1852 |
+
|
1853 |
+
class slimstat_widget extends WP_Widget {
|
1854 |
+
|
1855 |
+
/**
|
1856 |
+
* Sets up the widgets name etc
|
1857 |
+
*/
|
1858 |
+
public function __construct() {
|
1859 |
+
parent::__construct( 'slimstat_widget', 'SlimStat', array(
|
1860 |
+
'classname' => 'slimstat_widget',
|
1861 |
+
'description' => 'Add a SlimStat report to your sidebar',
|
1862 |
+
) );
|
1863 |
+
}
|
1864 |
+
|
1865 |
+
/**
|
1866 |
+
* Outputs the content of the widget
|
1867 |
+
*
|
1868 |
+
* @param array $args
|
1869 |
+
* @param array $instance
|
1870 |
+
*/
|
1871 |
+
public function widget( $args, $instance ) {
|
1872 |
+
extract( $instance );
|
1873 |
+
|
1874 |
+
$slimstat_widget_filters = empty( $slimstat_widget_filters ) ? '' : $slimstat_widget_filters;
|
1875 |
+
|
1876 |
+
if ( !empty( $slimstat_widget_id ) ) {
|
1877 |
+
echo do_shortcode( "[slimstat f='widget' w='{$slimstat_widget_id}']{$slimstat_widget_filters}[/slimstat]" );
|
1878 |
+
}
|
1879 |
+
else {
|
1880 |
+
echo '';
|
1881 |
+
}
|
1882 |
+
}
|
1883 |
+
|
1884 |
+
/**
|
1885 |
+
* Outputs the options form on admin
|
1886 |
+
*
|
1887 |
+
* @param array $instance The widget options
|
1888 |
+
*/
|
1889 |
+
public function form( $instance ) {
|
1890 |
+
// Let's build the dropdown
|
1891 |
+
include_once( dirname(__FILE__) . '/admin/view/wp-slimstat-reports.php' );
|
1892 |
+
wp_slimstat_reports::init();
|
1893 |
+
$select_options = '';
|
1894 |
+
$slimstat_widget_id = !empty( $instance[ 'slimstat_widget_id' ] ) ? $instance[ 'slimstat_widget_id' ] : '';
|
1895 |
+
$slimstat_widget_filters = !empty( $instance[ 'slimstat_widget_filters' ] ) ? $instance[ 'slimstat_widget_filters' ] : '';
|
1896 |
+
|
1897 |
+
foreach ( wp_slimstat_reports::$reports_info as $a_report_id => $a_report_info ) {
|
1898 |
+
$select_options .= "<option value='$a_report_id' " . ( ( $slimstat_widget_id == $a_report_id ) ? 'selected="selected"' : '' ) . ">{$a_report_info[ 'title' ]}</option>";
|
1899 |
+
}
|
1900 |
+
?>
|
1901 |
+
|
1902 |
+
<p>
|
1903 |
+
<label for="<?php echo esc_attr( $this->get_field_id( 'slimstat_widget_id' ) ); ?>">Widget</label>
|
1904 |
+
<select class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'slimstat_widget_id' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'slimstat_widget_id' ) ); ?>">
|
1905 |
+
<option value="">Select a widget</option>
|
1906 |
+
<?php echo $select_options ?>
|
1907 |
+
</select>
|
1908 |
+
</p>
|
1909 |
+
|
1910 |
+
<p>
|
1911 |
+
<label for="<?php echo esc_attr( $this->get_field_id( 'slimstat_widget_filters' ) ); ?>"><?php _e( 'Optional filters', 'wp-slimstat' ); ?></label>
|
1912 |
+
<a href="https://slimstat.freshdesk.com/solution/articles/5000631833-what-is-the-syntax-of-a-slimstat-shortcode-#slimstat-operators" target="_blank">[?]</a>
|
1913 |
+
<textarea class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'slimstat_widget_filters' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'slimstat_widget_filters' ) ); ?>"><?php echo trim( strip_tags( $slimstat_widget_filters ) ) ?></textarea>
|
1914 |
+
</p>
|
1915 |
+
<?php
|
1916 |
+
}
|
1917 |
+
|
1918 |
+
/**
|
1919 |
+
* Processing widget options on save
|
1920 |
+
*
|
1921 |
+
* @param array $new_instance The new options
|
1922 |
+
* @param array $old_instance The previous options
|
1923 |
+
*/
|
1924 |
+
public function update( $new_instance, $old_instance ) {
|
1925 |
+
$instance = $old_instance;
|
1926 |
+
|
1927 |
+
$instance[ 'slimstat_widget_id' ] = $new_instance[ 'slimstat_widget_id' ];
|
1928 |
+
$instance[ 'slimstat_widget_filters' ] = $new_instance[ 'slimstat_widget_filters' ];
|
1929 |
+
return $instance;
|
1930 |
+
}
|
1931 |
+
}
|
1932 |
+
|
1933 |
+
// Ok, let's go, Sparky!
|
1934 |
+
if ( function_exists( 'add_action' ) ) {
|
1935 |
+
// Since we use sendBeacon, this function sends raw POST data, which does not populate the $_POST variable automatically
|
1936 |
+
if ( ( !empty( $_SERVER[ 'HTTP_CONTENT_TYPE' ] ) || !empty( $_SERVER[ 'CONTENT_TYPE' ] ) ) && empty( $_POST ) ) {
|
1937 |
+
$raw_post_string = file_get_contents( 'php://input' );
|
1938 |
+
parse_str( $raw_post_string, wp_slimstat::$raw_post_array );
|
1939 |
+
}
|
1940 |
+
else if ( !empty( $_POST ) ) {
|
1941 |
+
wp_slimstat::$raw_post_array = $_POST;
|
1942 |
+
}
|
1943 |
+
|
1944 |
+
// Init the Ajax listener
|
1945 |
+
if ( !empty( wp_slimstat::$raw_post_array[ 'action' ] ) && wp_slimstat::$raw_post_array[ 'action' ] == 'slimtrack' ) {
|
1946 |
+
|
1947 |
+
// This is needed because admin-ajax.php is reading $_REQUEST to fire the corresponding action
|
1948 |
+
if ( empty( $_POST[ 'action' ] ) ) {
|
1949 |
+
$_POST[ 'action' ] = wp_slimstat::$raw_post_array[ 'action' ];
|
1950 |
+
}
|
1951 |
+
|
1952 |
+
add_action( 'wp_ajax_nopriv_slimtrack', array( 'wp_slimstat', 'slimtrack_ajax' ) );
|
1953 |
+
add_action( 'wp_ajax_slimtrack', array( 'wp_slimstat', 'slimtrack_ajax' ) );
|
1954 |
+
}
|
1955 |
+
|
1956 |
+
// From the codex: You can't call register_activation_hook() inside a function hooked to the 'plugins_loaded' or 'init' hooks (or any other hook). These hooks are called before the plugin is loaded or activated.
|
1957 |
+
if ( is_admin() ) {
|
1958 |
+
include_once( WP_PLUGIN_DIR . '/wp-slimstat/admin/wp-slimstat-admin.php' );
|
1959 |
+
register_activation_hook( __FILE__, array( 'wp_slimstat_admin', 'init_environment' ) );
|
1960 |
+
register_deactivation_hook( __FILE__, array( 'wp_slimstat_admin', 'deactivate' ) );
|
1961 |
+
}
|
1962 |
+
|
1963 |
+
add_action( 'widgets_init', array( 'wp_slimstat', 'register_widget' ) );
|
1964 |
+
|
1965 |
+
// Add the appropriate actions
|
1966 |
+
add_action( 'plugins_loaded', array( 'wp_slimstat', 'init' ), 20 );
|
1967 |
+
}
|