Version Description
- [Note] The team who manages the WordPress Plugin Repository notified us that since the MaxMind GeoLite library used by Slimstat to geolocate visitors is released under the Creative Commons BY-SA 3.0 license, it violates the repository guidelines, and cannot be bundled with the plugin. We were required to remove the code and alter the plugin so that this functionality becomes optional. We apologize for the inconvenience. However, the only immediate consequence is that your visitors' country will not be identified; everything else will still work as usual. You can download the geolocation DB as a separate add-on on our store, free of charge. Don't forget to enter your license key in the corresponding field under Slimstat > Add-ons, to receive free updates!
- [New] A few new options under Slimstat > Settings > General tab > WordPress Integration section, allow you to have more control over the information displayed in the Posts admin screen (thank you, Brad).
Download this release
Release Info
Developer | coolmann |
Plugin | Slimstat Analytics |
Version | 3.9.8 |
Comparing to | |
See all releases |
Code changes from version 3.9.7.1 to 3.9.8
- admin/config/addons.php +3 -4
- admin/config/index.php +3 -1
- admin/view/wp-slimstat-db-new.php +881 -0
- admin/wp-slimstat-admin.php +25 -7
- readme.txt +14 -4
- wp-slimstat.php +6 -35
admin/config/addons.php
CHANGED
@@ -62,7 +62,7 @@ if (!is_array($list_addons)){
|
|
62 |
</th>
|
63 |
<td class="column-description desc">
|
64 |
<div class="plugin-description"><p><?php echo $a_addon['description'] ?></p></div>
|
65 |
-
<?php if ((is_plugin_active($a_addon['slug'].'/index.php') || is_plugin_active($a_addon['slug'].'/'.$a_addon['slug'].'.php'))
|
66 |
<div class="active second">
|
67 |
License Key: <input type="text" name="licenses[<?php echo $a_addon['slug'] ?>]" value="<?php echo !empty(wp_slimstat::$options['addon_licenses'][$a_addon['slug']])?wp_slimstat::$options['addon_licenses'][$a_addon['slug']]:'' ?>" size="50"/>
|
68 |
</div>
|
@@ -72,8 +72,7 @@ if (!is_array($list_addons)){
|
|
72 |
<?php endforeach ?>
|
73 |
</tbody>
|
74 |
</table>
|
75 |
-
|
76 |
-
|
77 |
-
<?php endif ?>
|
78 |
</form>
|
79 |
</div>
|
62 |
</th>
|
63 |
<td class="column-description desc">
|
64 |
<div class="plugin-description"><p><?php echo $a_addon['description'] ?></p></div>
|
65 |
+
<?php if ((is_plugin_active($a_addon['slug'].'/index.php') || is_plugin_active($a_addon['slug'].'/'.$a_addon['slug'].'.php'))): ?>
|
66 |
<div class="active second">
|
67 |
License Key: <input type="text" name="licenses[<?php echo $a_addon['slug'] ?>]" value="<?php echo !empty(wp_slimstat::$options['addon_licenses'][$a_addon['slug']])?wp_slimstat::$options['addon_licenses'][$a_addon['slug']]:'' ?>" size="50"/>
|
68 |
</div>
|
72 |
<?php endforeach ?>
|
73 |
</tbody>
|
74 |
</table>
|
75 |
+
<input type="submit" value="Save Changes" class="button-primary" name="Submit">
|
76 |
+
|
|
|
77 |
</form>
|
78 |
</div>
|
admin/config/index.php
CHANGED
@@ -25,7 +25,9 @@ switch ($config_tabs[$current_tab-1]){
|
|
25 |
|
26 |
'general_integration_header' => array('description' => __('WordPress Integration','wp-slimstat'), 'type' => 'section_header'),
|
27 |
'use_separate_menu' => array( 'description' => __('Menu Position','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Choose between a standalone admin menu for Slimstat or a drop down in the admin bar (if visible).','wp-slimstat'), 'custom_label_yes' => __('Side Menu','wp-slimstat'), 'custom_label_no' => __('Admin Bar','wp-slimstat') ),
|
28 |
-
'add_posts_column' => array( 'description' => __('Add Stats to Posts and Pages','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Add a new column to the Edit Posts/Pages screens, with the number of hits per post.','wp-slimstat') ),
|
|
|
|
|
29 |
|
30 |
'general_database_header' => array('description' => __('Database','wp-slimstat'), 'type' => 'section_header'),
|
31 |
'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 regardless of its age.",'wp-slimstat').(wp_get_schedule('wp_slimstat_purge')?' '.__('Next clean-up on','wp-slimstat').' <strong>'.date_i18n(get_option('date_format').', '.get_option('time_format'), wp_next_scheduled('wp_slimstat_purge')).'</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::$options['auto_purge'].' days'))):''), 'after_input_field' => __('days','wp-slimstat') ),
|
25 |
|
26 |
'general_integration_header' => array('description' => __('WordPress Integration','wp-slimstat'), 'type' => 'section_header'),
|
27 |
'use_separate_menu' => array( 'description' => __('Menu Position','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Choose between a standalone admin menu for Slimstat or a drop down in the admin bar (if visible).','wp-slimstat'), 'custom_label_yes' => __('Side Menu','wp-slimstat'), 'custom_label_no' => __('Admin Bar','wp-slimstat') ),
|
28 |
+
'add_posts_column' => array( 'description' => __('Add Stats to Posts and Pages','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Add a new column to the Edit Posts/Pages screens, with the number of hits per post in the last 365 days.','wp-slimstat') ),
|
29 |
+
'posts_column_day_interval' => array( 'description' => __('Interval','wp-slimstat'), 'type' => 'integer', 'long_description' => __('Enter the time range, in days, that should be used to calculate the value here above.','wp-slimstat') ),
|
30 |
+
'posts_column_pageviews' => array( 'description' => __('Report Type','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Select what kind of information you would like to see displayed on the Posts admin screen. Pageviews include all the hits regardless of the user, Unique IPs consider only one hit per user in the given time range.','wp-slimstat'), 'custom_label_yes' => __('Pageviews','wp-slimstat'), 'custom_label_no' => __('Unique IPs','wp-slimstat') ),
|
31 |
|
32 |
'general_database_header' => array('description' => __('Database','wp-slimstat'), 'type' => 'section_header'),
|
33 |
'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 regardless of its age.",'wp-slimstat').(wp_get_schedule('wp_slimstat_purge')?' '.__('Next clean-up on','wp-slimstat').' <strong>'.date_i18n(get_option('date_format').', '.get_option('time_format'), wp_next_scheduled('wp_slimstat_purge')).'</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::$options['auto_purge'].' days'))):''), 'after_input_field' => __('days','wp-slimstat') ),
|
admin/view/wp-slimstat-db-new.php
ADDED
@@ -0,0 +1,881 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 $filter_names = array();
|
7 |
+
public static $filters_normalized = array();
|
8 |
+
|
9 |
+
// Number and date formats
|
10 |
+
public static $formats = array('decimal' => ',', 'thousand' => '.');
|
11 |
+
|
12 |
+
// Filters as SQL clauses
|
13 |
+
public static $sql_filters = array();
|
14 |
+
|
15 |
+
/*
|
16 |
+
* Initializes the environment, sets the filters
|
17 |
+
*/
|
18 |
+
public static function init($_filters = ''){
|
19 |
+
// Decimal and thousand separators
|
20 |
+
if (wp_slimstat::$options['use_european_separators'] == 'no'){
|
21 |
+
self::$formats['decimal'] = '.';
|
22 |
+
self::$formats['thousand'] = ',';
|
23 |
+
}
|
24 |
+
|
25 |
+
// Filters are defined as: browser equals Chrome|country starts_with en
|
26 |
+
if (!is_string($_filters) || empty($_filters)){
|
27 |
+
$_filters = '';
|
28 |
+
}
|
29 |
+
|
30 |
+
// List of supported filters and their friendly names
|
31 |
+
self::$filter_names = array(
|
32 |
+
'no_filter_selected_1' => ' ',
|
33 |
+
'browser' => __('Browser','wp-slimstat'),
|
34 |
+
'country' => __('Country Code','wp-slimstat'),
|
35 |
+
'ip' => __('IP Address','wp-slimstat'),
|
36 |
+
'searchterms' => __('Search Terms','wp-slimstat'),
|
37 |
+
'language' => __('Language Code','wp-slimstat'),
|
38 |
+
'platform' => __('Operating System','wp-slimstat'),
|
39 |
+
'resource' => __('Permalink','wp-slimstat'),
|
40 |
+
'domain' => __('Domain','wp-slimstat'),
|
41 |
+
'referer' => __('Referer','wp-slimstat'),
|
42 |
+
'user' => __('Visitor\'s Name','wp-slimstat'),
|
43 |
+
'page_performance' => __('Page Speed','wp-slimstat'),
|
44 |
+
'no_filter_selected_2' => ' ',
|
45 |
+
'no_filter_selected_3' => __('-- Advanced filters --','wp-slimstat'),
|
46 |
+
'plugins' => __('Browser Capabilities','wp-slimstat'),
|
47 |
+
'version' => __('Browser Version','wp-slimstat'),
|
48 |
+
'type' => __('Browser Type','wp-slimstat'),
|
49 |
+
'user_agent' => __('User Agent','wp-slimstat'),
|
50 |
+
'colordepth' => __('Color Depth','wp-slimstat'),
|
51 |
+
'css_version' => __('CSS Version','wp-slimstat'),
|
52 |
+
'notes' => __('Pageview Attributes','wp-slimstat'),
|
53 |
+
'server_latency' => __('Server Latency','wp-slimstat'),
|
54 |
+
'outbound_resource' => __('Outbound Link','wp-slimstat'),
|
55 |
+
'author' => __('Post Author','wp-slimstat'),
|
56 |
+
'category' => __('Post Category ID','wp-slimstat'),
|
57 |
+
'other_ip' => __('Originating IP','wp-slimstat'),
|
58 |
+
'content_type' => __('Resource Content Type','wp-slimstat'),
|
59 |
+
'content_id' => __('Resource ID','wp-slimstat'),
|
60 |
+
'resolution' => __('Screen Resolution','wp-slimstat'),
|
61 |
+
'visit_id' => __('Visit ID','wp-slimstat'),
|
62 |
+
|
63 |
+
// The following filters will not be displayed in the dropdown
|
64 |
+
'minute' => __('Minute','wp-slimstat'),
|
65 |
+
'hour' => __('Hour','wp-slimstat'),
|
66 |
+
'day' => __('Day','wp-slimstat'),
|
67 |
+
'month' => __('Month','wp-slimstat'),
|
68 |
+
'year' => __('Year','wp-slimstat'),
|
69 |
+
'interval_direction' => __('+/-','wp-slimstat'),
|
70 |
+
'interval' => __('days','wp-slimstat'),
|
71 |
+
'interval_hours' => __('hours','wp-slimstat'),
|
72 |
+
'interval_minutes' => __('minutes','wp-slimstat'),
|
73 |
+
|
74 |
+
'direction' => __('Order Direction','wp-slimstat'),
|
75 |
+
'limit_results' => __('Limit Results','wp-slimstat'),
|
76 |
+
'start_from' => __('Start From','wp-slimstat'),
|
77 |
+
|
78 |
+
// Misc Filters
|
79 |
+
'strtotime' => 0
|
80 |
+
);
|
81 |
+
|
82 |
+
// Hook for the... filters
|
83 |
+
$_filters = apply_filters('slimstat_db_pre_filters', $_filters);
|
84 |
+
|
85 |
+
// Normalize the input (filters)
|
86 |
+
self::$filters_normalized = self::parse_filters($_filters);
|
87 |
+
|
88 |
+
// Hook for the array of normalized filters
|
89 |
+
self::$filters_normalized = apply_filters('slimstat_db_filters_normalized', self::$filters_normalized, $_filters);
|
90 |
+
|
91 |
+
// Temporarily disable any filter on date_i18n
|
92 |
+
$date_i18n_filters = array();
|
93 |
+
if (!empty($GLOBALS['wp_filter']['date_i18n'])){
|
94 |
+
$date_i18n_filters = $GLOBALS['wp_filter']['date_i18n'];
|
95 |
+
remove_all_filters('date_i18n');
|
96 |
+
}
|
97 |
+
|
98 |
+
// Date and time ranges
|
99 |
+
if (empty(self::$filters_normalized['date']['interval']) && empty(self::$filters_normalized['date']['interval_hours']) && empty(self::$filters_normalized['date']['interval_minutes'])){
|
100 |
+
if (!empty(self::$filters_normalized['date']['minute'])){
|
101 |
+
self::$filters_normalized['utime']['start'] = mktime(
|
102 |
+
!empty(self::$filters_normalized['date']['hour'])?self::$filters_normalized['date']['hour']:0,
|
103 |
+
self::$filters_normalized['date']['minute'],
|
104 |
+
0,
|
105 |
+
!empty(self::$filters_normalized['date']['month'])?self::$filters_normalized['date']['month']:date_i18n('n'),
|
106 |
+
!empty(self::$filters_normalized['date']['day'])?self::$filters_normalized['date']['day']:date_i18n('j'),
|
107 |
+
!empty(self::$filters_normalized['date']['year'])?self::$filters_normalized['date']['year']:date_i18n('Y')
|
108 |
+
);
|
109 |
+
self::$filters_normalized['utime']['end'] = self::$filters_normalized['utime']['start'] + 60;
|
110 |
+
self::$filters_normalized['utime']['type'] = 'H';
|
111 |
+
}
|
112 |
+
else if (!empty(self::$filters_normalized['date']['hour'])){
|
113 |
+
self::$filters_normalized['utime']['start'] = mktime(
|
114 |
+
self::$filters_normalized['date']['hour'],
|
115 |
+
0,
|
116 |
+
0,
|
117 |
+
!empty(self::$filters_normalized['date']['month'])?self::$filters_normalized['date']['month']:date_i18n('n'),
|
118 |
+
!empty(self::$filters_normalized['date']['day'])?self::$filters_normalized['date']['day']:date_i18n('j'),
|
119 |
+
!empty(self::$filters_normalized['date']['year'])?self::$filters_normalized['date']['year']:date_i18n('Y')
|
120 |
+
);
|
121 |
+
self::$filters_normalized['utime']['end'] = self::$filters_normalized['utime']['start'] + 3599;
|
122 |
+
self::$filters_normalized['utime']['type'] = 'H';
|
123 |
+
}
|
124 |
+
else if (!empty(self::$filters_normalized['date']['day'])){
|
125 |
+
self::$filters_normalized['utime']['start'] = mktime(
|
126 |
+
0,
|
127 |
+
0,
|
128 |
+
0,
|
129 |
+
!empty(self::$filters_normalized['date']['month'])?self::$filters_normalized['date']['month']:date_i18n('n'),
|
130 |
+
self::$filters_normalized['date']['day'],
|
131 |
+
!empty(self::$filters_normalized['date']['year'])?self::$filters_normalized['date']['year']:date_i18n('Y')
|
132 |
+
);
|
133 |
+
self::$filters_normalized['utime']['end'] = self::$filters_normalized['utime']['start'] + 86399;
|
134 |
+
self::$filters_normalized['utime']['type'] = 'd';
|
135 |
+
}
|
136 |
+
else if(!empty(self::$filters_normalized['date']['year']) && empty(self::$filters_normalized['date']['month'])){
|
137 |
+
self::$filters_normalized['utime']['start'] = mktime(0, 0, 0, 1, 1, self::$filters_normalized['date']['year']);
|
138 |
+
self::$filters_normalized['utime']['end'] = mktime(0, 0, 0, 1, 1, self::$filters_normalized['date']['year']+1)-1;
|
139 |
+
self::$filters_normalized['utime']['type'] = 'Y';
|
140 |
+
}
|
141 |
+
else{
|
142 |
+
self::$filters_normalized['utime']['start'] = mktime(
|
143 |
+
0,
|
144 |
+
0,
|
145 |
+
0,
|
146 |
+
!empty(self::$filters_normalized['date']['month'])?self::$filters_normalized['date']['month']:date_i18n('n'),
|
147 |
+
1,
|
148 |
+
!empty(self::$filters_normalized['date']['year'])?self::$filters_normalized['date']['year']:date_i18n('Y')
|
149 |
+
);
|
150 |
+
|
151 |
+
self::$filters_normalized['utime']['end'] = strtotime(
|
152 |
+
(!empty(self::$filters_normalized['date']['year'])?self::$filters_normalized['date']['year']:date_i18n('Y')).'-'.
|
153 |
+
(!empty(self::$filters_normalized['date']['month'])?self::$filters_normalized['date']['month']:date_i18n('n')).
|
154 |
+
'-01 00:00 +1 month UTC'
|
155 |
+
)-1;
|
156 |
+
self::$filters_normalized['utime']['type'] = 'm';
|
157 |
+
}
|
158 |
+
}
|
159 |
+
else{ // An interval was specified
|
160 |
+
self::$filters_normalized['utime']['type'] = 'interval';
|
161 |
+
|
162 |
+
self::$filters_normalized['utime']['start'] = mktime(
|
163 |
+
!empty(self::$filters_normalized['date']['hour'])?self::$filters_normalized['date']['hour']:0,
|
164 |
+
!empty(self::$filters_normalized['date']['minute'])?self::$filters_normalized['date']['minute']:0,
|
165 |
+
0,
|
166 |
+
!empty(self::$filters_normalized['date']['month'])?self::$filters_normalized['date']['month']:date_i18n('n'),
|
167 |
+
!empty(self::$filters_normalized['date']['day'])?self::$filters_normalized['date']['day']:date_i18n('j'),
|
168 |
+
!empty(self::$filters_normalized['date']['year'])?self::$filters_normalized['date']['year']:date_i18n('Y')
|
169 |
+
);
|
170 |
+
|
171 |
+
$sign = (self::$filters_normalized['date']['interval_direction'] == 'plus')?'+':'-';
|
172 |
+
|
173 |
+
self::$filters_normalized['utime']['end'] = self::$filters_normalized['utime']['start'] + intval($sign.(
|
174 |
+
(!empty(self::$filters_normalized['date']['interval'])?intval(self::$filters_normalized['date']['interval'] + 1):0) * 86400 +
|
175 |
+
(!empty(self::$filters_normalized['date']['interval_hours'])?intval(self::$filters_normalized['date']['interval_hours']):0) * 3600 +
|
176 |
+
(!empty(self::$filters_normalized['date']['interval_minutes'])?intval(self::$filters_normalized['date']['interval_minutes']):0) * 60
|
177 |
+
)) - 1;
|
178 |
+
|
179 |
+
// Swap boundaries if we're going back
|
180 |
+
if (self::$filters_normalized['date']['interval_direction'] == 'minus'){
|
181 |
+
list(self::$filters_normalized['utime']['start'], self::$filters_normalized['utime']['end']) = array(self::$filters_normalized['utime']['end'] + 86401, self::$filters_normalized['utime']['start'] + 86399);
|
182 |
+
}
|
183 |
+
}
|
184 |
+
|
185 |
+
// If end is in the future, set it to now
|
186 |
+
if (self::$filters_normalized['utime']['end'] > date_i18n('U')){
|
187 |
+
self::$filters_normalized['utime']['end'] = date_i18n('U');
|
188 |
+
}
|
189 |
+
|
190 |
+
// If start is after end, set it to first of month
|
191 |
+
if (self::$filters_normalized['utime']['start'] > self::$filters_normalized['utime']['end']){
|
192 |
+
self::$filters_normalized['utime']['start'] = mktime(
|
193 |
+
0,
|
194 |
+
0,
|
195 |
+
0,
|
196 |
+
date_i18n('n', self::$filters_normalized['utime']['end']),
|
197 |
+
1,
|
198 |
+
date_i18n('Y', self::$filters_normalized['utime']['end'])
|
199 |
+
);
|
200 |
+
self::$filters_normalized['date']['hour'] = self::$filters_normalized['date']['day'] = self::$filters_normalized['date']['month'] = self::$filters_normalized['date']['year'] = 0;
|
201 |
+
}
|
202 |
+
|
203 |
+
// Restore filters on date_i18n
|
204 |
+
foreach ($date_i18n_filters as $i18n_priority => $i18n_func_list) {
|
205 |
+
foreach ($i18n_func_list as $func_name => $func_args) {
|
206 |
+
add_filter('date_i8n', $func_args['function'], $i18n_priority, $func_args['accepted_args']);
|
207 |
+
}
|
208 |
+
}
|
209 |
+
|
210 |
+
// Now let's translate our filters into SQL clauses
|
211 |
+
self::$sql_filters = array(
|
212 |
+
'table_info' => array(
|
213 |
+
'tb' => array('slim_browsers', 'browser_id'),
|
214 |
+
'tci' => array('slim_content_info', 'content_info_id'),
|
215 |
+
'tob' => array('slim_outbound', 'outbound_id'),
|
216 |
+
'tss' => array('slim_screenres', 'screenres_id'),
|
217 |
+
),
|
218 |
+
|
219 |
+
'from' => array(
|
220 |
+
't1' => "{$GLOBALS['wpdb']->prefix}slim_stats t1",
|
221 |
+
|
222 |
+
'all' => '',
|
223 |
+
'all_others' => ''
|
224 |
+
),
|
225 |
+
|
226 |
+
'where' => array(
|
227 |
+
't1' => '',
|
228 |
+
'tb' => array('browser_id' => ''),
|
229 |
+
'tci' => array('content_info_id' => ''),
|
230 |
+
'tob' => array('outbound_id' => ''),
|
231 |
+
'tss' => array('screenres_id' => ''),
|
232 |
+
|
233 |
+
'all' => '',
|
234 |
+
'time_range' => ' AND (t1.dt BETWEEN '.self::$filters_normalized['utime']['start'].' AND '.self::$filters_normalized['utime']['end'].')'
|
235 |
+
),
|
236 |
+
|
237 |
+
'id' => array(
|
238 |
+
'tb' => '',
|
239 |
+
'tci' => '',
|
240 |
+
'tob' => '',
|
241 |
+
'tss' => ''
|
242 |
+
)
|
243 |
+
);
|
244 |
+
|
245 |
+
foreach (self::$filters_normalized['columns'] as $a_filter_column => $a_filter_data){
|
246 |
+
// Add-ons can set their own custom filters, which are ignored here
|
247 |
+
if (strpos($a_filter_column, 'addon_') !== false){
|
248 |
+
continue;
|
249 |
+
}
|
250 |
+
|
251 |
+
$filter_empty = '0';
|
252 |
+
|
253 |
+
// Table this column belongs to
|
254 |
+
$table_alias = self::get_table_alias($a_filter_column);
|
255 |
+
|
256 |
+
// Some columns require a special treatment
|
257 |
+
switch($a_filter_column){
|
258 |
+
case 'ip':
|
259 |
+
case 'other_ip':
|
260 |
+
$a_filter_column = "INET_NTOA($a_filter_column)";
|
261 |
+
$filter_empty = '0.0.0.0';
|
262 |
+
break;
|
263 |
+
default:
|
264 |
+
$a_filter_column = $table_alias.'.'.$a_filter_column;
|
265 |
+
break;
|
266 |
+
}
|
267 |
+
|
268 |
+
switch ($a_filter_data[0]){
|
269 |
+
case 'is_not_equal_to':
|
270 |
+
self::$sql_filters['where'][$table_alias][$a_filter_column] = $GLOBALS['wpdb']->prepare("$a_filter_column <> %s", $a_filter_data[1]);
|
271 |
+
break;
|
272 |
+
case 'contains':
|
273 |
+
self::$sql_filters['where'][$table_alias][$a_filter_column] = $GLOBALS['wpdb']->prepare("$a_filter_column LIKE %s", '%'.$a_filter_data[1].'%');
|
274 |
+
break;
|
275 |
+
case 'includes_in_set':
|
276 |
+
self::$sql_filters['where'][$table_alias][$a_filter_column] = $GLOBALS['wpdb']->prepare("FIND_IN_SET(%s, $a_filter_column) > 0", $a_filter_data[1]);
|
277 |
+
break;
|
278 |
+
case 'does_not_contain':
|
279 |
+
self::$sql_filters['where'][$table_alias][$a_filter_column] = $GLOBALS['wpdb']->prepare("$a_filter_column NOT LIKE %s", '%'.$a_filter_data[1].'%');;
|
280 |
+
break;
|
281 |
+
case 'starts_with':
|
282 |
+
self::$sql_filters['where'][$table_alias][$a_filter_column] = $GLOBALS['wpdb']->prepare("$a_filter_column LIKE %s", $a_filter_data[1].'%');
|
283 |
+
break;
|
284 |
+
case 'ends_with':
|
285 |
+
self::$sql_filters['where'][$table_alias][$a_filter_column] = $GLOBALS['wpdb']->prepare("$a_filter_column LIKE %s", '%'.$a_filter_data[1]);
|
286 |
+
break;
|
287 |
+
case 'sounds_like':
|
288 |
+
self::$sql_filters['where'][$table_alias][$a_filter_column] = $GLOBALS['wpdb']->prepare("SOUNDEX($a_filter_column) = SOUNDEX(%s)", $a_filter_data[1]);
|
289 |
+
break;
|
290 |
+
case 'is_empty':
|
291 |
+
self::$sql_filters['where'][$table_alias][$a_filter_column] = "($a_filter_column = '' OR $a_filter_column = '$filter_empty')";
|
292 |
+
break;
|
293 |
+
case 'is_not_empty':
|
294 |
+
self::$sql_filters['where'][$table_alias][$a_filter_column] = "($a_filter_column <> '' AND $a_filter_column <> '$filter_empty')";
|
295 |
+
break;
|
296 |
+
case 'is_greater_than':
|
297 |
+
self::$sql_filters['where'][$table_alias][$a_filter_column] = $GLOBALS['wpdb']->prepare("$a_filter_column > %d", $a_filter_data[1]);
|
298 |
+
break;
|
299 |
+
case 'is_less_than':
|
300 |
+
self::$sql_filters['where'][$table_alias][$a_filter_column] = $GLOBALS['wpdb']->prepare("$a_filter_column < %d", $a_filter_data[1]);
|
301 |
+
break;
|
302 |
+
case 'between':
|
303 |
+
$range = explode(',', $a_filter_data[1]);
|
304 |
+
self::$sql_filters['where'][$table_alias][$a_filter_column] = $GLOBALS['wpdb']->prepare("$a_filter_column BETWEEN %d AND %d", $range[0], $range[1]);
|
305 |
+
break;
|
306 |
+
case 'matches':
|
307 |
+
self::$sql_filters['where'][$table_alias][$a_filter_column] = $GLOBALS['wpdb']->prepare("$a_filter_column REGEXP %s", $a_filter_data[1]);
|
308 |
+
break;
|
309 |
+
case 'does_not_match':
|
310 |
+
self::$sql_filters['where'][$table_alias][$a_filter_column] = $GLOBALS['wpdb']->prepare("$a_filter_column NOT REGEXP %s", $a_filter_data[1]);
|
311 |
+
break;
|
312 |
+
default:
|
313 |
+
self::$sql_filters['where'][$table_alias][$a_filter_column] = $GLOBALS['wpdb']->prepare("$a_filter_column = %s", $a_filter_data[1]);
|
314 |
+
}
|
315 |
+
}
|
316 |
+
|
317 |
+
// Get the IDs from the lookup tables
|
318 |
+
foreach (array_keys(self::$sql_filters['id']) as $a_table_alias){
|
319 |
+
if (!empty(self::$sql_filters['where'][$a_table_alias])){
|
320 |
+
self::$sql_filters['id'][$a_table_alias] = self::get_results('
|
321 |
+
SELECT *
|
322 |
+
FROM '.$GLOBALS['wpdb']->base_prefix.self::$sql_filters['table_info'][$a_table_alias][0].' '.$a_table_alias.'
|
323 |
+
WHERE '.implode(' AND ', self::$sql_filters['where'][$a_table_alias]));
|
324 |
+
|
325 |
+
if (!empty(self::$sql_filters['id'][$a_table_alias])){
|
326 |
+
$table_ids = array();
|
327 |
+
foreach (self::$sql_filters['id'][$a_table_alias] as $a_result){
|
328 |
+
$table_ids[] = $a_result[self::$sql_filters['table_info'][$a_table_alias][1]];
|
329 |
+
}
|
330 |
+
self::$sql_filters['where'][$a_table_alias][self::$sql_filters['table_info'][$a_table_alias][1]] = 't1.'.self::$sql_filters['table_info'][$a_table_alias][1].' IN ('.implode(',', $table_ids).')';
|
331 |
+
}
|
332 |
+
}
|
333 |
+
}
|
334 |
+
|
335 |
+
// self::$sql_filters['from']['all_others'] = trim(self::$sql_filters['from']['tb'].' '.self::$sql_filters['from']['tci'].' '.self::$sql_filters['from']['tob'].' '.self::$sql_filters['from']['tss']);
|
336 |
+
// self::$sql_filters['from']['all'] = "{$GLOBALS['wpdb']->prefix}slim_stats t1 ".self::$sql_filters['from']['all_others'];
|
337 |
+
|
338 |
+
self::$sql_filters['where']['all'] = trim(
|
339 |
+
self::$sql_filters['where']['t1'].' '.
|
340 |
+
self::$sql_filters['where']['tb']['browser_id'].' '.
|
341 |
+
self::$sql_filters['where']['tci']['content_info_id'].' '.
|
342 |
+
self::$sql_filters['where']['tob']['outbound_id'].' '.
|
343 |
+
self::$sql_filters['where']['tss']['screenres_id']);
|
344 |
+
}
|
345 |
+
// end init
|
346 |
+
|
347 |
+
// The following methods retrieve the information from the database
|
348 |
+
|
349 |
+
public static function count_bouncing_pages(){
|
350 |
+
return intval(self::get_var('
|
351 |
+
SELECT COUNT(*) counthits
|
352 |
+
FROM (
|
353 |
+
SELECT t1.resource
|
354 |
+
FROM '.self::$sql_filters['from']['all'].' '.self::_add_filters_to_sql_from('tci.content_type').'
|
355 |
+
WHERE t1.visit_id <> 0 AND t1.resource <> "" AND tci.content_type <> "404" '.self::$sql_filters['where']['all'].' '.self::$sql_filters['where']['time_range'].'
|
356 |
+
GROUP BY visit_id
|
357 |
+
HAVING COUNT(visit_id) = 1
|
358 |
+
) as ts1',
|
359 |
+
'SUM(counthits) AS counthits'));
|
360 |
+
}
|
361 |
+
|
362 |
+
public static function count_exit_pages(){
|
363 |
+
return intval(self::get_var('
|
364 |
+
SELECT COUNT(*) counthits
|
365 |
+
FROM (
|
366 |
+
SELECT resource, visit_id, dt
|
367 |
+
FROM '.self::$sql_filters['from']['all'].'
|
368 |
+
WHERE visit_id > 0 AND resource <> "" '.self::$sql_filters['where']['all'].' '.self::$sql_filters['where']['time_range'].'
|
369 |
+
GROUP BY visit_id
|
370 |
+
HAVING dt = MAX(dt)
|
371 |
+
) AS ts1',
|
372 |
+
'SUM(counthits) AS counthits'));
|
373 |
+
}
|
374 |
+
|
375 |
+
public static function count_records($_where_clause = '1=1', $_distinct_column = '*', $_use_filters = true, $_use_date_filters = true, $_join_tables = ''){
|
376 |
+
$column = ($_distinct_column != '*')?"DISTINCT $_distinct_column":$_distinct_column;
|
377 |
+
return intval(self::get_var("
|
378 |
+
SELECT COUNT($column) counthits
|
379 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats t1 ".($_use_filters?self::$sql_filters['from']['all_others']:'').' '.self::_add_filters_to_sql_from($_where_clause.$_join_tables).'
|
380 |
+
WHERE '.(!empty($_where_clause)?$_where_clause:'1=1').' '.($_use_filters?self::$sql_filters['where']['all']:'').' '.($_use_date_filters?self::$sql_filters['where']['time_range']:''),
|
381 |
+
'SUM(counthits) AS counthits'));
|
382 |
+
}
|
383 |
+
|
384 |
+
public static function count_outbound(){
|
385 |
+
return intval(self::get_var("
|
386 |
+
SELECT COUNT(outbound_id) counthits
|
387 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats t1 INNER JOIN {$GLOBALS['wpdb']->prefix}slim_outbound tob ON t1.id = tob.id ".self::$sql_filters['from']['all_others']."
|
388 |
+
WHERE 1=1 ".self::$sql_filters['where']['all'].' '.self::$sql_filters['where']['time_range'],
|
389 |
+
'SUM(counthits) AS counthits'));
|
390 |
+
}
|
391 |
+
|
392 |
+
public static function count_records_having($_where_clause = '1=1', $_column = 't1.ip', $_having_clause = ''){
|
393 |
+
return intval(self::get_var("
|
394 |
+
SELECT COUNT(*) counthits FROM (
|
395 |
+
SELECT $_column
|
396 |
+
FROM ".self::$sql_filters['from']['all'].' '.self::_add_filters_to_sql_from($_where_clause)."
|
397 |
+
WHERE $_where_clause ".self::$sql_filters['where']['all'].' '.self::$sql_filters['where']['time_range']."
|
398 |
+
GROUP BY $_column
|
399 |
+
".(!empty($_having_clause)?"HAVING $_having_clause":'').')
|
400 |
+
AS ts1',
|
401 |
+
'SUM(counthits) AS counthits'));
|
402 |
+
}
|
403 |
+
|
404 |
+
public static function get_data_size(){
|
405 |
+
$suffix = 'KB';
|
406 |
+
|
407 |
+
$sql = 'SHOW TABLE STATUS LIKE "'.$GLOBALS['wpdb']->prefix.'slim_stats"';
|
408 |
+
$table_details = wp_slimstat::$wpdb->get_row($sql, 'ARRAY_A', 0);
|
409 |
+
|
410 |
+
$table_size = ( $table_details['Data_length'] / 1024 ) + ( $table_details['Index_length'] / 1024 );
|
411 |
+
|
412 |
+
if ($table_size > 1024){
|
413 |
+
$table_size /= 1024;
|
414 |
+
$suffix = 'MB';
|
415 |
+
}
|
416 |
+
return number_format($table_size, 2, self::$formats['decimal'], self::$formats['thousand']).' '.$suffix;
|
417 |
+
}
|
418 |
+
|
419 |
+
public static function get_max_and_average_pages_per_visit(){
|
420 |
+
return self::get_results('
|
421 |
+
SELECT AVG(ts1.counthits) AS avghits, MAX(ts1.counthits) AS maxhits FROM (
|
422 |
+
SELECT count(ip) counthits, visit_id
|
423 |
+
FROM '.self::$sql_filters['from']['all'].'
|
424 |
+
WHERE visit_id > 0 '.self::$sql_filters['where']['all'].' '.self::$sql_filters['where']['time_range'].'
|
425 |
+
GROUP BY visit_id
|
426 |
+
) AS ts1',
|
427 |
+
'blog_id',
|
428 |
+
'',
|
429 |
+
'',
|
430 |
+
'AVG(avghits) AS avghits, MAX(maxhits) AS maxhits');
|
431 |
+
}
|
432 |
+
|
433 |
+
public static function get_oldest_visit($_where_clause = '1=1', $_use_filters = true){
|
434 |
+
return self::get_var("
|
435 |
+
SELECT t1.dt
|
436 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats t1 ".($_use_filters?self::$sql_filters['from']['all_others']:'').' '.self::_add_filters_to_sql_from($_where_clause).'
|
437 |
+
WHERE '.(!empty($_where_clause)?$_where_clause:'1=1').' '.($_use_filters?self::$sql_filters['where']['all']:'').'
|
438 |
+
ORDER BY dt ASC
|
439 |
+
LIMIT 0,1',
|
440 |
+
'MIN(dt)');
|
441 |
+
}
|
442 |
+
|
443 |
+
public static function get_popular($_column = 't1.id', $_custom_where = '', $_more_columns = '', $_having_clause = '', $_as_column = ''){
|
444 |
+
return self::get_results("
|
445 |
+
SELECT $_column ".(!empty($_as_column)?'AS '.$_as_column:'')." $_more_columns, COUNT(*) counthits
|
446 |
+
FROM ".self::$sql_filters['from']['all'].' '.self::_add_filters_to_sql_from($_column.$_custom_where.$_more_columns).'
|
447 |
+
WHERE '.(empty($_custom_where)?"$_column <> '' ":$_custom_where).' '.self::$sql_filters['where']['all'].' '.self::$sql_filters['where']['time_range']."
|
448 |
+
GROUP BY $_column $_having_clause
|
449 |
+
ORDER BY counthits ".self::$filters_normalized['misc']['direction']."
|
450 |
+
LIMIT ".self::$filters_normalized['misc']['start_from'].', '.self::$filters_normalized['misc']['limit_results'],
|
451 |
+
(!empty($_as_column)?$_as_column:$_column).' '.$_more_columns.', blog_id',
|
452 |
+
'counthits '.self::$filters_normalized['misc']['direction'],
|
453 |
+
"$_column $_more_columns",
|
454 |
+
'SUM(counthits) AS counthits');
|
455 |
+
}
|
456 |
+
|
457 |
+
public static function get_popular_outbound(){
|
458 |
+
return self::get_results("
|
459 |
+
SELECT tob.outbound_resource as resource, COUNT(*) counthits
|
460 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats t1 INNER JOIN {$GLOBALS['wpdb']->prefix}slim_outbound tob ON t1.id = tob.id ".self::$sql_filters['from']['tb'].' '.self::$sql_filters['from']['tss'].' '.self::$sql_filters['from']['tci']."
|
461 |
+
WHERE (tob.type = 0 OR tob.type = 1) ".self::$sql_filters['where']['all'].' '.self::$sql_filters['where']['time_range'].'
|
462 |
+
GROUP BY tob.outbound_resource
|
463 |
+
ORDER BY counthits '.self::$filters_normalized['misc']['direction'].'
|
464 |
+
LIMIT '.self::$filters_normalized['misc']['start_from'].', '.self::$filters_normalized['misc']['limit_results'],
|
465 |
+
'blog_id, resource',
|
466 |
+
'counthits '.self::$filters_normalized['misc']['direction'],
|
467 |
+
'outbound_resource',
|
468 |
+
'SUM(counthits) AS counthits');
|
469 |
+
}
|
470 |
+
|
471 |
+
public static function get_popular_complete($_column = 't1.id', $_custom_where = '', $_join_tables = '', $_having_clause = '', $_outer_select_column = '', $_max_min = 'MAX'){
|
472 |
+
$column_for_select = empty($_outer_select_column)?$_column:$_outer_select_column;
|
473 |
+
return self::get_results("
|
474 |
+
SELECT $column_for_select, ts1.maxid, COUNT(*) counthits
|
475 |
+
FROM (
|
476 |
+
SELECT $_column, $_max_min(t1.id) maxid
|
477 |
+
FROM ".self::$sql_filters['from']['all'].' '.self::_add_filters_to_sql_from($_column.$_custom_where).'
|
478 |
+
WHERE '.(empty($_custom_where)?"$_column <> '' ":$_custom_where).' '.self::$sql_filters['where']['all'].' '.self::$sql_filters['where']['time_range']."
|
479 |
+
GROUP BY $_column $_having_clause
|
480 |
+
) AS ts1 JOIN {$GLOBALS['wpdb']->prefix}slim_stats t1 ON ts1.maxid = t1.id ".
|
481 |
+
(!empty($_join_tables)?self::_add_filters_to_sql_from($_join_tables):'')."
|
482 |
+
GROUP BY $column_for_select
|
483 |
+
ORDER BY counthits ".self::$filters_normalized['misc']['direction'].'
|
484 |
+
LIMIT '.self::$filters_normalized['misc']['start_from'].', '.self::$filters_normalized['misc']['limit_results'],
|
485 |
+
$column_for_select,
|
486 |
+
'counthits '.self::$filters_normalized['misc']['direction'],
|
487 |
+
$column_for_select,
|
488 |
+
'MAX(maxid), SUM(counthits)');
|
489 |
+
}
|
490 |
+
|
491 |
+
public static function get_recent($_column = 't1.id', $_custom_where = '', $_more_columns = '', $_having_clause = '', $_order_by = '', $_use_date_filters = true){
|
492 |
+
if ($_column == 't1.id'){
|
493 |
+
return self::get_results('
|
494 |
+
SELECT t1.*'.(!empty($_more_columns)?', '.$_more_columns:'').'
|
495 |
+
FROM '.self::$sql_filters['from']['t1'].'
|
496 |
+
WHERE '.(empty($_custom_where)?"$_column <> 0 ":$_custom_where).' '.self::$sql_filters['where']['all'].' '.($_use_date_filters?self::$sql_filters['where']['time_range']:'').'
|
497 |
+
ORDER BY '.(empty($_order_by)?'t1.dt '.self::$filters_normalized['misc']['direction']:$_order_by).'
|
498 |
+
LIMIT '.self::$filters_normalized['misc']['start_from'].', '.self::$filters_normalized['misc']['limit_results'],
|
499 |
+
'*',
|
500 |
+
empty($_order_by)?'t1.dt '.self::$filters_normalized['misc']['direction']:$_order_by);
|
501 |
+
|
502 |
+
}
|
503 |
+
else{
|
504 |
+
$table_alias = self::get_table_alias($_column);
|
505 |
+
if ($table_alias != 't1'){
|
506 |
+
$group_by = self::$sql_filters['table_info'][$table_alias][1];
|
507 |
+
}
|
508 |
+
|
509 |
+
$where_ids = self::_add_ids_to_sql_where($_custom_where, $_column);
|
510 |
+
// WHERE '.(empty($_custom_where)?"$_column <> '' ":$_custom_where).' '.self::$sql_filters['where']['all'].' '.($_use_date_filters?self::$sql_filters['where']['time_range']:'')."
|
511 |
+
|
512 |
+
|
513 |
+
return self::get_results('
|
514 |
+
SELECT t1.*
|
515 |
+
FROM (
|
516 |
+
SELECT MAX(t1.id) maxid
|
517 |
+
FROM '.self::$sql_filters['from']['t1'].'
|
518 |
+
WHERE '.$where_ids.' '.($_use_date_filters?self::$sql_filters['where']['time_range']:'').'
|
519 |
+
GROUP BY '.$group_by.' '.
|
520 |
+
$_having_clause.'
|
521 |
+
) AS ts1 INNER JOIN '.$GLOBALS['wpdb']->prefix.'slim_stats t1 ON ts1.maxid = t1.id '.
|
522 |
+
(!empty($_more_columns)?self::_add_filters_to_sql_from($_more_columns):'').'
|
523 |
+
ORDER BY '.(empty($_order_by)?'t1.dt '.self::$filters_normalized['misc']['direction']:$_order_by).'
|
524 |
+
LIMIT '.self::$filters_normalized['misc']['start_from'].', '.self::$filters_normalized['misc']['limit_results'],
|
525 |
+
't1.*, '.(!empty($_more_columns)?$_more_columns:'ts1.maxid'),
|
526 |
+
empty($_order_by)?'t1.dt '.self::$filters_normalized['misc']['direction']:$_order_by);
|
527 |
+
}
|
528 |
+
}
|
529 |
+
|
530 |
+
public static function get_recent_outbound($_type = -1){
|
531 |
+
return self::get_results("
|
532 |
+
SELECT tob.outbound_id as visit_id, tob.outbound_domain, tob.outbound_resource as resource, tob.type, tob.notes, t1.ip, t1.other_ip, t1.user, 'local' as domain, t1.resource as referer, t1.country, tb.browser, tb.version, tb.platform, tob.dt
|
533 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats t1 INNER JOIN {$GLOBALS['wpdb']->prefix}slim_outbound tob ON tob.id = t1.id INNER JOIN {$GLOBALS['wpdb']->base_prefix}slim_browsers tb on t1.browser_id = tb.browser_id ".self::$sql_filters['from']['tci'].' '.self::$sql_filters['from']['tss'].'
|
534 |
+
WHERE '.(($_type != -1)?"tob.type = $_type":'tob.type > 1').' '.self::$sql_filters['where']['all'].' '.self::$sql_filters['where']['time_range'].'
|
535 |
+
ORDER BY tob.dt '.self::$filters_normalized['misc']['direction'].'
|
536 |
+
LIMIT '.self::$filters_normalized['misc']['start_from'].', '.self::$filters_normalized['misc']['limit_results'],
|
537 |
+
'blog_id, visit_id, outbound_domain, resource, type, notes, ip, other_ip, user, domain, referer, country, browser, platform, dt',
|
538 |
+
'dt '.self::$filters_normalized['misc']['direction']);
|
539 |
+
}
|
540 |
+
|
541 |
+
public static function get_data_for_chart($_data1, $_data2, $_custom_where_clause = '', $_sql_from_where = ''){
|
542 |
+
$previous = array('end' => self::$filters_normalized['utime']['start'] - 1);
|
543 |
+
$label_date_format = '';
|
544 |
+
$output = array();
|
545 |
+
|
546 |
+
// Each type has its own parameters
|
547 |
+
switch (self::$filters_normalized['utime']['type']){
|
548 |
+
case 'H':
|
549 |
+
$previous['start'] = self::$filters_normalized['utime']['start'] - 3600;
|
550 |
+
$label_date_format = wp_slimstat::$options['time_format'];
|
551 |
+
$group_by = array('HOUR', 'MINUTE', 'i');
|
552 |
+
$values_in_interval = array(59, 59, 0, 60);
|
553 |
+
break;
|
554 |
+
case 'd':
|
555 |
+
$previous['start'] = self::$filters_normalized['utime']['start'] - 86400;
|
556 |
+
$label_date_format = (self::$formats['decimal'] == '.')?'m/d':'d/m';
|
557 |
+
$group_by = array('DAY', 'HOUR', 'G');
|
558 |
+
$values_in_interval = array(23, 23, 0, 3600);
|
559 |
+
break;
|
560 |
+
case 'Y':
|
561 |
+
$previous['start'] = mktime(0, 0, 0, 1, 1, self::$filters_normalized['date']['year']-1);
|
562 |
+
$label_date_format = 'Y';
|
563 |
+
$group_by = array('YEAR', 'MONTH', 'n');
|
564 |
+
$values_in_interval = array(12, 12, 1, 2678400);
|
565 |
+
break;
|
566 |
+
case 'interval':
|
567 |
+
$group_by = array('MONTH', 'DAY', 'j');
|
568 |
+
$values_in_interval = array(abs(self::$filters_normalized['date']['interval']), abs(self::$filters_normalized['date']['interval']), 0, 86400);
|
569 |
+
break;
|
570 |
+
default:
|
571 |
+
$previous['start'] = mktime(0, 0, 0, (!empty(self::$filters_normalized['date']['month'])?self::$filters_normalized['date']['month']:date_i18n('n'))-1, 1, !empty(self::$filters_normalized['date']['year'])?self::$filters_normalized['date']['year']:date_i18n('Y'));
|
572 |
+
$label_date_format = 'm/Y';
|
573 |
+
$group_by = array('MONTH', 'DAY', 'j');
|
574 |
+
$values_in_interval = array(date('t', $previous['start']), date('t', self::$filters_normalized['utime']['start']), 1, 86400);
|
575 |
+
break;
|
576 |
+
}
|
577 |
+
|
578 |
+
// Custom intervals don't have a comparison chart ('previous' range)
|
579 |
+
$time_range = self::$sql_filters['where']['time_range'];
|
580 |
+
if (empty(self::$filters_normalized['date']['interval'])){
|
581 |
+
$time_range = 'AND (t1.dt BETWEEN '.$previous['start'].' AND '.$previous['end'].' OR t1.dt BETWEEN '.self::$filters_normalized['utime']['start'].' AND '.self::$filters_normalized['utime']['end'].')';
|
582 |
+
}
|
583 |
+
|
584 |
+
// Build the SQL query
|
585 |
+
$sql = "SELECT t1.dt, $_data1 first_metric, $_data2 second_metric";
|
586 |
+
|
587 |
+
// Panel 4 has a slightly different structure
|
588 |
+
if(empty($_sql_from_where)){
|
589 |
+
$sql .= ' FROM '.self::$sql_filters['from']['all'].' '.self::_add_filters_to_sql_from($_data1.$_data2.$_custom_where_clause)."
|
590 |
+
WHERE 1=1 $time_range ".self::$sql_filters['where']['all'].' '.$_custom_where_clause;
|
591 |
+
}
|
592 |
+
else{
|
593 |
+
$sql_no_placeholders = str_replace('[from_tables]', self::$sql_filters['from']['all'].' '.self::_add_filters_to_sql_from($_data1.$_data2.$_custom_where_clause), $_sql_from_where);
|
594 |
+
$sql_no_placeholders = str_replace('[where_clause]', '1=1 '.$time_range.' '.self::$sql_filters['where']['all'].' '.$_custom_where_clause, $sql_no_placeholders);
|
595 |
+
$sql .= $sql_no_placeholders;
|
596 |
+
}
|
597 |
+
|
598 |
+
$group_by_string = "{$group_by[0]}(CONVERT_TZ(FROM_UNIXTIME(t1.dt), @@session.time_zone, '+00:00')), {$group_by[1]}(CONVERT_TZ(FROM_UNIXTIME(t1.dt), @@session.time_zone, '+00:00'))";
|
599 |
+
$sql .= " GROUP BY $group_by_string";
|
600 |
+
|
601 |
+
// Get the data
|
602 |
+
$results = self::get_results($sql, 'blog_id', '', $group_by_string, 'SUM(first_metric) AS first_metric, SUM(second_metric) AS second_metric');
|
603 |
+
|
604 |
+
// Fill the output array
|
605 |
+
$output['current']['label'] = '';
|
606 |
+
if (!empty($label_date_format)){
|
607 |
+
$output['current']['label'] = gmdate($label_date_format, self::$filters_normalized['utime']['start']);
|
608 |
+
$output['previous']['label'] = gmdate($label_date_format, $previous['start']);
|
609 |
+
}
|
610 |
+
|
611 |
+
$output['previous']['first_metric'] = array_fill($values_in_interval[2], $values_in_interval[0], 0);
|
612 |
+
$output['previous']['second_metric'] = array_fill($values_in_interval[2], $values_in_interval[0], 0);
|
613 |
+
|
614 |
+
|
615 |
+
$today_limit = floatval(date_i18n('Ymd.Hi'));
|
616 |
+
for ($i = $values_in_interval[2]; $i <= $values_in_interval[1]; $i++){
|
617 |
+
// Do not include dates in the future
|
618 |
+
|
619 |
+
$floatval = floatval(date('Ymd.Hi', wp_slimstat_db::$filters_normalized['utime']['start'] + ( ($i - $values_in_interval[2]) * $values_in_interval[3])));
|
620 |
+
|
621 |
+
if ($floatval > $today_limit){
|
622 |
+
continue;
|
623 |
+
}
|
624 |
+
|
625 |
+
$output['current']['first_metric'][$i] = 0;
|
626 |
+
$output['current']['second_metric'][$i] = 0;
|
627 |
+
}
|
628 |
+
|
629 |
+
// No data? No problem!
|
630 |
+
if (!is_array($results) || empty($results)){
|
631 |
+
return ($output);
|
632 |
+
}
|
633 |
+
|
634 |
+
// Rearrange the data and then format it for Flot
|
635 |
+
foreach ($results as $i => $a_result){
|
636 |
+
$index = (!empty(self::$filters_normalized['date']['interval']))?floor(($a_result['dt'] - wp_slimstat_db::$filters_normalized['utime']['start'])/86400):gmdate($group_by[2], $a_result['dt']);
|
637 |
+
|
638 |
+
if (empty(self::$filters_normalized['date']['interval']) && gmdate(self::$filters_normalized['utime']['type'], $a_result['dt']) == gmdate(self::$filters_normalized['utime']['type'], $previous['start'])){
|
639 |
+
$output['previous']['first_metric'][$index] = $a_result['first_metric'];
|
640 |
+
$output['previous']['second_metric'][$index] = $a_result['second_metric'];
|
641 |
+
}
|
642 |
+
if (!empty(self::$filters_normalized['date']['interval']) || gmdate(self::$filters_normalized['utime']['type'], $a_result['dt']) == gmdate(self::$filters_normalized['utime']['type'], self::$filters_normalized['utime']['start'])){
|
643 |
+
$output['current']['first_metric'][$index] = $a_result['first_metric'];
|
644 |
+
$output['current']['second_metric'][$index] = $a_result['second_metric'];
|
645 |
+
}
|
646 |
+
}
|
647 |
+
|
648 |
+
return ($output);
|
649 |
+
}
|
650 |
+
|
651 |
+
public static function parse_filters($_filters = '', $_init_misc = true){
|
652 |
+
$filters_normalized = array(
|
653 |
+
'columns' => array(),
|
654 |
+
'date' => array(
|
655 |
+
'interval_direction' => '',
|
656 |
+
'is_past' => false
|
657 |
+
),
|
658 |
+
'misc' => $_init_misc?array(
|
659 |
+
'direction' => 'desc',
|
660 |
+
'limit_results' => wp_slimstat::$options['rows_to_show'],
|
661 |
+
'start_from' => 0
|
662 |
+
):array(),
|
663 |
+
'utime' => array(
|
664 |
+
'start' => 0,
|
665 |
+
'end' => 0,
|
666 |
+
'type' => 'm'
|
667 |
+
)
|
668 |
+
);
|
669 |
+
|
670 |
+
if (!empty($_filters)){
|
671 |
+
$matches = explode('&&&', $_filters);
|
672 |
+
|
673 |
+
foreach($matches as $idx => $a_match){
|
674 |
+
preg_match('/([^\s]+)\s([^\s]+)\s(.+)?/', urldecode($a_match), $a_filter);
|
675 |
+
|
676 |
+
if (empty($a_filter) || ((!array_key_exists($a_filter[1], self::$filter_names) || strpos($a_filter[1], 'no_filter') !== false) && strpos($a_filter[1], 'addon_') === false)){
|
677 |
+
continue;
|
678 |
+
}
|
679 |
+
|
680 |
+
switch($a_filter[1]){
|
681 |
+
case 'strtotime':
|
682 |
+
$custom_date = strtotime($a_filter[3].' UTC');
|
683 |
+
$filters_normalized['date']['day'] = date('j', $custom_date);
|
684 |
+
$filters_normalized['date']['month'] = date('n', $custom_date);
|
685 |
+
$filters_normalized['date']['year'] = date('Y', $custom_date);
|
686 |
+
break;
|
687 |
+
case 'minute':
|
688 |
+
case 'hour':
|
689 |
+
case 'day':
|
690 |
+
case 'month':
|
691 |
+
case 'year':
|
692 |
+
if (is_numeric($a_filter[3])){
|
693 |
+
$filters_normalized['date'][$a_filter[1]] = intval($a_filter[3]);
|
694 |
+
}
|
695 |
+
else{
|
696 |
+
// Try to apply strtotime to value
|
697 |
+
switch($a_filter[1]){
|
698 |
+
case 'minute':
|
699 |
+
$filters_normalized['date']['minute'] = date('i', strtotime($a_filter[3], date_i18n('U')));
|
700 |
+
$filters_normalized['date']['is_past'] = true;
|
701 |
+
break;
|
702 |
+
case 'hour':
|
703 |
+
$filters_normalized['date']['hour'] = date('H', strtotime($a_filter[3], date_i18n('U')));
|
704 |
+
$filters_normalized['date']['is_past'] = true;
|
705 |
+
break;
|
706 |
+
case 'day':
|
707 |
+
$filters_normalized['date']['day'] = date('j', strtotime($a_filter[3], date_i18n('U')));
|
708 |
+
break;
|
709 |
+
case 'month':
|
710 |
+
$filters_normalized['date']['month'] = date('n', strtotime($a_filter[3], date_i18n('U')));
|
711 |
+
break;
|
712 |
+
case 'year':
|
713 |
+
$filters_normalized['date']['year'] = date('Y', strtotime($a_filter[3], date_i18n('U')));
|
714 |
+
break;
|
715 |
+
default:
|
716 |
+
break;
|
717 |
+
}
|
718 |
+
|
719 |
+
if ($filters_normalized['date'][$a_filter[1]] === false){
|
720 |
+
unset($filters_normalized['date'][$a_filter[1]]);
|
721 |
+
}
|
722 |
+
}
|
723 |
+
|
724 |
+
switch($a_filter[1]){
|
725 |
+
case 'day':
|
726 |
+
if ($filters_normalized['date']['day'] != date_i18n('j')){
|
727 |
+
$filters_normalized['date']['is_past'] = true;
|
728 |
+
}
|
729 |
+
break;
|
730 |
+
case 'month':
|
731 |
+
if ($filters_normalized['date']['month'] != date_i18n('n')){
|
732 |
+
$filters_normalized['date']['is_past'] = true;
|
733 |
+
}
|
734 |
+
break;
|
735 |
+
case 'year':
|
736 |
+
if ($filters_normalized['date']['year'] != date_i18n('Y')){
|
737 |
+
$filters_normalized['date']['is_past'] = true;
|
738 |
+
}
|
739 |
+
break;
|
740 |
+
default:
|
741 |
+
break;
|
742 |
+
}
|
743 |
+
|
744 |
+
break;
|
745 |
+
case 'interval':
|
746 |
+
case 'interval_hours':
|
747 |
+
case 'interval_minutes':
|
748 |
+
$intval_filter = intval($a_filter[3]);
|
749 |
+
$filters_normalized['date'][$a_filter[1]] = abs($intval_filter);
|
750 |
+
if ($intval_filter < 0){
|
751 |
+
$filters_normalized['date']['interval_direction'] = 'minus';
|
752 |
+
}
|
753 |
+
break;
|
754 |
+
case 'interval_direction':
|
755 |
+
$filters_normalized['date'][$a_filter[1]] = in_array($a_filter[3], array('plus', 'minus'))?$a_filter[3]:'plus';
|
756 |
+
break;
|
757 |
+
case 'direction':
|
758 |
+
case 'limit_results':
|
759 |
+
case 'start_from':
|
760 |
+
$filters_normalized['misc'][$a_filter[1]] = str_replace('\\', '', htmlspecialchars_decode($a_filter[3]));
|
761 |
+
break;
|
762 |
+
default:
|
763 |
+
$filters_normalized['columns'][$a_filter[1]] = array($a_filter[2], isset($a_filter[3])?str_replace('\\', '', htmlspecialchars_decode($a_filter[3])):'');
|
764 |
+
break;
|
765 |
+
}
|
766 |
+
}
|
767 |
+
}
|
768 |
+
|
769 |
+
return $filters_normalized;
|
770 |
+
}
|
771 |
+
|
772 |
+
/**
|
773 |
+
* Associates tables and their 'SQL aliases'
|
774 |
+
*/
|
775 |
+
public static function get_table_alias($_field = 'id'){
|
776 |
+
switch($_field){
|
777 |
+
case 'browser_id':
|
778 |
+
case 'browser':
|
779 |
+
case 'version':
|
780 |
+
case 'css_version':
|
781 |
+
case 'type':
|
782 |
+
case 'platform':
|
783 |
+
case 'user_agent':
|
784 |
+
return 'tb';
|
785 |
+
break;
|
786 |
+
case 'content_info_id':
|
787 |
+
case 'author':
|
788 |
+
case 'category':
|
789 |
+
case 'content_type':
|
790 |
+
case 'content_id':
|
791 |
+
return 'tci';
|
792 |
+
break;
|
793 |
+
case 'outbound_id':
|
794 |
+
case 'outbound_domain':
|
795 |
+
case 'outbound_resource':
|
796 |
+
case 'position':
|
797 |
+
return 'tob';
|
798 |
+
break;
|
799 |
+
case 'screenres_id':
|
800 |
+
case 'resolution':
|
801 |
+
case 'colordepth':
|
802 |
+
case 'antialias':
|
803 |
+
return 'tss';
|
804 |
+
break;
|
805 |
+
default:
|
806 |
+
return 't1';
|
807 |
+
break;
|
808 |
+
}
|
809 |
+
}
|
810 |
+
// end get_table_alias
|
811 |
+
|
812 |
+
public static function get_col($_sql = ''){
|
813 |
+
$_sql = apply_filters('slimstat_get_col_sql', $_sql);
|
814 |
+
|
815 |
+
if (wp_slimstat::$options['show_sql_debug'] == 'yes'){
|
816 |
+
self::_show_debug($_sql);
|
817 |
+
}
|
818 |
+
|
819 |
+
return wp_slimstat::$wpdb->get_col($_sql);
|
820 |
+
}
|
821 |
+
|
822 |
+
public static function get_results($_sql = '', $_select_no_aggregate_values = '', $_order_by = '', $_group_by = '', $_aggregate_values_add = ''){
|
823 |
+
$_sql = apply_filters('slimstat_get_results_sql', $_sql, $_select_no_aggregate_values, $_order_by, $_group_by, $_aggregate_values_add);
|
824 |
+
|
825 |
+
if (wp_slimstat::$options['show_sql_debug'] == 'yes'){
|
826 |
+
self::_show_debug($_sql);
|
827 |
+
}
|
828 |
+
|
829 |
+
return wp_slimstat::$wpdb->get_results($_sql, ARRAY_A);
|
830 |
+
}
|
831 |
+
|
832 |
+
public static function get_var($_sql = '', $_aggregate_value = ''){
|
833 |
+
$_sql = apply_filters('slimstat_get_var_sql', $_sql, $_aggregate_value);
|
834 |
+
|
835 |
+
if (wp_slimstat::$options['show_sql_debug'] == 'yes'){
|
836 |
+
self::_show_debug($_sql);
|
837 |
+
}
|
838 |
+
|
839 |
+
return wp_slimstat::$wpdb->get_var($_sql);
|
840 |
+
}
|
841 |
+
|
842 |
+
protected static function _add_filters_to_sql_from($_sql_tables = '', $_ignore_empty = false){
|
843 |
+
$sql_from = '';
|
844 |
+
if (($_ignore_empty || empty(self::$sql_filters['from']['tb'])) && strpos($_sql_tables, 'tb.') !== false)
|
845 |
+
$sql_from .= " INNER JOIN {$GLOBALS['wpdb']->base_prefix}slim_browsers tb ON t1.browser_id = tb.browser_id";
|
846 |
+
|
847 |
+
if (($_ignore_empty || empty(self::$sql_filters['from']['tci'])) && strpos($_sql_tables, 'tci.') !== false)
|
848 |
+
$sql_from .= " INNER JOIN {$GLOBALS['wpdb']->base_prefix}slim_content_info tci ON t1.content_info_id = tci.content_info_id";
|
849 |
+
|
850 |
+
if (($_ignore_empty || empty(self::$sql_filters['from']['tob'])) && strpos($_sql_tables, 'tob.') !== false)
|
851 |
+
$sql_from .= " LEFT JOIN {$GLOBALS['wpdb']->prefix}slim_outbound tob ON t1.id = tob.id";
|
852 |
+
|
853 |
+
if (($_ignore_empty || empty(self::$sql_filters['from']['tss'])) && strpos($_sql_tables, 'tss.') !== false)
|
854 |
+
$sql_from .= " LEFT JOIN {$GLOBALS['wpdb']->base_prefix}slim_screenres tss ON t1.screenres_id = tss.screenres_id";
|
855 |
+
|
856 |
+
return $sql_from;
|
857 |
+
}
|
858 |
+
|
859 |
+
protected static function _get_lookup_rows($_where = array(), $_group_by_column = ''){
|
860 |
+
foreach ($_custom_where as $a_table_column => $a_filter_column){
|
861 |
+
$table_alias = self::get_table_alias($a_table_column);
|
862 |
+
|
863 |
+
$where_ids = self::get_results('
|
864 |
+
SELECT *
|
865 |
+
FROM '.$GLOBALS['wpdb']->base_prefix.self::$sql_filters['table_info'][$a_table_alias][0].' '.$a_table_alias.'
|
866 |
+
WHERE 1=1'.self::$sql_filters['where'][$a_table_alias]);
|
867 |
+
|
868 |
+
if (!empty(self::$sql_filters['id'][$a_table_alias])){
|
869 |
+
$table_ids = array();
|
870 |
+
foreach (self::$sql_filters['id'][$a_table_alias] as $a_result){
|
871 |
+
$table_ids[] = $a_result[self::$sql_filters['table_info'][$a_table_alias][1]];
|
872 |
+
}
|
873 |
+
self::$sql_filters['where'][$a_table_alias] = ' AND t1.'.self::$sql_filters['table_info'][$a_table_alias][1].' IN ('.implode(',', $table_ids).')';
|
874 |
+
}
|
875 |
+
}
|
876 |
+
}
|
877 |
+
|
878 |
+
protected static function _show_debug($_message = ''){
|
879 |
+
echo "<p class='debug'>$_message</p>";
|
880 |
+
}
|
881 |
+
}
|
admin/wp-slimstat-admin.php
CHANGED
@@ -12,9 +12,8 @@ class wp_slimstat_admin{
|
|
12 |
*/
|
13 |
public static function init(){
|
14 |
if ((wp_slimstat::$options['enable_ads_network'] == 'yes' || wp_slimstat::$options['enable_ads_network'] == 'no')){
|
15 |
-
self::$admin_notice = "The team who manages the WordPress Plugin Repository notified us that since the <a href='http://dev.maxmind.com/geoip/legacy/geolite/' target='_blank'>MaxMind GeoLite library</a> used by Slimstat to geolocate visitors is
|
16 |
|
17 |
-
// 3.9.8 self::$admin_notice = "We've been working on the documentation for Slimstat. Now you can find <a href='https://slimstat.freshdesk.com/support/solutions' target='_blank'>detailed information</a> about all the actions and filters available in our source code. Developers, use them to build your own custom add-ons! We are also adding video tours of our add-ons, and organizing the source code to make it easier to read and understand.";
|
18 |
// 3.9.9 self::$admin_notice = "Happy birthday, Slimstat. Nine years ago version 0.8.7 was released to the public, starting the unbelievable journey that has taken us here today. We would like to thank all the 25,000 users who appreciate and support our work in many great ways. We wouldn't have more than 1.3 million downloads, 4.8 out of 5 overall rating, 16 add-ons, video tutorials, etc... if it weren't for you!";
|
19 |
}
|
20 |
else {
|
@@ -613,7 +612,16 @@ class wp_slimstat_admin{
|
|
613 |
* Adds a new column header to the Posts panel (to show the number of pageviews for each post)
|
614 |
*/
|
615 |
public static function add_column_header($_columns){
|
616 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
617 |
return $_columns;
|
618 |
}
|
619 |
// end add_comment_column_header
|
@@ -626,12 +634,22 @@ class wp_slimstat_admin{
|
|
626 |
|
627 |
include_once(dirname(__FILE__).'/view/wp-slimstat-reports.php');
|
628 |
wp_slimstat_reports::init();
|
629 |
-
|
|
|
|
|
|
|
|
|
630 |
$parsed_permalink = parse_url( get_permalink($_post_id) );
|
631 |
$parsed_permalink = $parsed_permalink['path'].(!empty($parsed_permalink['query'])?'?'.$parsed_permalink['query']:'');
|
632 |
-
wp_slimstat_db::init('resource contains '.$parsed_permalink.'&&&hour equals 0&&&day equals '.date_i18n('d').'&&&month equals '.date_i18n('m').'&&&year equals '.date_i18n('Y').'&&&interval equals
|
633 |
-
|
634 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
635 |
}
|
636 |
// end add_column
|
637 |
|
12 |
*/
|
13 |
public static function init(){
|
14 |
if ((wp_slimstat::$options['enable_ads_network'] == 'yes' || wp_slimstat::$options['enable_ads_network'] == 'no')){
|
15 |
+
self::$admin_notice = "The team who manages the WordPress Plugin Repository notified us that since the <a href='http://dev.maxmind.com/geoip/legacy/geolite/' target='_blank'>MaxMind GeoLite library</a> used by Slimstat to geolocate visitors is released under the Creative Commons BY-SA 3.0 license, it violates the repository guidelines, and cannot be bundled with the plugin any longer. We were required to remove the code and alter the plugin so that this functionality becomes optional. We apologize for the inconvenience. However, the only immediate consequence is that your visitors' country will not be identified; everything else will still work as usual. You can download the geolocation DB as a <a href='http://slimstat.getused.to.it/downloads/get-country/' target='_blank'>separate add-on</a> on our store, free of charge. Don't forget to enter your license key in the corresponding field under Slimstat > Add-ons, to receive free updates!";
|
16 |
|
|
|
17 |
// 3.9.9 self::$admin_notice = "Happy birthday, Slimstat. Nine years ago version 0.8.7 was released to the public, starting the unbelievable journey that has taken us here today. We would like to thank all the 25,000 users who appreciate and support our work in many great ways. We wouldn't have more than 1.3 million downloads, 4.8 out of 5 overall rating, 16 add-ons, video tutorials, etc... if it weren't for you!";
|
18 |
}
|
19 |
else {
|
612 |
* Adds a new column header to the Posts panel (to show the number of pageviews for each post)
|
613 |
*/
|
614 |
public static function add_column_header($_columns){
|
615 |
+
if (wp_slimstat::$options['posts_column_day_interval'] == 0){
|
616 |
+
wp_slimstat::$options['posts_column_day_interval'] = 30;
|
617 |
+
}
|
618 |
+
|
619 |
+
if (wp_slimstat::$options['posts_column_pageviews'] == 'yes'){
|
620 |
+
$_columns['wp-slimstat'] = '<span class="slimstat-icon" title="'.__('Pageviews in the last '.wp_slimstat::$options['posts_column_day_interval'].' days','wp-slimstat').'"></span>';
|
621 |
+
}
|
622 |
+
else{
|
623 |
+
$_columns['wp-slimstat'] = '<span class="slimstat-icon" title="'.__('Unique IPs in the last '.wp_slimstat::$options['posts_column_day_interval'].' days','wp-slimstat').'"></span>';
|
624 |
+
}
|
625 |
return $_columns;
|
626 |
}
|
627 |
// end add_comment_column_header
|
634 |
|
635 |
include_once(dirname(__FILE__).'/view/wp-slimstat-reports.php');
|
636 |
wp_slimstat_reports::init();
|
637 |
+
|
638 |
+
if (wp_slimstat::$options['posts_column_day_interval'] == 0){
|
639 |
+
wp_slimstat::$options['posts_column_day_interval'] = 30;
|
640 |
+
}
|
641 |
+
|
642 |
$parsed_permalink = parse_url( get_permalink($_post_id) );
|
643 |
$parsed_permalink = $parsed_permalink['path'].(!empty($parsed_permalink['query'])?'?'.$parsed_permalink['query']:'');
|
644 |
+
wp_slimstat_db::init('resource contains '.$parsed_permalink.'&&&hour equals 0&&&day equals '.date_i18n('d').'&&&month equals '.date_i18n('m').'&&&year equals '.date_i18n('Y').'&&&interval equals '.wp_slimstat::$options['posts_column_day_interval'].'&&&interval_direction equals minus');
|
645 |
+
|
646 |
+
if (wp_slimstat::$options['posts_column_pageviews'] == 'yes'){
|
647 |
+
$count = wp_slimstat_db::count_records();
|
648 |
+
}
|
649 |
+
else{
|
650 |
+
$count = wp_slimstat_db::count_records('1=1', 't1.ip');
|
651 |
+
}
|
652 |
+
echo '<a href="'.wp_slimstat_reports::fs_url("resource contains $parsed_permalink&&&day equals ".date_i18n('d').'&&&month equals '.date_i18n('m').'&&&year equals '.date_i18n('Y').'&&&interval equals '.wp_slimstat::$options['posts_column_day_interval'].'&&interval_direction equals minus').'">'.$count.'</a>';
|
653 |
}
|
654 |
// end add_column
|
655 |
|
readme.txt
CHANGED
@@ -4,10 +4,10 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_i
|
|
4 |
Tags: analytics, tracking, reports, analyze, wassup, geolocation, online users, spider, tracker, pageviews, stats, maxmind, statistics, statpress
|
5 |
Requires at least: 3.8
|
6 |
Tested up to: 4.2
|
7 |
-
Stable tag: 3.9.
|
8 |
|
9 |
== Description ==
|
10 |
-
|
11 |
|
12 |
= Key Features =
|
13 |
* Real-time activity log, server latency, heatmaps, email reports, export data to Excel, and much more
|
@@ -16,6 +16,14 @@ Visit our [website](http://slimstat.getused.to.it/) for more information and to
|
|
16 |
* Available in multiple languages: English, Chinese (沐熙工作室), Farsi ([Dean](http://www.mangallery.net)), French (Michael Bastin, Jean-Michel Venet, Yves Pouplard, Henrick Kac), German (TechnoViel), Italian, Japanese (h_a_l_f), Portuguese, Russian ([Vitaly](http://www.visbiz.org/)), Spanish ([WebHostingHub](http://www.webhostinghub.com/)), Swedish (Per Soderman). Is your language missing or incomplete? [Contact Us](http://support.getused.to.it/) if you would like to share your localization.
|
17 |
* World Map that works on your mobile device, too (courtesy of [amMap](http://www.ammap.com/)).
|
18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
= What are people saying about Slimstat? =
|
20 |
* One of the 15+ Cool Free SEO Plugins for WordPress - [udesign](http://www.pixeldetail.com/wordpress/free-seo-plugins-for-wordpress/)
|
21 |
* 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)
|
@@ -62,8 +70,10 @@ Our knowledge base is available on our [support center](https://slimstat.freshde
|
|
62 |
5. **Responsive layout** - Keep an eye on your reports on the go
|
63 |
|
64 |
== Changelog ==
|
65 |
-
|
66 |
-
|
|
|
|
|
67 |
|
68 |
= 3.9.7 =
|
69 |
* [Note] The uninstall routine now deletes the archive table (wp_slim_stats_archive) along with all the other tables (thank you, KalleL)
|
4 |
Tags: analytics, tracking, reports, analyze, wassup, geolocation, online users, spider, tracker, pageviews, stats, maxmind, statistics, statpress
|
5 |
Requires at least: 3.8
|
6 |
Tested up to: 4.2
|
7 |
+
Stable tag: 3.9.8
|
8 |
|
9 |
== Description ==
|
10 |
+
[youtube https://www.youtube.com/watch?v=iJCtjxArq4U]
|
11 |
|
12 |
= Key Features =
|
13 |
* Real-time activity log, server latency, heatmaps, email reports, export data to Excel, and much more
|
16 |
* Available in multiple languages: English, Chinese (沐熙工作室), Farsi ([Dean](http://www.mangallery.net)), French (Michael Bastin, Jean-Michel Venet, Yves Pouplard, Henrick Kac), German (TechnoViel), Italian, Japanese (h_a_l_f), Portuguese, Russian ([Vitaly](http://www.visbiz.org/)), Spanish ([WebHostingHub](http://www.webhostinghub.com/)), Swedish (Per Soderman). Is your language missing or incomplete? [Contact Us](http://support.getused.to.it/) if you would like to share your localization.
|
17 |
* World Map that works on your mobile device, too (courtesy of [amMap](http://www.ammap.com/)).
|
18 |
|
19 |
+
= Track countries by IP Address =
|
20 |
+
Starting from Slimstat 3.9.8, we removed the functionality that allows the tracker to identify a visitor's country based on his IP address.
|
21 |
+
The team who manages the WordPress Plugin Repository notified us that since the [MaxMind GeoLite library](http://dev.maxmind.com/geoip/legacy/geolite/)
|
22 |
+
used by our plugin to geolocate visitors is released under the Creative Commons BY-SA 3.0 license, it violates the repository guidelines, and cannot
|
23 |
+
be bundled with the code. We were required to remove it and alter the plugin so that this functionality becomes optional. By default, your visitors' country
|
24 |
+
will be set to Unknown. You can download the geolocation DB as a [separate add-on](http://slimstat.getused.to.it/downloads/get-country/) on our website, free of charge,
|
25 |
+
to restore this feature. Don't forget to enter your license key in the corresponding field under Slimstat > Add-ons, to receive free updates!
|
26 |
+
|
27 |
= What are people saying about Slimstat? =
|
28 |
* One of the 15+ Cool Free SEO Plugins for WordPress - [udesign](http://www.pixeldetail.com/wordpress/free-seo-plugins-for-wordpress/)
|
29 |
* 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)
|
70 |
5. **Responsive layout** - Keep an eye on your reports on the go
|
71 |
|
72 |
== Changelog ==
|
73 |
+
|
74 |
+
= 3.9.8 =
|
75 |
+
* [Note] The team who manages the WordPress Plugin Repository notified us that since the [MaxMind GeoLite library](http://dev.maxmind.com/geoip/legacy/geolite/) used by Slimstat to geolocate visitors is released under the Creative Commons BY-SA 3.0 license, it violates the repository guidelines, and cannot be bundled with the plugin. We were required to remove the code and alter the plugin so that this functionality becomes optional. We apologize for the inconvenience. However, the only immediate consequence is that your visitors' country will not be identified; everything else will still work as usual. You can download the geolocation DB as a [separate add-on](http://slimstat.getused.to.it/downloads/get-country/) on our store, free of charge. Don't forget to enter your license key in the corresponding field under Slimstat > Add-ons, to receive free updates!
|
76 |
+
* [New] A few new options under Slimstat > Settings > General tab > WordPress Integration section, allow you to have more control over the information displayed in the Posts admin screen (thank you, Brad).
|
77 |
|
78 |
= 3.9.7 =
|
79 |
* [Note] The uninstall routine now deletes the archive table (wp_slim_stats_archive) along with all the other tables (thank you, KalleL)
|
wp-slimstat.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: WP Slimstat
|
4 |
Plugin URI: http://wordpress.org/plugins/wp-slimstat/
|
5 |
Description: The leading web analytics plugin for WordPress
|
6 |
-
Version: 3.9.
|
7 |
Author: Camu
|
8 |
Author URI: http://slimstat.getused.to.it/
|
9 |
*/
|
@@ -11,7 +11,7 @@ Author URI: http://slimstat.getused.to.it/
|
|
11 |
if (!empty(wp_slimstat::$options)) return true;
|
12 |
|
13 |
class wp_slimstat{
|
14 |
-
public static $version = '3.9.
|
15 |
public static $options = array();
|
16 |
|
17 |
public static $wpdb = '';
|
@@ -489,7 +489,7 @@ class wp_slimstat{
|
|
489 |
// end slimtrack
|
490 |
|
491 |
/**
|
492 |
-
* Searches for country associated to a given IP address
|
493 |
*/
|
494 |
public static function get_country($_ipnum = 0){
|
495 |
$float_ipnum = (float)sprintf("%u", $_ipnum);
|
@@ -501,39 +501,8 @@ class wp_slimstat{
|
|
501 |
($float_ipnum >= 3232235521 && $float_ipnum <= 3232301055) ){ // 192.168.0.1 - 192.168.255.255
|
502 |
return 'xy';
|
503 |
}
|
504 |
-
|
505 |
-
$country_codes = array("","ap","eu","ad","ae","af","ag","ai","al","am","cw","ao","aq","ar","as","at","au","aw","az","ba","bb","bd","be","bf","bg","bh","bi","bj","bm","bn","bo","br","bs","bt","bv","bw","by","bz","ca","cc","cd","cf","cg","ch","ci","ck","cl","cm","cn","co","cr","cu","cv","cx","cy","cz","de","dj","dk","dm","do","dz","ec","ee","eg","eh","er","es","et","fi","fj","fk","fm","fo","fr","sx","ga","gb","gd","ge","gf","gh","gi","gl","gm","gn","gp","gq","gr","gs","gt","gu","gw","gy","hk","hm","hn","hr","ht","hu","id","ie","il","in","io","iq","ir","is","it","jm","jo","jp","ke","kg","kh","ki","km","kn","kp","kr","kw","ky","kz","la","lb","lc","li","lk","lr","ls","lt","lu","lv","ly","ma","mc","md","mg","mh","mk","ml","mm","mn","mo","mp","mq","mr","ms","mt","mu","mv","mw","mx","my","mz","na","nc","ne","nf","ng","ni","nl","no","np","nr","nu","nz","om","pa","pe","pf","pg","ph","pk","pl","pm","pn","pr","ps","pt","pw","py","qa","re","ro","ru","rw","sa","sb","sc","sd","se","sg","sh","si","sj","sk","sl","sm","sn","so","sr","st","sv","sy","sz","tc","td","tf","tg","th","tj","tk","tm","tn","to","tl","tr","tt","tv","tw","tz","ua","ug","um","us","uy","uz","va","vc","ve","vg","vi","vn","vu","wf","ws","ye","yt","rs","za","zm","me","zw","a1","a2","o1","ax","gg","im","je","bl","mf","bq","ss","o1");
|
506 |
-
if (!$handle = fopen(WP_PLUGIN_DIR."/wp-slimstat/databases/maxmind.dat", "rb")){
|
507 |
-
return 'xx';
|
508 |
-
}
|
509 |
-
|
510 |
-
$offset = 0;
|
511 |
-
for ($depth = 31; $depth >= 0; --$depth) {
|
512 |
-
if (fseek($handle, 6 * $offset, SEEK_SET) != 0) return 'xx';
|
513 |
-
$buf = fread($handle, 6);
|
514 |
-
$x = array(0,0);
|
515 |
-
for ($i = 0; $i < 2; ++$i) {
|
516 |
-
for ($j = 0; $j < 3; ++$j) {
|
517 |
-
$x[$i] += ord(substr($buf, 3 * $i + $j, 1)) << ($j * 8);
|
518 |
-
}
|
519 |
-
}
|
520 |
|
521 |
-
|
522 |
-
if ($x[1] >= 16776960 && !empty($country_codes[$x[1] - 16776960])) {
|
523 |
-
fclose($handle);
|
524 |
-
return $country_codes[$x[1] - 16776960];
|
525 |
-
}
|
526 |
-
$offset = $x[1];
|
527 |
-
} else {
|
528 |
-
if ($x[0] >= 16776960 && !empty($country_codes[$x[0] - 16776960])) {
|
529 |
-
fclose($handle);
|
530 |
-
return $country_codes[$x[0] - 16776960];
|
531 |
-
}
|
532 |
-
$offset = $x[0];
|
533 |
-
}
|
534 |
-
}
|
535 |
-
fclose($handle);
|
536 |
-
return 'xx';
|
537 |
}
|
538 |
// end get_country
|
539 |
|
@@ -1182,6 +1151,8 @@ class wp_slimstat{
|
|
1182 |
'enable_javascript' => $val_yes,
|
1183 |
'javascript_mode' => $val_yes,
|
1184 |
'add_posts_column' => $val_no,
|
|
|
|
|
1185 |
'use_separate_menu' => $val_yes,
|
1186 |
'auto_purge_delete' => $val_yes,
|
1187 |
'auto_purge' => 0,
|
3 |
Plugin Name: WP Slimstat
|
4 |
Plugin URI: http://wordpress.org/plugins/wp-slimstat/
|
5 |
Description: The leading web analytics plugin for WordPress
|
6 |
+
Version: 3.9.8
|
7 |
Author: Camu
|
8 |
Author URI: http://slimstat.getused.to.it/
|
9 |
*/
|
11 |
if (!empty(wp_slimstat::$options)) return true;
|
12 |
|
13 |
class wp_slimstat{
|
14 |
+
public static $version = '3.9.8';
|
15 |
public static $options = array();
|
16 |
|
17 |
public static $wpdb = '';
|
489 |
// end slimtrack
|
490 |
|
491 |
/**
|
492 |
+
* Searches for the country code associated to a given IP address
|
493 |
*/
|
494 |
public static function get_country($_ipnum = 0){
|
495 |
$float_ipnum = (float)sprintf("%u", $_ipnum);
|
501 |
($float_ipnum >= 3232235521 && $float_ipnum <= 3232301055) ){ // 192.168.0.1 - 192.168.255.255
|
502 |
return 'xy';
|
503 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
504 |
|
505 |
+
return apply_filters('slimstat_get_country', 'xx', $_ipnum);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
506 |
}
|
507 |
// end get_country
|
508 |
|
1151 |
'enable_javascript' => $val_yes,
|
1152 |
'javascript_mode' => $val_yes,
|
1153 |
'add_posts_column' => $val_no,
|
1154 |
+
'posts_column_day_interval' => 30,
|
1155 |
+
'posts_column_pageviews' => $val_yes,
|
1156 |
'use_separate_menu' => $val_yes,
|
1157 |
'auto_purge_delete' => $val_yes,
|
1158 |
'auto_purge' => 0,
|