Version Description
- [New] Contextual counters are now added not just to pages and posts, but to other custom post types available on your website.
- [Update] Optimized SQL query that retrieves the data for the Access Log report.
- [Update] New link for GetSocial.io partnership.
- [Fix] Patched a remote XSS vulnerability related to forged referrer URLs.
- [Fix] Bug in refreshing Access Log (second try).
- [Fix] Bug in calculating Unique IP counters for pages and posts.
- [Fix] Link to install the GeoLocation DB was pointing to the wrong tab under Settings.
- [Fix] When selecting the filter in Overview > Top Pages, reports were returning empty datasets.
- [Fix] Resetting the report layout was not always working as expected, if Slimstat was displayed in the admin bar.
Download this release
Release Info
Developer | coolmann |
Plugin | Slimstat Analytics |
Version | 4.1.6.1 |
Comparing to | |
See all releases |
Code changes from version 4.1.6 to 4.1.6.1
- admin/config/addons.php +14 -2
- admin/config/index.php +1 -1
- admin/config/maintenance.php +4 -0
- admin/view/wp-slimstat-db.php +956 -926
- admin/view/wp-slimstat-reports.php +16 -10
- admin/wp-slimstat-admin.php +2 -2
- readme.txt +19 -44
- wp-slimstat.php +19 -13
admin/config/addons.php
CHANGED
@@ -54,11 +54,23 @@ if (!is_array($list_addons)){
|
|
54 |
<strong><a target="_blank" href="<?php echo $a_addon['download_url'] ?>"><?php echo $a_addon['name'] ?></a></strong>
|
55 |
<div class="row-actions-visible"><?php
|
56 |
if ( !empty( $a_addon['version'] ) ) {
|
57 |
-
echo 'Version: '
|
58 |
}
|
59 |
|
60 |
if ( $is_active ){
|
61 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
$at_least_one_add_on_active = true;
|
63 |
}
|
64 |
else{
|
54 |
<strong><a target="_blank" href="<?php echo $a_addon['download_url'] ?>"><?php echo $a_addon['name'] ?></a></strong>
|
55 |
<div class="row-actions-visible"><?php
|
56 |
if ( !empty( $a_addon['version'] ) ) {
|
57 |
+
echo ( $is_active ? __( 'Repo Version', 'wp-slimstat' ) : __( 'Version', 'wp-slimstat' ) ) . ': ' . $a_addon[ 'version' ].'<br/>';
|
58 |
}
|
59 |
|
60 |
if ( $is_active ){
|
61 |
+
if ( is_plugin_active($a_addon['slug'].'/index.php') ) {
|
62 |
+
$plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $a_addon['slug'] . '/index.php' );
|
63 |
+
}
|
64 |
+
else {
|
65 |
+
$plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $a_addon['slug'] . '/' . $a_addon['slug'] );
|
66 |
+
}
|
67 |
+
|
68 |
+
if ( !empty( $plugin_data[ 'Version' ] ) ) {
|
69 |
+
echo __( 'Your Version:', 'wp-slimstat' ) . ' ' . $plugin_data[ 'Version' ];
|
70 |
+
}
|
71 |
+
else{
|
72 |
+
_e( 'Installed and Active', 'wp-slimstat' );
|
73 |
+
}
|
74 |
$at_least_one_add_on_active = true;
|
75 |
}
|
76 |
else{
|
admin/config/index.php
CHANGED
@@ -242,7 +242,7 @@ $options = array(
|
|
242 |
'show_sql_debug' => array('description' => __('Debug Mode','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Display the SQL queries used to retrieve the data.','wp-slimstat')),
|
243 |
'ip_lookup_service' => array('description' => __('IP Lookup','wp-slimstat'), 'type' => 'text', 'long_description' => __('Customize the Geolocation service to be used in the reports.','wp-slimstat')),
|
244 |
'custom_css' => array('description' => __('Custom CSS','wp-slimstat'), 'type' => 'textarea', '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')),
|
245 |
-
'enable_ads_network' => array('description' => __('Enable UAN','wp-slimstat'), 'type' => 'yesno', 'long_description' => __("Send anonymous data about user agents to our server for analysis. This allows us to contribute to the <a href='http://browscap.org/' target='_blank'>BrowsCap opensource project</a>, and improve the accuracy of Slimstat's browser detection functionality. It also enables our transparent ads network. No worries, your site will not be affected in any way.",'wp-slimstat'))
|
246 |
)
|
247 |
),
|
248 |
|
242 |
'show_sql_debug' => array('description' => __('Debug Mode','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Display the SQL queries used to retrieve the data.','wp-slimstat')),
|
243 |
'ip_lookup_service' => array('description' => __('IP Lookup','wp-slimstat'), 'type' => 'text', 'long_description' => __('Customize the Geolocation service to be used in the reports.','wp-slimstat')),
|
244 |
'custom_css' => array('description' => __('Custom CSS','wp-slimstat'), 'type' => 'textarea', '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')),
|
245 |
+
'enable_ads_network' => array('description' => __('Enable UAN','wp-slimstat'), 'type' => 'yesno', 'long_description' => __("Send anonymous data about user agents to our server for analysis. This allows us to contribute to the <a href='http://browscap.org/' target='_blank'>BrowsCap opensource project</a>, and improve the accuracy of Slimstat's browser detection functionality. It also enables our transparent ads network. No worries, your site will not be affected in any way. Please note, this option is enabled only when the setting is explicitly set to YES.",'wp-slimstat'))
|
246 |
)
|
247 |
),
|
248 |
|
admin/config/maintenance.php
CHANGED
@@ -159,6 +159,10 @@ if (!empty($_REQUEST['action'])){
|
|
159 |
break;
|
160 |
|
161 |
case 'restore-views':
|
|
|
|
|
|
|
|
|
162 |
$GLOBALS['wpdb']->query("DELETE FROM {$GLOBALS['wpdb']->prefix}usermeta WHERE meta_key LIKE '%meta-box-order_slimstat%'");
|
163 |
$GLOBALS['wpdb']->query("DELETE FROM {$GLOBALS['wpdb']->prefix}usermeta WHERE meta_key LIKE '%metaboxhidden_slimstat%'");
|
164 |
$GLOBALS['wpdb']->query("DELETE FROM {$GLOBALS['wpdb']->prefix}usermeta WHERE meta_key LIKE '%closedpostboxes_slimstat%'");
|
159 |
break;
|
160 |
|
161 |
case 'restore-views':
|
162 |
+
$GLOBALS['wpdb']->query("DELETE FROM {$GLOBALS['wpdb']->prefix}usermeta WHERE meta_key LIKE '%meta-box-order_admin_page_wp-slim-view-%'");
|
163 |
+
$GLOBALS['wpdb']->query("DELETE FROM {$GLOBALS['wpdb']->prefix}usermeta WHERE meta_key LIKE '%meta-box-order_slimstat_page_wp-slim-view-%'");
|
164 |
+
$GLOBALS['wpdb']->query("DELETE FROM {$GLOBALS['wpdb']->prefix}usermeta WHERE meta_key LIKE '%mmetaboxhidden_admin_page_wp-slim-view-%'");
|
165 |
+
$GLOBALS['wpdb']->query("DELETE FROM {$GLOBALS['wpdb']->prefix}usermeta WHERE meta_key LIKE '%mmetaboxhidden_slimstat_page_wp-slim-view-%'");
|
166 |
$GLOBALS['wpdb']->query("DELETE FROM {$GLOBALS['wpdb']->prefix}usermeta WHERE meta_key LIKE '%meta-box-order_slimstat%'");
|
167 |
$GLOBALS['wpdb']->query("DELETE FROM {$GLOBALS['wpdb']->prefix}usermeta WHERE meta_key LIKE '%metaboxhidden_slimstat%'");
|
168 |
$GLOBALS['wpdb']->query("DELETE FROM {$GLOBALS['wpdb']->prefix}usermeta WHERE meta_key LIKE '%closedpostboxes_slimstat%'");
|
admin/view/wp-slimstat-db.php
CHANGED
@@ -1,927 +1,957 @@
|
|
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 $filters_normalized = array();
|
8 |
-
|
9 |
-
// Number and date formats
|
10 |
-
public static $formats = array( 'decimal' => ',', 'thousand' => '.' );
|
11 |
-
|
12 |
-
// Structure that maps filters to SQL information (table names, clauses, lookup tables, etc)
|
13 |
-
public static $sql_where = array( 'columns' => '', 'time_range' => '' );
|
14 |
-
|
15 |
-
// Filters that are not visible in the dropdown
|
16 |
-
public static $all_columns_names = array();
|
17 |
-
|
18 |
-
// Debug message
|
19 |
-
public static $debug_message = '';
|
20 |
-
|
21 |
-
/*
|
22 |
-
* Sets the filters and other structures needed to store the data retrieved from the DB
|
23 |
-
*/
|
24 |
-
public static function init( $_filters = '' ){
|
25 |
-
// Decimal and thousand separators
|
26 |
-
if ( wp_slimstat::$options[ 'use_european_separators' ] == 'no' ){
|
27 |
-
self::$formats[ 'decimal' ] = '.';
|
28 |
-
self::$formats[ 'thousand' ] = ',';
|
29 |
-
}
|
30 |
-
|
31 |
-
// Filters are defined as: browser equals Chrome|country starts_with en
|
32 |
-
if ( !is_string( $_filters ) || empty( $_filters ) ){
|
33 |
-
$_filters = '';
|
34 |
-
}
|
35 |
-
|
36 |
-
// List of supported filters and their friendly names
|
37 |
-
self::$columns_names = array(
|
38 |
-
'no_filter_selected_1' => array( ' ', 'none' ),
|
39 |
-
'browser' => array( __( 'Browser', 'wp-slimstat' ), 'varchar' ),
|
40 |
-
'country' => array( __( 'Country Code', 'wp-slimstat' ), 'varchar' ),
|
41 |
-
'ip' => array( __( 'IP Address', 'wp-slimstat' ), 'varchar' ),
|
42 |
-
'searchterms' => array( __( 'Search Terms', 'wp-slimstat' ), 'varchar' ),
|
43 |
-
'language' => array( __( 'Language Code', 'wp-slimstat' ), 'varchar' ),
|
44 |
-
'platform' => array( __( 'Operating System', 'wp-slimstat' ), 'varchar' ),
|
45 |
-
'resource' => array( __( 'Permalink', 'wp-slimstat' ), 'varchar' ),
|
46 |
-
'referer' => array( __( 'Referer', 'wp-slimstat' ), 'varchar' ),
|
47 |
-
'username' => array( __( 'Visitor\'s Name', 'wp-slimstat' ), 'varchar' ),
|
48 |
-
'outbound_resource' => array( __( 'Outbound Link', 'wp-slimstat' ), 'varchar' ),
|
49 |
-
'page_performance' => array( __( 'Page Speed', 'wp-slimstat' ), 'int' ),
|
50 |
-
'no_filter_selected_2' => array( ' ', 'none' ),
|
51 |
-
'no_filter_selected_3' => array( __( '-- Advanced filters --', 'wp-slimstat' ), 'none' ),
|
52 |
-
'plugins' => array( __( 'Browser Capabilities', 'wp-slimstat' ), 'varchar' ),
|
53 |
-
'browser_version' => array( __( 'Browser Version', 'wp-slimstat' ), 'varchar' ),
|
54 |
-
'browser_type' => array( __( 'Browser Type', 'wp-slimstat' ), 'int' ),
|
55 |
-
'user_agent' => array( __( 'User Agent', 'wp-slimstat' ), 'varchar' ),
|
56 |
-
'notes' => array( __( 'Annotations', 'wp-slimstat' ), 'varchar' ),
|
57 |
-
'server_latency' => array( __( 'Server Latency', 'wp-slimstat' ), 'int' ),
|
58 |
-
'author' => array( __( 'Post Author', 'wp-slimstat' ), 'varchar' ),
|
59 |
-
'category' => array( __( 'Post Category ID', 'wp-slimstat' ), 'varchar' ),
|
60 |
-
'other_ip' => array( __( 'Originating IP', 'wp-slimstat' ), 'varchar' ),
|
61 |
-
'content_type' => array( __( 'Resource Content Type', 'wp-slimstat' ), 'varchar' ),
|
62 |
-
'content_id' => array( __( 'Resource ID', 'wp-slimstat' ), 'int' ),
|
63 |
-
'screen_width' => array( __( 'Screen Width', 'wp-slimstat' ), 'int' ),
|
64 |
-
'screen_height' => array( __( 'Screen Height', 'wp-slimstat' ), 'int' ),
|
65 |
-
'resolution' => array( __( 'Viewport Size', 'wp-slimstat' ), 'varchar' ),
|
66 |
-
'visit_id' => array( __( 'Visit ID', 'wp-slimstat' ), 'int' )
|
67 |
-
);
|
68 |
-
|
69 |
-
// The following filters will not be displayed in the dropdown
|
70 |
-
self::$all_columns_names = array_merge( array(
|
71 |
-
|
72 |
-
// Date and Time
|
73 |
-
'minute' => array( __( 'Minute', 'wp-slimstat' ), 'int' ),
|
74 |
-
'hour' => array( __( 'Hour', 'wp-slimstat' ), 'int' ),
|
75 |
-
'day' => array( __( 'Day', 'wp-slimstat' ), 'int' ),
|
76 |
-
'month' => array( __( 'Month', 'wp-slimstat' ), 'int' ),
|
77 |
-
'year' => array( __( 'Year', 'wp-slimstat' ), 'int' ),
|
78 |
-
'interval_direction' => array( __( '+/-', 'wp-slimstat' ), 'int' ),
|
79 |
-
'interval' => array( __( 'days', 'wp-slimstat' ), 'int' ),
|
80 |
-
'interval_hours' => array( __( 'hours', 'wp-slimstat' ), 'int' ),
|
81 |
-
'interval_minutes' => array( __( 'minutes', 'wp-slimstat' ), 'int' ),
|
82 |
-
'dt' => array( __( 'Unix Timestamp', 'wp-slimstat' ), 'int' ),
|
83 |
-
|
84 |
-
// Other columns
|
85 |
-
'language_calculated' => array( __( 'Language', 'wp-slimstat' ), 'varchar' ),
|
86 |
-
'platform_calculated' => array( __( 'Operating System', 'wp-slimstat' ), 'varchar' ),
|
87 |
-
'resource_calculated' => array( __( 'Permalink', 'wp-slimstat' ), 'varchar' ),
|
88 |
-
'metric' => array( __( 'Metric', 'wp-slimstat' ), 'varchar' ),
|
89 |
-
'value' => array( __( 'Value', 'wp-slimstat' ), 'varchar' ),
|
90 |
-
'tooltip' => array( __( 'Notes', 'wp-slimstat' ), 'varchar' ),
|
91 |
-
'details' => array( __( 'Notes', 'wp-slimstat' ), 'varchar' ),
|
92 |
-
|
93 |
-
// Events
|
94 |
-
'event_id' => array( __( 'Event ID', 'wp-slimstat' ), 'int' ),
|
95 |
-
'type' => array( __( 'Type', 'wp-slimstat' ), 'int' ),
|
96 |
-
'event_description' => array( __( 'Event Description', 'wp-slimstat' ), 'varchar' ),
|
97 |
-
'position' => array( __( 'Event Coordinates', 'wp-slimstat' ), 'int' ),
|
98 |
-
|
99 |
-
'direction' => array( __( 'Direction', 'wp-slimstat' ), 'varchar' ),
|
100 |
-
'limit_results' => array( __( 'Max Results', 'wp-slimstat' ), 'int' ),
|
101 |
-
'start_from' => array( __( 'Offset', 'wp-slimstat' ), 'int' ),
|
102 |
-
|
103 |
-
// Misc Filters
|
104 |
-
'strtotime' => array( 0, 'int' )
|
105 |
-
), self::$columns_names );
|
106 |
-
|
107 |
-
// Allow third party plugins to add even more column names to the array
|
108 |
-
self::$all_columns_names = apply_filters( 'slimstat_column_names', self::$all_columns_names );
|
109 |
-
|
110 |
-
// Hook for the... filters
|
111 |
-
$_filters = apply_filters( 'slimstat_db_pre_filters', $_filters );
|
112 |
-
|
113 |
-
// Normalize the input (filters)
|
114 |
-
self::$filters_normalized = self::parse_filters( $_filters );
|
115 |
-
|
116 |
-
// Hook for the array of normalized filters
|
117 |
-
self::$filters_normalized = apply_filters( 'slimstat_db_filters_normalized', self::$filters_normalized, $_filters );
|
118 |
-
}
|
119 |
-
// end init
|
120 |
-
|
121 |
-
/**
|
122 |
-
* Builds the array of WHERE clauses to be used later in our SQL queries
|
123 |
-
*/
|
124 |
-
protected static function _get_sql_where( $_filters_normalized = array(), $_slim_stats_table_alias = '' ) {
|
125 |
-
$sql_array = array();
|
126 |
-
|
127 |
-
foreach ( $_filters_normalized as $a_filter_column => $a_filter_data ) {
|
128 |
-
// Add-ons can set their own custom filters, which are ignored here
|
129 |
-
if ( strpos( $a_filter_column, 'addon_' ) !== false ) {
|
130 |
-
continue;
|
131 |
-
}
|
132 |
-
|
133 |
-
$sql_array[] = self::get_single_where_clause( $a_filter_column, $a_filter_data[ 0 ], $a_filter_data[ 1 ], $_slim_stats_table_alias );
|
134 |
-
}
|
135 |
-
|
136 |
-
// Flatten array
|
137 |
-
if ( !empty( $sql_array ) ) {
|
138 |
-
return implode( ' AND ', $sql_array );
|
139 |
-
}
|
140 |
-
|
141 |
-
return '';
|
142 |
-
}
|
143 |
-
|
144 |
-
public static function get_combined_where( $_where = '', $_column = '*', $_use_date_filters = true, $_slim_stats_table_alias = '' ) {
|
145 |
-
$dt_with_alias = 'dt';
|
146 |
-
if ( !empty( $_slim_stats_table_alias ) ) {
|
147 |
-
$dt_with_alias = $_slim_stats_table_alias . '.' . $dt_with_alias;
|
148 |
-
}
|
149 |
-
|
150 |
-
$time_range_condition = '';
|
151 |
-
if ( empty( $_where ) ) {
|
152 |
-
if ( !empty( self::$filters_normalized[ 'columns' ] ) ) {
|
153 |
-
$_where = self::_get_sql_where( self::$filters_normalized[ 'columns' ], $_slim_stats_table_alias );
|
154 |
-
|
155 |
-
if ($_use_date_filters) {
|
156 |
-
$time_range_condition = "$dt_with_alias BETWEEN " . self::$filters_normalized[ 'utime' ][ 'start' ] . ' AND ' . self::$filters_normalized[ 'utime' ][ 'end' ];
|
157 |
-
}
|
158 |
-
|
159 |
-
}
|
160 |
-
elseif ( $_use_date_filters ) {
|
161 |
-
$time_range_condition = "$dt_with_alias BETWEEN " . self::$filters_normalized[ 'utime' ][ 'start' ] . ' AND ' . self::$filters_normalized[ 'utime' ][ 'end' ];
|
162 |
-
}
|
163 |
-
else {
|
164 |
-
$_where = '1=1';
|
165 |
-
}
|
166 |
-
}
|
167 |
-
else {
|
168 |
-
if ( $_where != '1=1' && !empty( self::$filters_normalized[ 'columns' ] ) ) {
|
169 |
-
$new_clause = self::_get_sql_where( self::$filters_normalized[ 'columns' ], $_slim_stats_table_alias );
|
170 |
-
|
171 |
-
// This condition could be empty if it's related to a custom column
|
172 |
-
if ( !empty( $new_clause ) ) {
|
173 |
-
$_where .= ' AND ' . $new_clause;
|
174 |
-
}
|
175 |
-
}
|
176 |
-
if ( $_use_date_filters ) {
|
177 |
-
$time_range_condition = "$dt_with_alias BETWEEN " . self::$filters_normalized[ 'utime' ][ 'start' ] . ' AND ' . self::$filters_normalized[ 'utime' ][ 'end' ];
|
178 |
-
}
|
179 |
-
}
|
180 |
-
|
181 |
-
if ( !empty( $_where ) && !empty( $time_range_condition ) ) {
|
182 |
-
$_where = "$_where AND $time_range_condition";
|
183 |
-
}
|
184 |
-
else {
|
185 |
-
$_where = trim( "$_where $time_range_condition" );
|
186 |
-
}
|
187 |
-
|
188 |
-
if ( !empty( $_column ) && !empty( self::$columns_names[ $_column ] ) ) {
|
189 |
-
$_column = str_replace( '_calculated', '', $_column );
|
190 |
-
$column_with_alias = $_column;
|
191 |
-
if ( !empty( $_slim_stats_table_alias ) ) {
|
192 |
-
$column_with_alias = $_slim_stats_table_alias . '.' . $column_with_alias;
|
193 |
-
}
|
194 |
-
|
195 |
-
$filter_empty = "$column_with_alias " . ( ( self::$columns_names[ $_column ] [ 1 ] == 'varchar' ) ? 'IS NULL' : '= 0' );
|
196 |
-
$filter_not_empty = "$column_with_alias " . ( ( self::$columns_names[ $_column ] [ 1 ] == 'varchar' ) ? 'IS NOT NULL' : '<> 0' );
|
197 |
-
|
198 |
-
if ( strpos( $_where, $filter_empty ) === false && strpos( $_where, $filter_not_empty) === false) {
|
199 |
-
$_where = "$filter_not_empty AND $_where";
|
200 |
-
}
|
201 |
-
}
|
202 |
-
|
203 |
-
return $_where;
|
204 |
-
}
|
205 |
-
|
206 |
-
/**
|
207 |
-
* Translates user-friendly operators into SQL conditions
|
208 |
-
*/
|
209 |
-
public static function get_single_where_clause( $_column = 'id', $_operator = 'equals', $_value = '', $_slim_stats_table_alias = '' ) {
|
210 |
-
$filter_empty = ( !empty( self::$columns_names[ $_column ] ) && self::$columns_names[ $_column ] [ 1 ] == 'varchar' ) ? 'IS NULL' : '= 0';
|
211 |
-
$filter_not_empty = ( !empty( self::$columns_names[ $_column ] ) && self::$columns_names[ $_column ] [ 1 ] == 'varchar' ) ? 'IS NOT NULL' : '<> 0';
|
212 |
-
|
213 |
-
$_column = str_replace( '_calculated', '', $_column );
|
214 |
-
|
215 |
-
$column_with_alias = $_column;
|
216 |
-
if ( !empty( $_slim_stats_table_alias ) ) {
|
217 |
-
$column_with_alias = $_slim_stats_table_alias . '.' . $_column;
|
218 |
-
}
|
219 |
-
|
220 |
-
switch( $_column ) {
|
221 |
-
case 'ip':
|
222 |
-
case 'other_ip':
|
223 |
-
$filter_empty = '= "0.0.0.0"';
|
224 |
-
break;
|
225 |
-
default:
|
226 |
-
break;
|
227 |
-
}
|
228 |
-
|
229 |
-
$where = array( '', $_value );
|
230 |
-
switch ( $_operator ) {
|
231 |
-
case 'is_not_equal_to':
|
232 |
-
$where[0] = "$column_with_alias <> %s";
|
233 |
-
break;
|
234 |
-
|
235 |
-
case 'contains':
|
236 |
-
$where = array( "$column_with_alias LIKE %s", '%'.$_value.'%' );
|
237 |
-
break;
|
238 |
-
|
239 |
-
case 'includes_in_set':
|
240 |
-
$where[0] = "FIND_IN_SET(%s, $column_with_alias) > 0";
|
241 |
-
break;
|
242 |
-
|
243 |
-
case 'does_not_contain':
|
244 |
-
$where = array( "$column_with_alias NOT LIKE %s", '%'.$_value.'%' );
|
245 |
-
break;
|
246 |
-
|
247 |
-
case 'starts_with':
|
248 |
-
$where = array( "$column_with_alias LIKE %s", $_value.'%' );
|
249 |
-
break;
|
250 |
-
|
251 |
-
case 'ends_with':
|
252 |
-
$where = array( "$column_with_alias LIKE %s", '%'.$_value );
|
253 |
-
break;
|
254 |
-
|
255 |
-
case 'sounds_like':
|
256 |
-
$where[0] = "SOUNDEX($column_with_alias) = SOUNDEX(%s)";
|
257 |
-
break;
|
258 |
-
|
259 |
-
case 'is_empty':
|
260 |
-
$where = array( "$column_with_alias $filter_empty", '' );
|
261 |
-
break;
|
262 |
-
|
263 |
-
case 'is_not_empty':
|
264 |
-
$where = array( "$column_with_alias $filter_not_empty", '' );
|
265 |
-
break;
|
266 |
-
|
267 |
-
case 'is_greater_than':
|
268 |
-
$where[0] = "$column_with_alias > %d";
|
269 |
-
break;
|
270 |
-
|
271 |
-
case 'is_less_than':
|
272 |
-
$where[0] = "$column_with_alias < %d";
|
273 |
-
break;
|
274 |
-
|
275 |
-
case 'between':
|
276 |
-
$range = explode(',', $_value);
|
277 |
-
$where = array( "$column_with_alias BETWEEN %d AND %d", array( $range[0], $range[1] ) );
|
278 |
-
break;
|
279 |
-
|
280 |
-
case 'matches':
|
281 |
-
$where[0] = "$column_with_alias REGEXP %s";
|
282 |
-
break;
|
283 |
-
|
284 |
-
case 'does_not_match':
|
285 |
-
$where[0] = "$column_with_alias NOT REGEXP %s";
|
286 |
-
break;
|
287 |
-
|
288 |
-
default:
|
289 |
-
$where[0] = "$column_with_alias = %s";
|
290 |
-
break;
|
291 |
-
}
|
292 |
-
|
293 |
-
if ( !empty( $where[ 1 ] ) ) {
|
294 |
-
return $GLOBALS[ 'wpdb' ]->prepare( $where[ 0 ], $where[ 1 ] );
|
295 |
-
}
|
296 |
-
else {
|
297 |
-
return $where[ 0 ];
|
298 |
-
}
|
299 |
-
}
|
300 |
-
|
301 |
-
public static function get_results( $_sql = '', $_select_no_aggregate_values = '', $_order_by = '', $_group_by = '', $_aggregate_values_add = '' ) {
|
302 |
-
$_sql = apply_filters( 'slimstat_get_results_sql', $_sql, $_select_no_aggregate_values, $_order_by, $_group_by, $_aggregate_values_add );
|
303 |
-
|
304 |
-
if ( wp_slimstat::$options[ 'show_sql_debug' ] == 'yes' ) {
|
305 |
-
self::$debug_message .= "<p class='debug'>$_sql</p>";
|
306 |
-
}
|
307 |
-
|
308 |
-
return wp_slimstat::$wpdb->get_results( $_sql, ARRAY_A );
|
309 |
-
}
|
310 |
-
|
311 |
-
public static function get_var( $_sql = '', $_aggregate_value = '' ) {
|
312 |
-
$_sql = apply_filters( 'slimstat_get_var_sql', $_sql, $_aggregate_value );
|
313 |
-
|
314 |
-
if ( wp_slimstat::$options[ 'show_sql_debug' ] == 'yes' ) {
|
315 |
-
self::$debug_message .= "<p class='debug'>$_sql</p>";
|
316 |
-
}
|
317 |
-
|
318 |
-
return wp_slimstat::$wpdb->get_var( $_sql );
|
319 |
-
}
|
320 |
-
|
321 |
-
public static function parse_filters( $_filters = '', $_init_misc = true ) {
|
322 |
-
$filters_normalized = array(
|
323 |
-
'columns' => array(),
|
324 |
-
'date' => array(
|
325 |
-
'interval_direction' => '',
|
326 |
-
'is_past' => false
|
327 |
-
),
|
328 |
-
'misc' => $_init_misc?array(
|
329 |
-
'direction' => 'DESC',
|
330 |
-
'limit_results' => wp_slimstat::$options[ 'limit_results' ],
|
331 |
-
'start_from' => 0
|
332 |
-
) : array(),
|
333 |
-
'utime' => array(
|
334 |
-
'start' => 0,
|
335 |
-
'end' => 0,
|
336 |
-
'type' => 'm'
|
337 |
-
)
|
338 |
-
);
|
339 |
-
|
340 |
-
if ( !empty( $_filters ) ) {
|
341 |
-
$matches = explode( '&&&', $_filters );
|
342 |
-
foreach( $matches as $idx => $a_match ) {
|
343 |
-
preg_match( '/([^\s]+)\s([^\s]+)\s(.+)?/', urldecode( $a_match ), $a_filter );
|
344 |
-
|
345 |
-
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 ) ) {
|
346 |
-
continue;
|
347 |
-
}
|
348 |
-
|
349 |
-
switch( $a_filter[ 1 ] ) {
|
350 |
-
case 'strtotime':
|
351 |
-
$custom_date = strtotime( $a_filter[ 3 ], date_i18n( 'U' ) );
|
352 |
-
|
353 |
-
$filters_normalized[ 'date' ][ 'minute' ] = intval( date( 'i', $custom_date ) );
|
354 |
-
$filters_normalized[ 'date' ][ 'hour' ] = intval( date( 'H', $custom_date ) );
|
355 |
-
$filters_normalized[ 'date' ][ 'day' ] = intval( date( 'j', $custom_date ) );
|
356 |
-
$filters_normalized[ 'date' ][ 'month' ] = intval( date( 'n', $custom_date ) );
|
357 |
-
$filters_normalized[ 'date' ][ 'year' ] = intval( date( 'Y', $custom_date ) );
|
358 |
-
break;
|
359 |
-
|
360 |
-
case 'minute':
|
361 |
-
case 'hour':
|
362 |
-
case 'day':
|
363 |
-
case 'month':
|
364 |
-
case 'year':
|
365 |
-
if ( is_numeric( $a_filter[ 3 ] ) ) {
|
366 |
-
$filters_normalized[ 'date' ][ $a_filter[ 1 ] ] = intval( $a_filter[ 3 ] );
|
367 |
-
}
|
368 |
-
else{
|
369 |
-
// Try to apply strtotime to value
|
370 |
-
switch( $a_filter[ 1 ] ) {
|
371 |
-
case 'minute':
|
372 |
-
$filters_normalized[ 'date' ][ 'minute' ] = intval( date( 'i', strtotime( $a_filter[ 3 ], date_i18n( 'U' ) ) ) );
|
373 |
-
$filters_normalized[ 'date' ][ 'is_past' ] = true;
|
374 |
-
break;
|
375 |
-
|
376 |
-
case 'hour':
|
377 |
-
$filters_normalized[ 'date' ][ 'hour' ] = intval( date( 'H', strtotime( $a_filter[ 3 ], date_i18n( 'U' ) ) ) );
|
378 |
-
$filters_normalized[ 'date' ][ 'is_past' ] = true;
|
379 |
-
break;
|
380 |
-
|
381 |
-
case 'day':
|
382 |
-
$filters_normalized[ 'date' ][ 'day' ] = intval( date( 'j', strtotime( $a_filter[ 3 ], date_i18n( 'U' ) ) ) );
|
383 |
-
break;
|
384 |
-
|
385 |
-
case 'month':
|
386 |
-
$filters_normalized[ 'date' ][ 'month' ] = intval( date( 'n', strtotime( $a_filter[ 3 ], date_i18n( 'U' ) ) ) );
|
387 |
-
break;
|
388 |
-
|
389 |
-
case 'year':
|
390 |
-
$filters_normalized[ 'date' ][ 'year' ] = intval( date( 'Y', strtotime( $a_filter[ 3 ], date_i18n( 'U' ) ) ) );
|
391 |
-
break;
|
392 |
-
|
393 |
-
default:
|
394 |
-
break;
|
395 |
-
}
|
396 |
-
|
397 |
-
if ( $filters_normalized[ 'date' ][ $a_filter[ 1 ] ] === false ) {
|
398 |
-
unset( $filters_normalized[ 'date' ][ $a_filter[ 1 ] ] );
|
399 |
-
}
|
400 |
-
}
|
401 |
-
|
402 |
-
switch( $a_filter[ 1 ] ) {
|
403 |
-
case 'day':
|
404 |
-
if ( $filters_normalized[ 'date' ][ 'day' ] != date_i18n( 'j' ) ) {
|
405 |
-
$filters_normalized[ 'date' ][ 'is_past' ] = true;
|
406 |
-
}
|
407 |
-
break;
|
408 |
-
|
409 |
-
case 'month':
|
410 |
-
if ( $filters_normalized[ 'date' ][ 'month' ] != date_i18n( 'n' ) ) {
|
411 |
-
$filters_normalized[ 'date' ][ 'is_past' ] = true;
|
412 |
-
}
|
413 |
-
break;
|
414 |
-
|
415 |
-
case 'year':
|
416 |
-
if ( $filters_normalized[ 'date' ][ 'year' ] != date_i18n( 'Y' ) ) {
|
417 |
-
$filters_normalized[ 'date' ][ 'is_past' ] = true;
|
418 |
-
}
|
419 |
-
break;
|
420 |
-
|
421 |
-
default:
|
422 |
-
break;
|
423 |
-
}
|
424 |
-
break;
|
425 |
-
|
426 |
-
case 'interval':
|
427 |
-
case 'interval_hours':
|
428 |
-
case 'interval_minutes':
|
429 |
-
$intval_filter = intval( $a_filter[ 3 ] );
|
430 |
-
$filters_normalized[ 'date' ][ $a_filter[ 1 ] ] = abs( $intval_filter );
|
431 |
-
if ( $intval_filter < 0 ) {
|
432 |
-
$filters_normalized[ 'date' ][ 'interval_direction' ] = 'minus';
|
433 |
-
}
|
434 |
-
break;
|
435 |
-
|
436 |
-
case 'interval_direction':
|
437 |
-
$filters_normalized[ 'date' ][ $a_filter[ 1 ] ] = in_array( $a_filter[ 3 ], array( 'plus', 'minus' ) ) ? $a_filter[ 3 ] : 'plus';
|
438 |
-
break;
|
439 |
-
|
440 |
-
case 'direction':
|
441 |
-
case 'limit_results':
|
442 |
-
case 'start_from':
|
443 |
-
$filters_normalized[ 'misc' ][ $a_filter[ 1 ] ] = str_replace( '\\', '', htmlspecialchars_decode( $a_filter[ 3 ] ) );
|
444 |
-
break;
|
445 |
-
|
446 |
-
default:
|
447 |
-
$filters_normalized[ 'columns' ][ $a_filter[ 1 ] ] = array( $a_filter[ 2 ], isset( $a_filter[ 3 ] ) ? str_replace( '\\', '', htmlspecialchars_decode( $a_filter[ 3 ] ) ) : '' );
|
448 |
-
break;
|
449 |
-
}
|
450 |
-
}
|
451 |
-
}
|
452 |
-
|
453 |
-
// Temporarily disable any filters on date_i18n
|
454 |
-
$date_i18n_filters = array();
|
455 |
-
if ( !empty( $GLOBALS[ 'wp_filter' ][ 'date_i18n' ] ) ) {
|
456 |
-
$date_i18n_filters = $GLOBALS[ 'wp_filter' ][ 'date_i18n' ];
|
457 |
-
remove_all_filters( 'date_i18n' );
|
458 |
-
}
|
459 |
-
|
460 |
-
// Let's calculate our time range, based on date filters
|
461 |
-
if ( empty( $filters_normalized[ 'date' ][ 'interval' ] ) && empty( $filters_normalized[ 'date' ][ 'interval_hours' ] ) && empty( $filters_normalized[ 'date' ][ 'interval_minutes' ] ) ) {
|
462 |
-
if ( !empty( $filters_normalized[ 'date' ][ 'minute' ] ) ) {
|
463 |
-
$filters_normalized[ 'utime' ][ 'start' ] = mktime(
|
464 |
-
!empty( $filters_normalized[ 'date' ][ 'hour' ] )?$filters_normalized[ 'date' ][ 'hour' ]:0,
|
465 |
-
$filters_normalized[ 'date' ][ 'minute' ],
|
466 |
-
0,
|
467 |
-
!empty( $filters_normalized[ 'date' ][ 'month' ] )?$filters_normalized[ 'date' ][ 'month' ]:date_i18n( 'n' ),
|
468 |
-
!empty( $filters_normalized[ 'date' ][ 'day' ] )?$filters_normalized[ 'date' ][ 'day' ]:date_i18n( 'j' ),
|
469 |
-
!empty( $filters_normalized[ 'date' ][ 'year' ] )?$filters_normalized[ 'date' ][ 'year' ]:date_i18n( 'Y' )
|
470 |
-
);
|
471 |
-
$filters_normalized[ 'utime' ][ 'end' ] = $filters_normalized[ 'utime' ][ 'start' ] + 60;
|
472 |
-
$filters_normalized[ 'utime' ][ 'type' ] = 'H';
|
473 |
-
}
|
474 |
-
else if ( !empty( $filters_normalized[ 'date' ][ 'hour' ] ) ) {
|
475 |
-
$filters_normalized[ 'utime' ][ 'start' ] = mktime(
|
476 |
-
$filters_normalized[ 'date' ][ 'hour' ],
|
477 |
-
0,
|
478 |
-
0,
|
479 |
-
!empty( $filters_normalized[ 'date' ][ 'month' ] )?$filters_normalized[ 'date' ][ 'month' ]:date_i18n( 'n' ),
|
480 |
-
!empty( $filters_normalized[ 'date' ][ 'day' ] )?$filters_normalized[ 'date' ][ 'day' ]:date_i18n( 'j' ),
|
481 |
-
!empty( $filters_normalized[ 'date' ][ 'year' ] )?$filters_normalized[ 'date' ][ 'year' ]:date_i18n( 'Y' )
|
482 |
-
);
|
483 |
-
$filters_normalized[ 'utime' ][ 'end' ] = $filters_normalized[ 'utime' ][ 'start' ] + 3599;
|
484 |
-
$filters_normalized[ 'utime' ][ 'type' ] = 'H';
|
485 |
-
}
|
486 |
-
else if ( !empty( $filters_normalized[ 'date' ][ 'day' ] ) ) {
|
487 |
-
$filters_normalized[ 'utime' ][ 'start' ] = mktime(
|
488 |
-
0,
|
489 |
-
0,
|
490 |
-
0,
|
491 |
-
!empty( $filters_normalized[ 'date' ][ 'month' ] )?$filters_normalized[ 'date' ][ 'month' ]:date_i18n( 'n' ),
|
492 |
-
$filters_normalized[ 'date' ][ 'day' ],
|
493 |
-
!empty( $filters_normalized[ 'date' ][ 'year' ] )?$filters_normalized[ 'date' ][ 'year' ]:date_i18n( 'Y' )
|
494 |
-
);
|
495 |
-
$filters_normalized[ 'utime' ][ 'end' ] = $filters_normalized[ 'utime' ][ 'start' ] + 86399;
|
496 |
-
$filters_normalized[ 'utime' ][ 'type' ] = 'd';
|
497 |
-
}
|
498 |
-
else if( !empty( $filters_normalized[ 'date' ][ 'year' ] ) && empty( $filters_normalized[ 'date' ][ 'month' ] ) ) {
|
499 |
-
$filters_normalized[ 'utime' ][ 'start' ] = mktime( 0, 0, 0, 1, 1, $filters_normalized[ 'date' ][ 'year' ] );
|
500 |
-
$filters_normalized[ 'utime' ][ 'end' ] = mktime( 0, 0, 0, 1, 1, $filters_normalized[ 'date' ][ 'year' ]+1 )-1;
|
501 |
-
$filters_normalized[ 'utime' ][ 'type' ] = 'Y';
|
502 |
-
}
|
503 |
-
else {
|
504 |
-
$filters_normalized[ 'utime' ][ 'start' ] = mktime(
|
505 |
-
0,
|
506 |
-
0,
|
507 |
-
0,
|
508 |
-
!empty( $filters_normalized[ 'date' ][ 'month' ] )?$filters_normalized[ 'date' ][ 'month' ]:date_i18n( 'n' ),
|
509 |
-
1,
|
510 |
-
!empty( $filters_normalized[ 'date' ][ 'year' ] )?$filters_normalized[ 'date' ][ 'year' ]:date_i18n( 'Y' )
|
511 |
-
);
|
512 |
-
|
513 |
-
$filters_normalized[ 'utime' ][ 'end' ] = strtotime(
|
514 |
-
( !empty( $filters_normalized[ 'date' ][ 'year' ] )?$filters_normalized[ 'date' ][ 'year' ]:date_i18n( 'Y' ) ).'-'.
|
515 |
-
( !empty( $filters_normalized[ 'date' ][ 'month' ] )?$filters_normalized[ 'date' ][ 'month' ]:date_i18n( 'n' ) ).
|
516 |
-
'-01 00:00 +1 month UTC'
|
517 |
-
)-1;
|
518 |
-
$filters_normalized[ 'utime' ][ 'type' ] = 'm';
|
519 |
-
}
|
520 |
-
}
|
521 |
-
else { // An interval was specified
|
522 |
-
$filters_normalized[ 'utime' ][ 'type' ] = 'interval';
|
523 |
-
|
524 |
-
$filters_normalized[ 'utime' ][ 'start' ] = mktime(
|
525 |
-
!empty( $filters_normalized[ 'date' ][ 'hour' ] )?$filters_normalized[ 'date' ][ 'hour' ]:0,
|
526 |
-
!empty( $filters_normalized[ 'date' ][ 'minute' ] )?$filters_normalized[ 'date' ][ 'minute' ]:0,
|
527 |
-
0,
|
528 |
-
!empty( $filters_normalized[ 'date' ][ 'month' ] )?$filters_normalized[ 'date' ][ 'month' ]:date_i18n( 'n' ),
|
529 |
-
!empty( $filters_normalized[ 'date' ][ 'day' ] )?$filters_normalized[ 'date' ][ 'day' ]:date_i18n( 'j' ),
|
530 |
-
!empty( $filters_normalized[ 'date' ][ 'year' ] )?$filters_normalized[ 'date' ][ 'year' ]:date_i18n( 'Y' )
|
531 |
-
);
|
532 |
-
|
533 |
-
$sign = ( $filters_normalized[ 'date' ][ 'interval_direction' ] == 'plus' )?'+':'-';
|
534 |
-
|
535 |
-
$filters_normalized[ 'utime' ][ 'end' ] = $filters_normalized[ 'utime' ][ 'start' ] + intval( $sign.(
|
536 |
-
( !empty( $filters_normalized[ 'date' ][ 'interval' ] )?intval( $filters_normalized[ 'date' ][ 'interval' ] + 1):0 ) * 86400 +
|
537 |
-
( !empty( $filters_normalized[ 'date' ][ 'interval_hours' ] )?intval( $filters_normalized[ 'date' ][ 'interval_hours' ] ):0 ) * 3600 +
|
538 |
-
( !empty( $filters_normalized[ 'date' ][ 'interval_minutes' ] )?intval( $filters_normalized[ 'date' ][ 'interval_minutes' ] ):0 ) * 60
|
539 |
-
) ) - 1;
|
540 |
-
|
541 |
-
// Swap boundaries if we're going back in time
|
542 |
-
if ( $filters_normalized[ 'date' ][ 'interval_direction' ] == 'minus' ) {
|
543 |
-
list( $filters_normalized[ 'utime' ][ 'start' ], $filters_normalized[ 'utime' ][ 'end' ] ) = array( $filters_normalized[ 'utime' ][ 'end' ] + 1, $filters_normalized[ 'utime' ][ 'start' ] - 1 );
|
544 |
-
}
|
545 |
-
}
|
546 |
-
|
547 |
-
// If end is in the future, set it to now
|
548 |
-
if ( $filters_normalized[ 'utime' ][ 'end' ] > date_i18n( 'U' ) ) {
|
549 |
-
$filters_normalized[ 'utime' ][ 'end' ] = date_i18n( 'U' );
|
550 |
-
}
|
551 |
-
|
552 |
-
// If start is after end, set it to first of month
|
553 |
-
if ( $filters_normalized[ 'utime' ][ 'start' ] > $filters_normalized[ 'utime' ][ 'end' ] ) {
|
554 |
-
$filters_normalized[ 'utime' ][ 'start' ] = mktime(
|
555 |
-
0,
|
556 |
-
0,
|
557 |
-
0,
|
558 |
-
date_i18n( 'n', $filters_normalized[ 'utime' ][ 'end' ] ),
|
559 |
-
1,
|
560 |
-
date_i18n( 'Y', $filters_normalized[ 'utime' ][ 'end' ] )
|
561 |
-
);
|
562 |
-
$filters_normalized[ 'date' ][ 'hour' ] = $filters_normalized[ 'date' ][ 'day' ] = $filters_normalized[ 'date' ][ 'month' ] = $filters_normalized[ 'date' ][ 'year' ] = 0;
|
563 |
-
}
|
564 |
-
|
565 |
-
// Restore filters on date_i18n
|
566 |
-
foreach ($date_i18n_filters as $i18n_priority => $i18n_func_list) {
|
567 |
-
foreach ($i18n_func_list as $func_name => $func_args) {
|
568 |
-
add_filter('date_i8n', $func_args[ 'function' ], $i18n_priority, $func_args[ 'accepted_args' ]);
|
569 |
-
}
|
570 |
-
}
|
571 |
-
|
572 |
-
return $filters_normalized;
|
573 |
-
}
|
574 |
-
|
575 |
-
// The following methods retrieve the information from the database
|
576 |
-
|
577 |
-
public static function count_bouncing_pages() {
|
578 |
-
$where = self::get_combined_where( 'visit_id > 0 AND content_type <> "404"', 'resource' );
|
579 |
-
|
580 |
-
return intval( self::get_var( "
|
581 |
-
SELECT COUNT(*) counthits
|
582 |
-
FROM (
|
583 |
-
SELECT resource, visit_id
|
584 |
-
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
585 |
-
WHERE $where
|
586 |
-
GROUP BY resource
|
587 |
-
HAVING COUNT(visit_id) = 1
|
588 |
-
) as ts1",
|
589 |
-
'SUM(counthits) AS counthits' ) );
|
590 |
-
}
|
591 |
-
|
592 |
-
public static function count_exit_pages() {
|
593 |
-
$where = self::get_combined_where( 'visit_id > 0', 'resource' );
|
594 |
-
|
595 |
-
return intval( self::get_var( "
|
596 |
-
SELECT COUNT(*) counthits
|
597 |
-
FROM (
|
598 |
-
SELECT resource, dt
|
599 |
-
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
600 |
-
WHERE $where
|
601 |
-
GROUP BY resource
|
602 |
-
HAVING dt = MAX(dt)
|
603 |
-
) AS ts1",
|
604 |
-
'SUM(counthits) AS counthits' ) );
|
605 |
-
}
|
606 |
-
|
607 |
-
public static function count_records( $_column = 'id', $_where = '', $_use_date_filters = true ) {
|
608 |
-
$distinct_column = ( $_column != 'id' ) ? "DISTINCT $_column" : $_column;
|
609 |
-
$_where = self::get_combined_where( $_where, $_column, $_use_date_filters );
|
610 |
-
|
611 |
-
return intval( self::get_var( "
|
612 |
-
SELECT COUNT($distinct_column) counthits
|
613 |
-
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
614 |
-
WHERE $_where",
|
615 |
-
'SUM(counthits) AS counthits' ) );
|
616 |
-
}
|
617 |
-
|
618 |
-
public static function count_records_having( $_column = 'id', $_where = '', $_having = '' ) {
|
619 |
-
$_where = self::get_combined_where( $_where, $_column );
|
620 |
-
|
621 |
-
return intval( self::get_var( "
|
622 |
-
SELECT COUNT(*) counthits FROM (
|
623 |
-
SELECT $_column
|
624 |
-
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
625 |
-
WHERE $_where
|
626 |
-
GROUP BY $_column
|
627 |
-
HAVING $_having
|
628 |
-
) AS ts1",
|
629 |
-
'SUM(counthits) AS counthits' ) );
|
630 |
-
}
|
631 |
-
|
632 |
-
public static function get_data_for_chart( $_data1 = '', $_data2 = '', $_where = '' ) {
|
633 |
-
$previous = array( 'end' => self::$filters_normalized[ 'utime' ][ 'start' ] - 1 );
|
634 |
-
$label_date_format = '';
|
635 |
-
$output = array();
|
636 |
-
|
637 |
-
// Each type has its own parameters
|
638 |
-
switch (self::$filters_normalized[ 'utime' ][ 'type' ]) {
|
639 |
-
case 'H':
|
640 |
-
$previous[ 'start' ] = self::$filters_normalized[ 'utime' ][ 'start' ] - 3600;
|
641 |
-
$label_date_format = wp_slimstat::$options[ 'time_format' ];
|
642 |
-
$group_by = array( 'HOUR', 'MINUTE', 'i' );
|
643 |
-
$values_in_interval = array( 59, 59, 0, 60 );
|
644 |
-
break;
|
645 |
-
|
646 |
-
case 'd':
|
647 |
-
$previous[ 'start' ] = self::$filters_normalized[ 'utime' ][ 'start' ] - 86400;
|
648 |
-
$label_date_format = ( self::$formats[ 'decimal' ] == '.' ) ? 'm/d' : 'd/m';
|
649 |
-
$group_by = array( 'DAY', 'HOUR', 'G' );
|
650 |
-
$values_in_interval = array( 23, 23, 0, 3600 );
|
651 |
-
break;
|
652 |
-
|
653 |
-
case 'Y':
|
654 |
-
$previous[ 'start' ] = mktime( 0, 0, 0, 1, 1, self::$filters_normalized[ 'date' ][ 'year' ] - 1 );
|
655 |
-
$label_date_format = 'Y';
|
656 |
-
$group_by = array( 'YEAR', 'MONTH', 'n' );
|
657 |
-
$values_in_interval = array( 12, 12, 1, 2678400 );
|
658 |
-
break;
|
659 |
-
|
660 |
-
case 'interval':
|
661 |
-
$group_by = array( 'MONTH', 'DAY', 'j' );
|
662 |
-
$values_in_interval = array( abs( self::$filters_normalized[ 'date' ][ 'interval' ] ), abs( self::$filters_normalized[ 'date' ][ 'interval' ] ), 0, 86400 );
|
663 |
-
break;
|
664 |
-
|
665 |
-
default:
|
666 |
-
$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' ) );
|
667 |
-
$label_date_format = 'm/Y';
|
668 |
-
$group_by = array( 'MONTH', 'DAY', 'j' );
|
669 |
-
$values_in_interval = array( date( 't', $previous[ 'start' ] ), date( 't', self::$filters_normalized[ 'utime' ][ 'start' ] ), 1, 86400 );
|
670 |
-
break;
|
671 |
-
}
|
672 |
-
|
673 |
-
// Custom intervals don't have a comparison chart ('previous' range)
|
674 |
-
if ( empty( self::$filters_normalized[ 'date' ][ 'interval' ] ) ) {
|
675 |
-
$_where = self::get_combined_where( $_where, '*', false );
|
676 |
-
$previous_time_range = ' AND (dt BETWEEN '.$previous[ 'start' ].' AND '.$previous[ 'end' ].' OR dt BETWEEN '.self::$filters_normalized[ 'utime' ][ 'start' ].' AND '.self::$filters_normalized[ 'utime' ][ 'end' ].')';
|
677 |
-
}
|
678 |
-
else {
|
679 |
-
$_where = self::get_combined_where( $_where );
|
680 |
-
$previous_time_range = '';
|
681 |
-
}
|
682 |
-
|
683 |
-
// Build the SQL query
|
684 |
-
$group_by_string = "GROUP BY {$group_by[0]}(CONVERT_TZ(FROM_UNIXTIME(dt), @@session.time_zone, '+00:00')), {$group_by[1]}(CONVERT_TZ(FROM_UNIXTIME(dt), @@session.time_zone, '+00:00'))";
|
685 |
-
$sql = "
|
686 |
-
SELECT dt, $_data1 first_metric, $_data2 second_metric
|
687 |
-
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
688 |
-
WHERE $_where $previous_time_range
|
689 |
-
$group_by_string";
|
690 |
-
|
691 |
-
// Get the data
|
692 |
-
$results = self::get_results( $sql, 'blog_id', '', $group_by_string, 'SUM(first_metric) AS first_metric, SUM(second_metric) AS second_metric' );
|
693 |
-
|
694 |
-
// Fill the output array
|
695 |
-
$output[ 'current' ][ 'label' ] = '';
|
696 |
-
if ( !empty( $label_date_format ) ) {
|
697 |
-
$output[ 'current' ][ 'label' ] = gmdate( $label_date_format, self::$filters_normalized[ 'utime' ][ 'start' ] );
|
698 |
-
$output[ 'previous' ][ 'label' ] = gmdate( $label_date_format, $previous[ 'start' ] );
|
699 |
-
}
|
700 |
-
|
701 |
-
$output[ 'previous' ][ 'first_metric' ] = array_fill( $values_in_interval[ 2 ], $values_in_interval[ 0 ], 0 );
|
702 |
-
$output['previous']['second_metric'] = array_fill( $values_in_interval[ 2 ], $values_in_interval[ 0 ], 0 );
|
703 |
-
|
704 |
-
$today_limit = floatval( date_i18n( 'Ymd.Hi' ) );
|
705 |
-
for ( $i = $values_in_interval[ 2 ]; $i <= $values_in_interval[ 1 ]; $i++ ){
|
706 |
-
// Do not include dates in the future
|
707 |
-
if ( floatval( date( 'Ymd.Hi', wp_slimstat_db::$filters_normalized[ 'utime' ][ 'start' ] + ( ( $i - $values_in_interval[ 2 ]) * $values_in_interval[ 3 ] ) ) ) > $today_limit ) {
|
708 |
-
continue;
|
709 |
-
}
|
710 |
-
|
711 |
-
$output[ 'current' ][ 'first_metric' ][ $i ] = 0;
|
712 |
-
$output[ 'current' ][ 'second_metric' ][ $i ] = 0;
|
713 |
-
}
|
714 |
-
|
715 |
-
// No data? No problem!
|
716 |
-
if ( !is_array( $results ) || empty( $results ) ) {
|
717 |
-
return $output;
|
718 |
-
}
|
719 |
-
|
720 |
-
// Rearrange the data and then format it for Flot
|
721 |
-
foreach ($results as $i => $a_result ) {
|
722 |
-
$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' ] );
|
723 |
-
|
724 |
-
if ( empty( self::$filters_normalized[ 'date' ][ 'interval' ] ) && gmdate( self::$filters_normalized[ 'utime' ][ 'type' ], $a_result[ 'dt' ] ) == gmdate( self::$filters_normalized[ 'utime' ][ 'type' ], $previous[ 'start' ] ) ){
|
725 |
-
$output[ 'previous' ][ 'first_metric' ][ $index ] = $a_result[ 'first_metric' ];
|
726 |
-
$output[ 'previous' ][ 'second_metric' ][ $index ] = $a_result[ 'second_metric' ];
|
727 |
-
}
|
728 |
-
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' ] ) ){
|
729 |
-
$output[ 'current' ][ 'first_metric' ][ $index ] = $a_result[ 'first_metric' ];
|
730 |
-
$output[ 'current' ][ 'second_metric' ][ $index ] = $a_result[ 'second_metric' ];
|
731 |
-
}
|
732 |
-
}
|
733 |
-
|
734 |
-
return $output;
|
735 |
-
}
|
736 |
-
|
737 |
-
public static function get_data_size() {
|
738 |
-
$suffix = 'KB';
|
739 |
-
|
740 |
-
$sql = 'SHOW TABLE STATUS LIKE "'.$GLOBALS[ 'wpdb' ]->prefix.'slim_stats"';
|
741 |
-
$table_details = wp_slimstat::$wpdb->get_row( $sql, 'ARRAY_A', 0 );
|
742 |
-
|
743 |
-
$table_size = ( $table_details[ 'Data_length' ] / 1024 ) + ( $table_details[ 'Index_length' ] / 1024 );
|
744 |
-
|
745 |
-
if ( $table_size > 1024 ) {
|
746 |
-
$table_size /= 1024;
|
747 |
-
$suffix = 'MB';
|
748 |
-
}
|
749 |
-
return number_format( $table_size, 2, self::$formats[ 'decimal' ], self::$formats[ 'thousand' ] ).' '.$suffix;
|
750 |
-
}
|
751 |
-
|
752 |
-
public static function get_max_and_average_pages_per_visit() {
|
753 |
-
$where = self::get_combined_where( 'visit_id > 0' );
|
754 |
-
|
755 |
-
return self::get_results( "
|
756 |
-
SELECT AVG(ts1.counthits) AS avghits, MAX(ts1.counthits) AS maxhits FROM (
|
757 |
-
SELECT count(ip) counthits, visit_id
|
758 |
-
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
759 |
-
WHERE $where
|
760 |
-
GROUP BY visit_id
|
761 |
-
) AS ts1",
|
762 |
-
'blog_id',
|
763 |
-
'',
|
764 |
-
'',
|
765 |
-
'AVG(avghits) AS avghits, MAX(maxhits) AS maxhits' );
|
766 |
-
}
|
767 |
-
|
768 |
-
public static function get_oldest_visit() {
|
769 |
-
return self::get_var( "
|
770 |
-
SELECT dt
|
771 |
-
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
772 |
-
ORDER BY dt ASC
|
773 |
-
LIMIT 0, 1",
|
774 |
-
'MIN(dt)' );
|
775 |
-
}
|
776 |
-
|
777 |
-
public static function get_recent( $_column = '
|
778 |
-
// This function can be passed individual arguments, or an array of arguments
|
779 |
-
if ( is_array( $_column ) ) {
|
780 |
-
$_where = !empty( $_column[ 'where' ] ) ? $_column[ 'where' ] : '';
|
781 |
-
$_having = !empty( $_column[ 'having' ] ) ? $_column[ 'having' ] : '';
|
782 |
-
$_use_date_filters = !empty( $_column[ 'use_date_filters' ] ) ? $_column[ 'use_date_filters' ] : true;
|
783 |
-
$_as_column = !empty( $_column[ 'as_column' ] ) ? $_column[ 'as_column' ] : '';
|
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 |
-
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
-
|
909 |
-
|
910 |
-
|
911 |
-
|
912 |
-
|
913 |
-
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
)
|
926 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
927 |
}
|
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 $filters_normalized = array();
|
8 |
+
|
9 |
+
// Number and date formats
|
10 |
+
public static $formats = array( 'decimal' => ',', 'thousand' => '.' );
|
11 |
+
|
12 |
+
// Structure that maps filters to SQL information (table names, clauses, lookup tables, etc)
|
13 |
+
public static $sql_where = array( 'columns' => '', 'time_range' => '' );
|
14 |
+
|
15 |
+
// Filters that are not visible in the dropdown
|
16 |
+
public static $all_columns_names = array();
|
17 |
+
|
18 |
+
// Debug message
|
19 |
+
public static $debug_message = '';
|
20 |
+
|
21 |
+
/*
|
22 |
+
* Sets the filters and other structures needed to store the data retrieved from the DB
|
23 |
+
*/
|
24 |
+
public static function init( $_filters = '' ){
|
25 |
+
// Decimal and thousand separators
|
26 |
+
if ( wp_slimstat::$options[ 'use_european_separators' ] == 'no' ){
|
27 |
+
self::$formats[ 'decimal' ] = '.';
|
28 |
+
self::$formats[ 'thousand' ] = ',';
|
29 |
+
}
|
30 |
+
|
31 |
+
// Filters are defined as: browser equals Chrome|country starts_with en
|
32 |
+
if ( !is_string( $_filters ) || empty( $_filters ) ){
|
33 |
+
$_filters = '';
|
34 |
+
}
|
35 |
+
|
36 |
+
// List of supported filters and their friendly names
|
37 |
+
self::$columns_names = array(
|
38 |
+
'no_filter_selected_1' => array( ' ', 'none' ),
|
39 |
+
'browser' => array( __( 'Browser', 'wp-slimstat' ), 'varchar' ),
|
40 |
+
'country' => array( __( 'Country Code', 'wp-slimstat' ), 'varchar' ),
|
41 |
+
'ip' => array( __( 'IP Address', 'wp-slimstat' ), 'varchar' ),
|
42 |
+
'searchterms' => array( __( 'Search Terms', 'wp-slimstat' ), 'varchar' ),
|
43 |
+
'language' => array( __( 'Language Code', 'wp-slimstat' ), 'varchar' ),
|
44 |
+
'platform' => array( __( 'Operating System', 'wp-slimstat' ), 'varchar' ),
|
45 |
+
'resource' => array( __( 'Permalink', 'wp-slimstat' ), 'varchar' ),
|
46 |
+
'referer' => array( __( 'Referer', 'wp-slimstat' ), 'varchar' ),
|
47 |
+
'username' => array( __( 'Visitor\'s Name', 'wp-slimstat' ), 'varchar' ),
|
48 |
+
'outbound_resource' => array( __( 'Outbound Link', 'wp-slimstat' ), 'varchar' ),
|
49 |
+
'page_performance' => array( __( 'Page Speed', 'wp-slimstat' ), 'int' ),
|
50 |
+
'no_filter_selected_2' => array( ' ', 'none' ),
|
51 |
+
'no_filter_selected_3' => array( __( '-- Advanced filters --', 'wp-slimstat' ), 'none' ),
|
52 |
+
'plugins' => array( __( 'Browser Capabilities', 'wp-slimstat' ), 'varchar' ),
|
53 |
+
'browser_version' => array( __( 'Browser Version', 'wp-slimstat' ), 'varchar' ),
|
54 |
+
'browser_type' => array( __( 'Browser Type', 'wp-slimstat' ), 'int' ),
|
55 |
+
'user_agent' => array( __( 'User Agent', 'wp-slimstat' ), 'varchar' ),
|
56 |
+
'notes' => array( __( 'Annotations', 'wp-slimstat' ), 'varchar' ),
|
57 |
+
'server_latency' => array( __( 'Server Latency', 'wp-slimstat' ), 'int' ),
|
58 |
+
'author' => array( __( 'Post Author', 'wp-slimstat' ), 'varchar' ),
|
59 |
+
'category' => array( __( 'Post Category ID', 'wp-slimstat' ), 'varchar' ),
|
60 |
+
'other_ip' => array( __( 'Originating IP', 'wp-slimstat' ), 'varchar' ),
|
61 |
+
'content_type' => array( __( 'Resource Content Type', 'wp-slimstat' ), 'varchar' ),
|
62 |
+
'content_id' => array( __( 'Resource ID', 'wp-slimstat' ), 'int' ),
|
63 |
+
'screen_width' => array( __( 'Screen Width', 'wp-slimstat' ), 'int' ),
|
64 |
+
'screen_height' => array( __( 'Screen Height', 'wp-slimstat' ), 'int' ),
|
65 |
+
'resolution' => array( __( 'Viewport Size', 'wp-slimstat' ), 'varchar' ),
|
66 |
+
'visit_id' => array( __( 'Visit ID', 'wp-slimstat' ), 'int' )
|
67 |
+
);
|
68 |
+
|
69 |
+
// The following filters will not be displayed in the dropdown
|
70 |
+
self::$all_columns_names = array_merge( array(
|
71 |
+
|
72 |
+
// Date and Time
|
73 |
+
'minute' => array( __( 'Minute', 'wp-slimstat' ), 'int' ),
|
74 |
+
'hour' => array( __( 'Hour', 'wp-slimstat' ), 'int' ),
|
75 |
+
'day' => array( __( 'Day', 'wp-slimstat' ), 'int' ),
|
76 |
+
'month' => array( __( 'Month', 'wp-slimstat' ), 'int' ),
|
77 |
+
'year' => array( __( 'Year', 'wp-slimstat' ), 'int' ),
|
78 |
+
'interval_direction' => array( __( '+/-', 'wp-slimstat' ), 'int' ),
|
79 |
+
'interval' => array( __( 'days', 'wp-slimstat' ), 'int' ),
|
80 |
+
'interval_hours' => array( __( 'hours', 'wp-slimstat' ), 'int' ),
|
81 |
+
'interval_minutes' => array( __( 'minutes', 'wp-slimstat' ), 'int' ),
|
82 |
+
'dt' => array( __( 'Unix Timestamp', 'wp-slimstat' ), 'int' ),
|
83 |
+
|
84 |
+
// Other columns
|
85 |
+
'language_calculated' => array( __( 'Language', 'wp-slimstat' ), 'varchar' ),
|
86 |
+
'platform_calculated' => array( __( 'Operating System', 'wp-slimstat' ), 'varchar' ),
|
87 |
+
'resource_calculated' => array( __( 'Permalink', 'wp-slimstat' ), 'varchar' ),
|
88 |
+
'metric' => array( __( 'Metric', 'wp-slimstat' ), 'varchar' ),
|
89 |
+
'value' => array( __( 'Value', 'wp-slimstat' ), 'varchar' ),
|
90 |
+
'tooltip' => array( __( 'Notes', 'wp-slimstat' ), 'varchar' ),
|
91 |
+
'details' => array( __( 'Notes', 'wp-slimstat' ), 'varchar' ),
|
92 |
+
|
93 |
+
// Events
|
94 |
+
'event_id' => array( __( 'Event ID', 'wp-slimstat' ), 'int' ),
|
95 |
+
'type' => array( __( 'Type', 'wp-slimstat' ), 'int' ),
|
96 |
+
'event_description' => array( __( 'Event Description', 'wp-slimstat' ), 'varchar' ),
|
97 |
+
'position' => array( __( 'Event Coordinates', 'wp-slimstat' ), 'int' ),
|
98 |
+
|
99 |
+
'direction' => array( __( 'Direction', 'wp-slimstat' ), 'varchar' ),
|
100 |
+
'limit_results' => array( __( 'Max Results', 'wp-slimstat' ), 'int' ),
|
101 |
+
'start_from' => array( __( 'Offset', 'wp-slimstat' ), 'int' ),
|
102 |
+
|
103 |
+
// Misc Filters
|
104 |
+
'strtotime' => array( 0, 'int' )
|
105 |
+
), self::$columns_names );
|
106 |
+
|
107 |
+
// Allow third party plugins to add even more column names to the array
|
108 |
+
self::$all_columns_names = apply_filters( 'slimstat_column_names', self::$all_columns_names );
|
109 |
+
|
110 |
+
// Hook for the... filters
|
111 |
+
$_filters = apply_filters( 'slimstat_db_pre_filters', $_filters );
|
112 |
+
|
113 |
+
// Normalize the input (filters)
|
114 |
+
self::$filters_normalized = self::parse_filters( $_filters );
|
115 |
+
|
116 |
+
// Hook for the array of normalized filters
|
117 |
+
self::$filters_normalized = apply_filters( 'slimstat_db_filters_normalized', self::$filters_normalized, $_filters );
|
118 |
+
}
|
119 |
+
// end init
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Builds the array of WHERE clauses to be used later in our SQL queries
|
123 |
+
*/
|
124 |
+
protected static function _get_sql_where( $_filters_normalized = array(), $_slim_stats_table_alias = '' ) {
|
125 |
+
$sql_array = array();
|
126 |
+
|
127 |
+
foreach ( $_filters_normalized as $a_filter_column => $a_filter_data ) {
|
128 |
+
// Add-ons can set their own custom filters, which are ignored here
|
129 |
+
if ( strpos( $a_filter_column, 'addon_' ) !== false ) {
|
130 |
+
continue;
|
131 |
+
}
|
132 |
+
|
133 |
+
$sql_array[] = self::get_single_where_clause( $a_filter_column, $a_filter_data[ 0 ], $a_filter_data[ 1 ], $_slim_stats_table_alias );
|
134 |
+
}
|
135 |
+
|
136 |
+
// Flatten array
|
137 |
+
if ( !empty( $sql_array ) ) {
|
138 |
+
return implode( ' AND ', $sql_array );
|
139 |
+
}
|
140 |
+
|
141 |
+
return '';
|
142 |
+
}
|
143 |
+
|
144 |
+
public static function get_combined_where( $_where = '', $_column = '*', $_use_date_filters = true, $_slim_stats_table_alias = '' ) {
|
145 |
+
$dt_with_alias = 'dt';
|
146 |
+
if ( !empty( $_slim_stats_table_alias ) ) {
|
147 |
+
$dt_with_alias = $_slim_stats_table_alias . '.' . $dt_with_alias;
|
148 |
+
}
|
149 |
+
|
150 |
+
$time_range_condition = '';
|
151 |
+
if ( empty( $_where ) ) {
|
152 |
+
if ( !empty( self::$filters_normalized[ 'columns' ] ) ) {
|
153 |
+
$_where = self::_get_sql_where( self::$filters_normalized[ 'columns' ], $_slim_stats_table_alias );
|
154 |
+
|
155 |
+
if ($_use_date_filters) {
|
156 |
+
$time_range_condition = "$dt_with_alias BETWEEN " . self::$filters_normalized[ 'utime' ][ 'start' ] . ' AND ' . self::$filters_normalized[ 'utime' ][ 'end' ];
|
157 |
+
}
|
158 |
+
|
159 |
+
}
|
160 |
+
elseif ( $_use_date_filters ) {
|
161 |
+
$time_range_condition = "$dt_with_alias BETWEEN " . self::$filters_normalized[ 'utime' ][ 'start' ] . ' AND ' . self::$filters_normalized[ 'utime' ][ 'end' ];
|
162 |
+
}
|
163 |
+
else {
|
164 |
+
$_where = '1=1';
|
165 |
+
}
|
166 |
+
}
|
167 |
+
else {
|
168 |
+
if ( $_where != '1=1' && !empty( self::$filters_normalized[ 'columns' ] ) ) {
|
169 |
+
$new_clause = self::_get_sql_where( self::$filters_normalized[ 'columns' ], $_slim_stats_table_alias );
|
170 |
+
|
171 |
+
// This condition could be empty if it's related to a custom column
|
172 |
+
if ( !empty( $new_clause ) ) {
|
173 |
+
$_where .= ' AND ' . $new_clause;
|
174 |
+
}
|
175 |
+
}
|
176 |
+
if ( $_use_date_filters ) {
|
177 |
+
$time_range_condition = "$dt_with_alias BETWEEN " . self::$filters_normalized[ 'utime' ][ 'start' ] . ' AND ' . self::$filters_normalized[ 'utime' ][ 'end' ];
|
178 |
+
}
|
179 |
+
}
|
180 |
+
|
181 |
+
if ( !empty( $_where ) && !empty( $time_range_condition ) ) {
|
182 |
+
$_where = "$_where AND $time_range_condition";
|
183 |
+
}
|
184 |
+
else {
|
185 |
+
$_where = trim( "$_where $time_range_condition" );
|
186 |
+
}
|
187 |
+
|
188 |
+
if ( !empty( $_column ) && !empty( self::$columns_names[ $_column ] ) ) {
|
189 |
+
$_column = str_replace( '_calculated', '', $_column );
|
190 |
+
$column_with_alias = $_column;
|
191 |
+
if ( !empty( $_slim_stats_table_alias ) ) {
|
192 |
+
$column_with_alias = $_slim_stats_table_alias . '.' . $column_with_alias;
|
193 |
+
}
|
194 |
+
|
195 |
+
$filter_empty = "$column_with_alias " . ( ( self::$columns_names[ $_column ] [ 1 ] == 'varchar' ) ? 'IS NULL' : '= 0' );
|
196 |
+
$filter_not_empty = "$column_with_alias " . ( ( self::$columns_names[ $_column ] [ 1 ] == 'varchar' ) ? 'IS NOT NULL' : '<> 0' );
|
197 |
+
|
198 |
+
if ( strpos( $_where, $filter_empty ) === false && strpos( $_where, $filter_not_empty) === false) {
|
199 |
+
$_where = "$filter_not_empty AND $_where";
|
200 |
+
}
|
201 |
+
}
|
202 |
+
|
203 |
+
return $_where;
|
204 |
+
}
|
205 |
+
|
206 |
+
/**
|
207 |
+
* Translates user-friendly operators into SQL conditions
|
208 |
+
*/
|
209 |
+
public static function get_single_where_clause( $_column = 'id', $_operator = 'equals', $_value = '', $_slim_stats_table_alias = '' ) {
|
210 |
+
$filter_empty = ( !empty( self::$columns_names[ $_column ] ) && self::$columns_names[ $_column ] [ 1 ] == 'varchar' ) ? 'IS NULL' : '= 0';
|
211 |
+
$filter_not_empty = ( !empty( self::$columns_names[ $_column ] ) && self::$columns_names[ $_column ] [ 1 ] == 'varchar' ) ? 'IS NOT NULL' : '<> 0';
|
212 |
+
|
213 |
+
$_column = str_replace( '_calculated', '', $_column );
|
214 |
+
|
215 |
+
$column_with_alias = $_column;
|
216 |
+
if ( !empty( $_slim_stats_table_alias ) ) {
|
217 |
+
$column_with_alias = $_slim_stats_table_alias . '.' . $_column;
|
218 |
+
}
|
219 |
+
|
220 |
+
switch( $_column ) {
|
221 |
+
case 'ip':
|
222 |
+
case 'other_ip':
|
223 |
+
$filter_empty = '= "0.0.0.0"';
|
224 |
+
break;
|
225 |
+
default:
|
226 |
+
break;
|
227 |
+
}
|
228 |
+
|
229 |
+
$where = array( '', $_value );
|
230 |
+
switch ( $_operator ) {
|
231 |
+
case 'is_not_equal_to':
|
232 |
+
$where[0] = "$column_with_alias <> %s";
|
233 |
+
break;
|
234 |
+
|
235 |
+
case 'contains':
|
236 |
+
$where = array( "$column_with_alias LIKE %s", '%'.$_value.'%' );
|
237 |
+
break;
|
238 |
+
|
239 |
+
case 'includes_in_set':
|
240 |
+
$where[0] = "FIND_IN_SET(%s, $column_with_alias) > 0";
|
241 |
+
break;
|
242 |
+
|
243 |
+
case 'does_not_contain':
|
244 |
+
$where = array( "$column_with_alias NOT LIKE %s", '%'.$_value.'%' );
|
245 |
+
break;
|
246 |
+
|
247 |
+
case 'starts_with':
|
248 |
+
$where = array( "$column_with_alias LIKE %s", $_value.'%' );
|
249 |
+
break;
|
250 |
+
|
251 |
+
case 'ends_with':
|
252 |
+
$where = array( "$column_with_alias LIKE %s", '%'.$_value );
|
253 |
+
break;
|
254 |
+
|
255 |
+
case 'sounds_like':
|
256 |
+
$where[0] = "SOUNDEX($column_with_alias) = SOUNDEX(%s)";
|
257 |
+
break;
|
258 |
+
|
259 |
+
case 'is_empty':
|
260 |
+
$where = array( "$column_with_alias $filter_empty", '' );
|
261 |
+
break;
|
262 |
+
|
263 |
+
case 'is_not_empty':
|
264 |
+
$where = array( "$column_with_alias $filter_not_empty", '' );
|
265 |
+
break;
|
266 |
+
|
267 |
+
case 'is_greater_than':
|
268 |
+
$where[0] = "$column_with_alias > %d";
|
269 |
+
break;
|
270 |
+
|
271 |
+
case 'is_less_than':
|
272 |
+
$where[0] = "$column_with_alias < %d";
|
273 |
+
break;
|
274 |
+
|
275 |
+
case 'between':
|
276 |
+
$range = explode(',', $_value);
|
277 |
+
$where = array( "$column_with_alias BETWEEN %d AND %d", array( $range[0], $range[1] ) );
|
278 |
+
break;
|
279 |
+
|
280 |
+
case 'matches':
|
281 |
+
$where[0] = "$column_with_alias REGEXP %s";
|
282 |
+
break;
|
283 |
+
|
284 |
+
case 'does_not_match':
|
285 |
+
$where[0] = "$column_with_alias NOT REGEXP %s";
|
286 |
+
break;
|
287 |
+
|
288 |
+
default:
|
289 |
+
$where[0] = "$column_with_alias = %s";
|
290 |
+
break;
|
291 |
+
}
|
292 |
+
|
293 |
+
if ( !empty( $where[ 1 ] ) ) {
|
294 |
+
return $GLOBALS[ 'wpdb' ]->prepare( $where[ 0 ], $where[ 1 ] );
|
295 |
+
}
|
296 |
+
else {
|
297 |
+
return $where[ 0 ];
|
298 |
+
}
|
299 |
+
}
|
300 |
+
|
301 |
+
public static function get_results( $_sql = '', $_select_no_aggregate_values = '', $_order_by = '', $_group_by = '', $_aggregate_values_add = '' ) {
|
302 |
+
$_sql = apply_filters( 'slimstat_get_results_sql', $_sql, $_select_no_aggregate_values, $_order_by, $_group_by, $_aggregate_values_add );
|
303 |
+
|
304 |
+
if ( wp_slimstat::$options[ 'show_sql_debug' ] == 'yes' ) {
|
305 |
+
self::$debug_message .= "<p class='debug'>$_sql</p>";
|
306 |
+
}
|
307 |
+
|
308 |
+
return wp_slimstat::$wpdb->get_results( $_sql, ARRAY_A );
|
309 |
+
}
|
310 |
+
|
311 |
+
public static function get_var( $_sql = '', $_aggregate_value = '' ) {
|
312 |
+
$_sql = apply_filters( 'slimstat_get_var_sql', $_sql, $_aggregate_value );
|
313 |
+
|
314 |
+
if ( wp_slimstat::$options[ 'show_sql_debug' ] == 'yes' ) {
|
315 |
+
self::$debug_message .= "<p class='debug'>$_sql</p>";
|
316 |
+
}
|
317 |
+
|
318 |
+
return wp_slimstat::$wpdb->get_var( $_sql );
|
319 |
+
}
|
320 |
+
|
321 |
+
public static function parse_filters( $_filters = '', $_init_misc = true ) {
|
322 |
+
$filters_normalized = array(
|
323 |
+
'columns' => array(),
|
324 |
+
'date' => array(
|
325 |
+
'interval_direction' => '',
|
326 |
+
'is_past' => false
|
327 |
+
),
|
328 |
+
'misc' => $_init_misc?array(
|
329 |
+
'direction' => 'DESC',
|
330 |
+
'limit_results' => wp_slimstat::$options[ 'limit_results' ],
|
331 |
+
'start_from' => 0
|
332 |
+
) : array(),
|
333 |
+
'utime' => array(
|
334 |
+
'start' => 0,
|
335 |
+
'end' => 0,
|
336 |
+
'type' => 'm'
|
337 |
+
)
|
338 |
+
);
|
339 |
+
|
340 |
+
if ( !empty( $_filters ) ) {
|
341 |
+
$matches = explode( '&&&', $_filters );
|
342 |
+
foreach( $matches as $idx => $a_match ) {
|
343 |
+
preg_match( '/([^\s]+)\s([^\s]+)\s(.+)?/', urldecode( $a_match ), $a_filter );
|
344 |
+
|
345 |
+
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 ) ) {
|
346 |
+
continue;
|
347 |
+
}
|
348 |
+
|
349 |
+
switch( $a_filter[ 1 ] ) {
|
350 |
+
case 'strtotime':
|
351 |
+
$custom_date = strtotime( $a_filter[ 3 ], date_i18n( 'U' ) );
|
352 |
+
|
353 |
+
$filters_normalized[ 'date' ][ 'minute' ] = intval( date( 'i', $custom_date ) );
|
354 |
+
$filters_normalized[ 'date' ][ 'hour' ] = intval( date( 'H', $custom_date ) );
|
355 |
+
$filters_normalized[ 'date' ][ 'day' ] = intval( date( 'j', $custom_date ) );
|
356 |
+
$filters_normalized[ 'date' ][ 'month' ] = intval( date( 'n', $custom_date ) );
|
357 |
+
$filters_normalized[ 'date' ][ 'year' ] = intval( date( 'Y', $custom_date ) );
|
358 |
+
break;
|
359 |
+
|
360 |
+
case 'minute':
|
361 |
+
case 'hour':
|
362 |
+
case 'day':
|
363 |
+
case 'month':
|
364 |
+
case 'year':
|
365 |
+
if ( is_numeric( $a_filter[ 3 ] ) ) {
|
366 |
+
$filters_normalized[ 'date' ][ $a_filter[ 1 ] ] = intval( $a_filter[ 3 ] );
|
367 |
+
}
|
368 |
+
else{
|
369 |
+
// Try to apply strtotime to value
|
370 |
+
switch( $a_filter[ 1 ] ) {
|
371 |
+
case 'minute':
|
372 |
+
$filters_normalized[ 'date' ][ 'minute' ] = intval( date( 'i', strtotime( $a_filter[ 3 ], date_i18n( 'U' ) ) ) );
|
373 |
+
$filters_normalized[ 'date' ][ 'is_past' ] = true;
|
374 |
+
break;
|
375 |
+
|
376 |
+
case 'hour':
|
377 |
+
$filters_normalized[ 'date' ][ 'hour' ] = intval( date( 'H', strtotime( $a_filter[ 3 ], date_i18n( 'U' ) ) ) );
|
378 |
+
$filters_normalized[ 'date' ][ 'is_past' ] = true;
|
379 |
+
break;
|
380 |
+
|
381 |
+
case 'day':
|
382 |
+
$filters_normalized[ 'date' ][ 'day' ] = intval( date( 'j', strtotime( $a_filter[ 3 ], date_i18n( 'U' ) ) ) );
|
383 |
+
break;
|
384 |
+
|
385 |
+
case 'month':
|
386 |
+
$filters_normalized[ 'date' ][ 'month' ] = intval( date( 'n', strtotime( $a_filter[ 3 ], date_i18n( 'U' ) ) ) );
|
387 |
+
break;
|
388 |
+
|
389 |
+
case 'year':
|
390 |
+
$filters_normalized[ 'date' ][ 'year' ] = intval( date( 'Y', strtotime( $a_filter[ 3 ], date_i18n( 'U' ) ) ) );
|
391 |
+
break;
|
392 |
+
|
393 |
+
default:
|
394 |
+
break;
|
395 |
+
}
|
396 |
+
|
397 |
+
if ( $filters_normalized[ 'date' ][ $a_filter[ 1 ] ] === false ) {
|
398 |
+
unset( $filters_normalized[ 'date' ][ $a_filter[ 1 ] ] );
|
399 |
+
}
|
400 |
+
}
|
401 |
+
|
402 |
+
switch( $a_filter[ 1 ] ) {
|
403 |
+
case 'day':
|
404 |
+
if ( $filters_normalized[ 'date' ][ 'day' ] != date_i18n( 'j' ) ) {
|
405 |
+
$filters_normalized[ 'date' ][ 'is_past' ] = true;
|
406 |
+
}
|
407 |
+
break;
|
408 |
+
|
409 |
+
case 'month':
|
410 |
+
if ( $filters_normalized[ 'date' ][ 'month' ] != date_i18n( 'n' ) ) {
|
411 |
+
$filters_normalized[ 'date' ][ 'is_past' ] = true;
|
412 |
+
}
|
413 |
+
break;
|
414 |
+
|
415 |
+
case 'year':
|
416 |
+
if ( $filters_normalized[ 'date' ][ 'year' ] != date_i18n( 'Y' ) ) {
|
417 |
+
$filters_normalized[ 'date' ][ 'is_past' ] = true;
|
418 |
+
}
|
419 |
+
break;
|
420 |
+
|
421 |
+
default:
|
422 |
+
break;
|
423 |
+
}
|
424 |
+
break;
|
425 |
+
|
426 |
+
case 'interval':
|
427 |
+
case 'interval_hours':
|
428 |
+
case 'interval_minutes':
|
429 |
+
$intval_filter = intval( $a_filter[ 3 ] );
|
430 |
+
$filters_normalized[ 'date' ][ $a_filter[ 1 ] ] = abs( $intval_filter );
|
431 |
+
if ( $intval_filter < 0 ) {
|
432 |
+
$filters_normalized[ 'date' ][ 'interval_direction' ] = 'minus';
|
433 |
+
}
|
434 |
+
break;
|
435 |
+
|
436 |
+
case 'interval_direction':
|
437 |
+
$filters_normalized[ 'date' ][ $a_filter[ 1 ] ] = in_array( $a_filter[ 3 ], array( 'plus', 'minus' ) ) ? $a_filter[ 3 ] : 'plus';
|
438 |
+
break;
|
439 |
+
|
440 |
+
case 'direction':
|
441 |
+
case 'limit_results':
|
442 |
+
case 'start_from':
|
443 |
+
$filters_normalized[ 'misc' ][ $a_filter[ 1 ] ] = str_replace( '\\', '', htmlspecialchars_decode( $a_filter[ 3 ] ) );
|
444 |
+
break;
|
445 |
+
|
446 |
+
default:
|
447 |
+
$filters_normalized[ 'columns' ][ $a_filter[ 1 ] ] = array( $a_filter[ 2 ], isset( $a_filter[ 3 ] ) ? str_replace( '\\', '', htmlspecialchars_decode( $a_filter[ 3 ] ) ) : '' );
|
448 |
+
break;
|
449 |
+
}
|
450 |
+
}
|
451 |
+
}
|
452 |
+
|
453 |
+
// Temporarily disable any filters on date_i18n
|
454 |
+
$date_i18n_filters = array();
|
455 |
+
if ( !empty( $GLOBALS[ 'wp_filter' ][ 'date_i18n' ] ) ) {
|
456 |
+
$date_i18n_filters = $GLOBALS[ 'wp_filter' ][ 'date_i18n' ];
|
457 |
+
remove_all_filters( 'date_i18n' );
|
458 |
+
}
|
459 |
+
|
460 |
+
// Let's calculate our time range, based on date filters
|
461 |
+
if ( empty( $filters_normalized[ 'date' ][ 'interval' ] ) && empty( $filters_normalized[ 'date' ][ 'interval_hours' ] ) && empty( $filters_normalized[ 'date' ][ 'interval_minutes' ] ) ) {
|
462 |
+
if ( !empty( $filters_normalized[ 'date' ][ 'minute' ] ) ) {
|
463 |
+
$filters_normalized[ 'utime' ][ 'start' ] = mktime(
|
464 |
+
!empty( $filters_normalized[ 'date' ][ 'hour' ] )?$filters_normalized[ 'date' ][ 'hour' ]:0,
|
465 |
+
$filters_normalized[ 'date' ][ 'minute' ],
|
466 |
+
0,
|
467 |
+
!empty( $filters_normalized[ 'date' ][ 'month' ] )?$filters_normalized[ 'date' ][ 'month' ]:date_i18n( 'n' ),
|
468 |
+
!empty( $filters_normalized[ 'date' ][ 'day' ] )?$filters_normalized[ 'date' ][ 'day' ]:date_i18n( 'j' ),
|
469 |
+
!empty( $filters_normalized[ 'date' ][ 'year' ] )?$filters_normalized[ 'date' ][ 'year' ]:date_i18n( 'Y' )
|
470 |
+
);
|
471 |
+
$filters_normalized[ 'utime' ][ 'end' ] = $filters_normalized[ 'utime' ][ 'start' ] + 60;
|
472 |
+
$filters_normalized[ 'utime' ][ 'type' ] = 'H';
|
473 |
+
}
|
474 |
+
else if ( !empty( $filters_normalized[ 'date' ][ 'hour' ] ) ) {
|
475 |
+
$filters_normalized[ 'utime' ][ 'start' ] = mktime(
|
476 |
+
$filters_normalized[ 'date' ][ 'hour' ],
|
477 |
+
0,
|
478 |
+
0,
|
479 |
+
!empty( $filters_normalized[ 'date' ][ 'month' ] )?$filters_normalized[ 'date' ][ 'month' ]:date_i18n( 'n' ),
|
480 |
+
!empty( $filters_normalized[ 'date' ][ 'day' ] )?$filters_normalized[ 'date' ][ 'day' ]:date_i18n( 'j' ),
|
481 |
+
!empty( $filters_normalized[ 'date' ][ 'year' ] )?$filters_normalized[ 'date' ][ 'year' ]:date_i18n( 'Y' )
|
482 |
+
);
|
483 |
+
$filters_normalized[ 'utime' ][ 'end' ] = $filters_normalized[ 'utime' ][ 'start' ] + 3599;
|
484 |
+
$filters_normalized[ 'utime' ][ 'type' ] = 'H';
|
485 |
+
}
|
486 |
+
else if ( !empty( $filters_normalized[ 'date' ][ 'day' ] ) ) {
|
487 |
+
$filters_normalized[ 'utime' ][ 'start' ] = mktime(
|
488 |
+
0,
|
489 |
+
0,
|
490 |
+
0,
|
491 |
+
!empty( $filters_normalized[ 'date' ][ 'month' ] )?$filters_normalized[ 'date' ][ 'month' ]:date_i18n( 'n' ),
|
492 |
+
$filters_normalized[ 'date' ][ 'day' ],
|
493 |
+
!empty( $filters_normalized[ 'date' ][ 'year' ] )?$filters_normalized[ 'date' ][ 'year' ]:date_i18n( 'Y' )
|
494 |
+
);
|
495 |
+
$filters_normalized[ 'utime' ][ 'end' ] = $filters_normalized[ 'utime' ][ 'start' ] + 86399;
|
496 |
+
$filters_normalized[ 'utime' ][ 'type' ] = 'd';
|
497 |
+
}
|
498 |
+
else if( !empty( $filters_normalized[ 'date' ][ 'year' ] ) && empty( $filters_normalized[ 'date' ][ 'month' ] ) ) {
|
499 |
+
$filters_normalized[ 'utime' ][ 'start' ] = mktime( 0, 0, 0, 1, 1, $filters_normalized[ 'date' ][ 'year' ] );
|
500 |
+
$filters_normalized[ 'utime' ][ 'end' ] = mktime( 0, 0, 0, 1, 1, $filters_normalized[ 'date' ][ 'year' ]+1 )-1;
|
501 |
+
$filters_normalized[ 'utime' ][ 'type' ] = 'Y';
|
502 |
+
}
|
503 |
+
else {
|
504 |
+
$filters_normalized[ 'utime' ][ 'start' ] = mktime(
|
505 |
+
0,
|
506 |
+
0,
|
507 |
+
0,
|
508 |
+
!empty( $filters_normalized[ 'date' ][ 'month' ] )?$filters_normalized[ 'date' ][ 'month' ]:date_i18n( 'n' ),
|
509 |
+
1,
|
510 |
+
!empty( $filters_normalized[ 'date' ][ 'year' ] )?$filters_normalized[ 'date' ][ 'year' ]:date_i18n( 'Y' )
|
511 |
+
);
|
512 |
+
|
513 |
+
$filters_normalized[ 'utime' ][ 'end' ] = strtotime(
|
514 |
+
( !empty( $filters_normalized[ 'date' ][ 'year' ] )?$filters_normalized[ 'date' ][ 'year' ]:date_i18n( 'Y' ) ).'-'.
|
515 |
+
( !empty( $filters_normalized[ 'date' ][ 'month' ] )?$filters_normalized[ 'date' ][ 'month' ]:date_i18n( 'n' ) ).
|
516 |
+
'-01 00:00 +1 month UTC'
|
517 |
+
)-1;
|
518 |
+
$filters_normalized[ 'utime' ][ 'type' ] = 'm';
|
519 |
+
}
|
520 |
+
}
|
521 |
+
else { // An interval was specified
|
522 |
+
$filters_normalized[ 'utime' ][ 'type' ] = 'interval';
|
523 |
+
|
524 |
+
$filters_normalized[ 'utime' ][ 'start' ] = mktime(
|
525 |
+
!empty( $filters_normalized[ 'date' ][ 'hour' ] )?$filters_normalized[ 'date' ][ 'hour' ]:0,
|
526 |
+
!empty( $filters_normalized[ 'date' ][ 'minute' ] )?$filters_normalized[ 'date' ][ 'minute' ]:0,
|
527 |
+
0,
|
528 |
+
!empty( $filters_normalized[ 'date' ][ 'month' ] )?$filters_normalized[ 'date' ][ 'month' ]:date_i18n( 'n' ),
|
529 |
+
!empty( $filters_normalized[ 'date' ][ 'day' ] )?$filters_normalized[ 'date' ][ 'day' ]:date_i18n( 'j' ),
|
530 |
+
!empty( $filters_normalized[ 'date' ][ 'year' ] )?$filters_normalized[ 'date' ][ 'year' ]:date_i18n( 'Y' )
|
531 |
+
);
|
532 |
+
|
533 |
+
$sign = ( $filters_normalized[ 'date' ][ 'interval_direction' ] == 'plus' )?'+':'-';
|
534 |
+
|
535 |
+
$filters_normalized[ 'utime' ][ 'end' ] = $filters_normalized[ 'utime' ][ 'start' ] + intval( $sign.(
|
536 |
+
( !empty( $filters_normalized[ 'date' ][ 'interval' ] )?intval( $filters_normalized[ 'date' ][ 'interval' ] + 1):0 ) * 86400 +
|
537 |
+
( !empty( $filters_normalized[ 'date' ][ 'interval_hours' ] )?intval( $filters_normalized[ 'date' ][ 'interval_hours' ] ):0 ) * 3600 +
|
538 |
+
( !empty( $filters_normalized[ 'date' ][ 'interval_minutes' ] )?intval( $filters_normalized[ 'date' ][ 'interval_minutes' ] ):0 ) * 60
|
539 |
+
) ) - 1;
|
540 |
+
|
541 |
+
// Swap boundaries if we're going back in time
|
542 |
+
if ( $filters_normalized[ 'date' ][ 'interval_direction' ] == 'minus' ) {
|
543 |
+
list( $filters_normalized[ 'utime' ][ 'start' ], $filters_normalized[ 'utime' ][ 'end' ] ) = array( $filters_normalized[ 'utime' ][ 'end' ] + 1, $filters_normalized[ 'utime' ][ 'start' ] - 1 );
|
544 |
+
}
|
545 |
+
}
|
546 |
+
|
547 |
+
// If end is in the future, set it to now
|
548 |
+
if ( $filters_normalized[ 'utime' ][ 'end' ] > date_i18n( 'U' ) ) {
|
549 |
+
$filters_normalized[ 'utime' ][ 'end' ] = date_i18n( 'U' );
|
550 |
+
}
|
551 |
+
|
552 |
+
// If start is after end, set it to first of month
|
553 |
+
if ( $filters_normalized[ 'utime' ][ 'start' ] > $filters_normalized[ 'utime' ][ 'end' ] ) {
|
554 |
+
$filters_normalized[ 'utime' ][ 'start' ] = mktime(
|
555 |
+
0,
|
556 |
+
0,
|
557 |
+
0,
|
558 |
+
date_i18n( 'n', $filters_normalized[ 'utime' ][ 'end' ] ),
|
559 |
+
1,
|
560 |
+
date_i18n( 'Y', $filters_normalized[ 'utime' ][ 'end' ] )
|
561 |
+
);
|
562 |
+
$filters_normalized[ 'date' ][ 'hour' ] = $filters_normalized[ 'date' ][ 'day' ] = $filters_normalized[ 'date' ][ 'month' ] = $filters_normalized[ 'date' ][ 'year' ] = 0;
|
563 |
+
}
|
564 |
+
|
565 |
+
// Restore filters on date_i18n
|
566 |
+
foreach ($date_i18n_filters as $i18n_priority => $i18n_func_list) {
|
567 |
+
foreach ($i18n_func_list as $func_name => $func_args) {
|
568 |
+
add_filter('date_i8n', $func_args[ 'function' ], $i18n_priority, $func_args[ 'accepted_args' ]);
|
569 |
+
}
|
570 |
+
}
|
571 |
+
|
572 |
+
return $filters_normalized;
|
573 |
+
}
|
574 |
+
|
575 |
+
// The following methods retrieve the information from the database
|
576 |
+
|
577 |
+
public static function count_bouncing_pages() {
|
578 |
+
$where = self::get_combined_where( 'visit_id > 0 AND content_type <> "404"', 'resource' );
|
579 |
+
|
580 |
+
return intval( self::get_var( "
|
581 |
+
SELECT COUNT(*) counthits
|
582 |
+
FROM (
|
583 |
+
SELECT resource, visit_id
|
584 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
585 |
+
WHERE $where
|
586 |
+
GROUP BY resource
|
587 |
+
HAVING COUNT(visit_id) = 1
|
588 |
+
) as ts1",
|
589 |
+
'SUM(counthits) AS counthits' ) );
|
590 |
+
}
|
591 |
+
|
592 |
+
public static function count_exit_pages() {
|
593 |
+
$where = self::get_combined_where( 'visit_id > 0', 'resource' );
|
594 |
+
|
595 |
+
return intval( self::get_var( "
|
596 |
+
SELECT COUNT(*) counthits
|
597 |
+
FROM (
|
598 |
+
SELECT resource, dt
|
599 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
600 |
+
WHERE $where
|
601 |
+
GROUP BY resource
|
602 |
+
HAVING dt = MAX(dt)
|
603 |
+
) AS ts1",
|
604 |
+
'SUM(counthits) AS counthits' ) );
|
605 |
+
}
|
606 |
+
|
607 |
+
public static function count_records( $_column = 'id', $_where = '', $_use_date_filters = true ) {
|
608 |
+
$distinct_column = ( $_column != 'id' ) ? "DISTINCT $_column" : $_column;
|
609 |
+
$_where = self::get_combined_where( $_where, $_column, $_use_date_filters );
|
610 |
+
|
611 |
+
return intval( self::get_var( "
|
612 |
+
SELECT COUNT($distinct_column) counthits
|
613 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
614 |
+
WHERE $_where",
|
615 |
+
'SUM(counthits) AS counthits' ) );
|
616 |
+
}
|
617 |
+
|
618 |
+
public static function count_records_having( $_column = 'id', $_where = '', $_having = '' ) {
|
619 |
+
$_where = self::get_combined_where( $_where, $_column );
|
620 |
+
|
621 |
+
return intval( self::get_var( "
|
622 |
+
SELECT COUNT(*) counthits FROM (
|
623 |
+
SELECT $_column
|
624 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
625 |
+
WHERE $_where
|
626 |
+
GROUP BY $_column
|
627 |
+
HAVING $_having
|
628 |
+
) AS ts1",
|
629 |
+
'SUM(counthits) AS counthits' ) );
|
630 |
+
}
|
631 |
+
|
632 |
+
public static function get_data_for_chart( $_data1 = '', $_data2 = '', $_where = '' ) {
|
633 |
+
$previous = array( 'end' => self::$filters_normalized[ 'utime' ][ 'start' ] - 1 );
|
634 |
+
$label_date_format = '';
|
635 |
+
$output = array();
|
636 |
+
|
637 |
+
// Each type has its own parameters
|
638 |
+
switch (self::$filters_normalized[ 'utime' ][ 'type' ]) {
|
639 |
+
case 'H':
|
640 |
+
$previous[ 'start' ] = self::$filters_normalized[ 'utime' ][ 'start' ] - 3600;
|
641 |
+
$label_date_format = wp_slimstat::$options[ 'time_format' ];
|
642 |
+
$group_by = array( 'HOUR', 'MINUTE', 'i' );
|
643 |
+
$values_in_interval = array( 59, 59, 0, 60 );
|
644 |
+
break;
|
645 |
+
|
646 |
+
case 'd':
|
647 |
+
$previous[ 'start' ] = self::$filters_normalized[ 'utime' ][ 'start' ] - 86400;
|
648 |
+
$label_date_format = ( self::$formats[ 'decimal' ] == '.' ) ? 'm/d' : 'd/m';
|
649 |
+
$group_by = array( 'DAY', 'HOUR', 'G' );
|
650 |
+
$values_in_interval = array( 23, 23, 0, 3600 );
|
651 |
+
break;
|
652 |
+
|
653 |
+
case 'Y':
|
654 |
+
$previous[ 'start' ] = mktime( 0, 0, 0, 1, 1, self::$filters_normalized[ 'date' ][ 'year' ] - 1 );
|
655 |
+
$label_date_format = 'Y';
|
656 |
+
$group_by = array( 'YEAR', 'MONTH', 'n' );
|
657 |
+
$values_in_interval = array( 12, 12, 1, 2678400 );
|
658 |
+
break;
|
659 |
+
|
660 |
+
case 'interval':
|
661 |
+
$group_by = array( 'MONTH', 'DAY', 'j' );
|
662 |
+
$values_in_interval = array( abs( self::$filters_normalized[ 'date' ][ 'interval' ] ), abs( self::$filters_normalized[ 'date' ][ 'interval' ] ), 0, 86400 );
|
663 |
+
break;
|
664 |
+
|
665 |
+
default:
|
666 |
+
$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' ) );
|
667 |
+
$label_date_format = 'm/Y';
|
668 |
+
$group_by = array( 'MONTH', 'DAY', 'j' );
|
669 |
+
$values_in_interval = array( date( 't', $previous[ 'start' ] ), date( 't', self::$filters_normalized[ 'utime' ][ 'start' ] ), 1, 86400 );
|
670 |
+
break;
|
671 |
+
}
|
672 |
+
|
673 |
+
// Custom intervals don't have a comparison chart ('previous' range)
|
674 |
+
if ( empty( self::$filters_normalized[ 'date' ][ 'interval' ] ) ) {
|
675 |
+
$_where = self::get_combined_where( $_where, '*', false );
|
676 |
+
$previous_time_range = ' AND (dt BETWEEN '.$previous[ 'start' ].' AND '.$previous[ 'end' ].' OR dt BETWEEN '.self::$filters_normalized[ 'utime' ][ 'start' ].' AND '.self::$filters_normalized[ 'utime' ][ 'end' ].')';
|
677 |
+
}
|
678 |
+
else {
|
679 |
+
$_where = self::get_combined_where( $_where );
|
680 |
+
$previous_time_range = '';
|
681 |
+
}
|
682 |
+
|
683 |
+
// Build the SQL query
|
684 |
+
$group_by_string = "GROUP BY {$group_by[0]}(CONVERT_TZ(FROM_UNIXTIME(dt), @@session.time_zone, '+00:00')), {$group_by[1]}(CONVERT_TZ(FROM_UNIXTIME(dt), @@session.time_zone, '+00:00'))";
|
685 |
+
$sql = "
|
686 |
+
SELECT dt, $_data1 first_metric, $_data2 second_metric
|
687 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
688 |
+
WHERE $_where $previous_time_range
|
689 |
+
$group_by_string";
|
690 |
+
|
691 |
+
// Get the data
|
692 |
+
$results = self::get_results( $sql, 'blog_id', '', $group_by_string, 'SUM(first_metric) AS first_metric, SUM(second_metric) AS second_metric' );
|
693 |
+
|
694 |
+
// Fill the output array
|
695 |
+
$output[ 'current' ][ 'label' ] = '';
|
696 |
+
if ( !empty( $label_date_format ) ) {
|
697 |
+
$output[ 'current' ][ 'label' ] = gmdate( $label_date_format, self::$filters_normalized[ 'utime' ][ 'start' ] );
|
698 |
+
$output[ 'previous' ][ 'label' ] = gmdate( $label_date_format, $previous[ 'start' ] );
|
699 |
+
}
|
700 |
+
|
701 |
+
$output[ 'previous' ][ 'first_metric' ] = array_fill( $values_in_interval[ 2 ], $values_in_interval[ 0 ], 0 );
|
702 |
+
$output['previous']['second_metric'] = array_fill( $values_in_interval[ 2 ], $values_in_interval[ 0 ], 0 );
|
703 |
+
|
704 |
+
$today_limit = floatval( date_i18n( 'Ymd.Hi' ) );
|
705 |
+
for ( $i = $values_in_interval[ 2 ]; $i <= $values_in_interval[ 1 ]; $i++ ){
|
706 |
+
// Do not include dates in the future
|
707 |
+
if ( floatval( date( 'Ymd.Hi', wp_slimstat_db::$filters_normalized[ 'utime' ][ 'start' ] + ( ( $i - $values_in_interval[ 2 ]) * $values_in_interval[ 3 ] ) ) ) > $today_limit ) {
|
708 |
+
continue;
|
709 |
+
}
|
710 |
+
|
711 |
+
$output[ 'current' ][ 'first_metric' ][ $i ] = 0;
|
712 |
+
$output[ 'current' ][ 'second_metric' ][ $i ] = 0;
|
713 |
+
}
|
714 |
+
|
715 |
+
// No data? No problem!
|
716 |
+
if ( !is_array( $results ) || empty( $results ) ) {
|
717 |
+
return $output;
|
718 |
+
}
|
719 |
+
|
720 |
+
// Rearrange the data and then format it for Flot
|
721 |
+
foreach ($results as $i => $a_result ) {
|
722 |
+
$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' ] );
|
723 |
+
|
724 |
+
if ( empty( self::$filters_normalized[ 'date' ][ 'interval' ] ) && gmdate( self::$filters_normalized[ 'utime' ][ 'type' ], $a_result[ 'dt' ] ) == gmdate( self::$filters_normalized[ 'utime' ][ 'type' ], $previous[ 'start' ] ) ){
|
725 |
+
$output[ 'previous' ][ 'first_metric' ][ $index ] = $a_result[ 'first_metric' ];
|
726 |
+
$output[ 'previous' ][ 'second_metric' ][ $index ] = $a_result[ 'second_metric' ];
|
727 |
+
}
|
728 |
+
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' ] ) ){
|
729 |
+
$output[ 'current' ][ 'first_metric' ][ $index ] = $a_result[ 'first_metric' ];
|
730 |
+
$output[ 'current' ][ 'second_metric' ][ $index ] = $a_result[ 'second_metric' ];
|
731 |
+
}
|
732 |
+
}
|
733 |
+
|
734 |
+
return $output;
|
735 |
+
}
|
736 |
+
|
737 |
+
public static function get_data_size() {
|
738 |
+
$suffix = 'KB';
|
739 |
+
|
740 |
+
$sql = 'SHOW TABLE STATUS LIKE "'.$GLOBALS[ 'wpdb' ]->prefix.'slim_stats"';
|
741 |
+
$table_details = wp_slimstat::$wpdb->get_row( $sql, 'ARRAY_A', 0 );
|
742 |
+
|
743 |
+
$table_size = ( $table_details[ 'Data_length' ] / 1024 ) + ( $table_details[ 'Index_length' ] / 1024 );
|
744 |
+
|
745 |
+
if ( $table_size > 1024 ) {
|
746 |
+
$table_size /= 1024;
|
747 |
+
$suffix = 'MB';
|
748 |
+
}
|
749 |
+
return number_format( $table_size, 2, self::$formats[ 'decimal' ], self::$formats[ 'thousand' ] ).' '.$suffix;
|
750 |
+
}
|
751 |
+
|
752 |
+
public static function get_max_and_average_pages_per_visit() {
|
753 |
+
$where = self::get_combined_where( 'visit_id > 0' );
|
754 |
+
|
755 |
+
return self::get_results( "
|
756 |
+
SELECT AVG(ts1.counthits) AS avghits, MAX(ts1.counthits) AS maxhits FROM (
|
757 |
+
SELECT count(ip) counthits, visit_id
|
758 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
759 |
+
WHERE $where
|
760 |
+
GROUP BY visit_id
|
761 |
+
) AS ts1",
|
762 |
+
'blog_id',
|
763 |
+
'',
|
764 |
+
'',
|
765 |
+
'AVG(avghits) AS avghits, MAX(maxhits) AS maxhits' );
|
766 |
+
}
|
767 |
+
|
768 |
+
public static function get_oldest_visit() {
|
769 |
+
return self::get_var( "
|
770 |
+
SELECT dt
|
771 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
772 |
+
ORDER BY dt ASC
|
773 |
+
LIMIT 0, 1",
|
774 |
+
'MIN(dt)' );
|
775 |
+
}
|
776 |
+
|
777 |
+
public static function get_recent( $_column = 'id', $_where = '', $_having = '', $_use_date_filters = true, $_as_column = '', $_more_columns = '' ) {
|
778 |
+
// This function can be passed individual arguments, or an array of arguments
|
779 |
+
if ( is_array( $_column ) ) {
|
780 |
+
$_where = !empty( $_column[ 'where' ] ) ? $_column[ 'where' ] : '';
|
781 |
+
$_having = !empty( $_column[ 'having' ] ) ? $_column[ 'having' ] : '';
|
782 |
+
$_use_date_filters = !empty( $_column[ 'use_date_filters' ] ) ? $_column[ 'use_date_filters' ] : true;
|
783 |
+
$_as_column = !empty( $_column[ 'as_column' ] ) ? $_column[ 'as_column' ] : '';
|
784 |
+
$_more_columns = !empty( $_column[ 'more_columns' ] ) ? $_column[ 'more_columns' ] : '';
|
785 |
+
$_column = $_column[ 'columns' ];
|
786 |
+
}
|
787 |
+
|
788 |
+
$columns = $_column;
|
789 |
+
if ( !empty( $_as_column ) ) {
|
790 |
+
$columns = "$_column AS $_as_column";
|
791 |
+
}
|
792 |
+
|
793 |
+
if ( $_column != '*' ) {
|
794 |
+
$columns .= ', ip, dt';
|
795 |
+
}
|
796 |
+
|
797 |
+
if ( !empty( $_more_columns ) ) {
|
798 |
+
$columns .= ', ' . $_more_columns;
|
799 |
+
}
|
800 |
+
|
801 |
+
$_where = self::get_combined_where( $_where, $_column, $_use_date_filters );
|
802 |
+
|
803 |
+
//if ( $_column == 'id' || $_column == '*' ) {
|
804 |
+
$results = self::get_results( "
|
805 |
+
SELECT $columns
|
806 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
807 |
+
WHERE $_where
|
808 |
+
ORDER BY dt DESC
|
809 |
+
LIMIT 0, " . self::$filters_normalized[ 'misc' ][ 'limit_results' ],
|
810 |
+
$columns,
|
811 |
+
'dt DESC' );
|
812 |
+
|
813 |
+
if ( $_column != '*' ) {
|
814 |
+
$column_values = array_map( 'unserialize', array_unique( array_map( 'serialize', self::array_column( $results, explode( ',', $_column ) ) ) ) );
|
815 |
+
$results = array_intersect_key( $results, $column_values );
|
816 |
+
}
|
817 |
+
|
818 |
+
return $results;
|
819 |
+
|
820 |
+
//}
|
821 |
+
//else {
|
822 |
+
// return self::get_results( "
|
823 |
+
// SELECT t1.*
|
824 |
+
// FROM (
|
825 |
+
// SELECT $_column, MAX(id) maxid
|
826 |
+
// FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
827 |
+
// WHERE $_where
|
828 |
+
// GROUP BY $_as_column $_having
|
829 |
+
// ) AS ts1 INNER JOIN {$GLOBALS['wpdb']->prefix}slim_stats t1 ON ts1.maxid = t1.id
|
830 |
+
// ORDER BY t1.dt DESC
|
831 |
+
// LIMIT 0, " . self::$filters_normalized[ 'misc' ][ 'limit_results' ],
|
832 |
+
// ( ( !empty( $_as_column ) && $_as_column != $_column ) ? $_as_column : $_column ).', blog_id',
|
833 |
+
// 't1.dt DESC' );
|
834 |
+
//}
|
835 |
+
}
|
836 |
+
|
837 |
+
public static function get_recent_events() {
|
838 |
+
if ( empty( self::$filters_normalized[ 'columns' ] ) ) {
|
839 |
+
$from = "{$GLOBALS['wpdb']->prefix}slim_events te";
|
840 |
+
$where = wp_slimstat_db::get_combined_where( 'te.type > 1', 'notes' );
|
841 |
+
}
|
842 |
+
else {
|
843 |
+
$from = "{$GLOBALS['wpdb']->prefix}slim_events te INNER JOIN {$GLOBALS['wpdb']->prefix}slim_stats t1 ON te.id = t1.id";
|
844 |
+
$where = wp_slimstat_db::get_combined_where( 'te.type > 1', 'notes', true, 't1' );
|
845 |
+
}
|
846 |
+
|
847 |
+
return self::get_results( "
|
848 |
+
SELECT *
|
849 |
+
FROM $from
|
850 |
+
WHERE $where
|
851 |
+
ORDER BY te.dt DESC"
|
852 |
+
);
|
853 |
+
}
|
854 |
+
|
855 |
+
public static function get_top( $_column = 'id', $_where = '', $_having = '', $_use_date_filters = true, $_as_column = '' ){
|
856 |
+
// This function can be passed individual arguments, or an array of arguments
|
857 |
+
if ( is_array( $_column ) ) {
|
858 |
+
$_where = !empty( $_column[ 'where' ] ) ? $_column[ 'where' ] : '';
|
859 |
+
$_having = !empty( $_column[ 'having' ] ) ? $_column[ 'having' ] : '';
|
860 |
+
$_use_date_filters = !empty( $_column[ 'use_date_filters' ] ) ? $_column[ 'use_date_filters' ] : true;
|
861 |
+
$_as_column = !empty( $_column[ 'as_column' ] ) ? $_column[ 'as_column' ] : '';
|
862 |
+
$_column = $_column[ 'columns' ];
|
863 |
+
}
|
864 |
+
|
865 |
+
if ( !empty( $_as_column ) ) {
|
866 |
+
$_column = "$_column AS $_as_column";
|
867 |
+
}
|
868 |
+
else {
|
869 |
+
$_as_column = $_column;
|
870 |
+
}
|
871 |
+
|
872 |
+
$_where = self::get_combined_where( $_where, $_as_column, $_use_date_filters );
|
873 |
+
|
874 |
+
return self::get_results( "
|
875 |
+
SELECT $_column, COUNT(*) counthits
|
876 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
877 |
+
WHERE $_where
|
878 |
+
GROUP BY $_as_column $_having
|
879 |
+
ORDER BY counthits DESC
|
880 |
+
LIMIT 0, " . self::$filters_normalized[ 'misc' ][ 'limit_results' ],
|
881 |
+
( ( !empty( $_as_column ) && $_as_column != $_column ) ? $_as_column : $_column ).', blog_id',
|
882 |
+
'counthits DESC',
|
883 |
+
$_column,
|
884 |
+
'SUM(counthits) AS counthits' );
|
885 |
+
}
|
886 |
+
|
887 |
+
public static function get_top_aggr( $_column = 'id', $_where = '', $_outer_select_column = '', $_aggr_function = 'MAX' ) {
|
888 |
+
if ( is_array( $_column ) ) {
|
889 |
+
$_where = !empty( $_column[ 'where' ] ) ? $_column[ 'where' ] : '';
|
890 |
+
$_having = !empty( $_column[ 'having' ] ) ? $_column[ 'having' ] : '';
|
891 |
+
$_use_date_filters = !empty( $_column[ 'use_date_filters' ] ) ? $_column[ 'use_date_filters' ] : true;
|
892 |
+
$_as_column = !empty( $_column[ 'as_column' ] ) ? $_column[ 'as_column' ] : '';
|
893 |
+
$_outer_select_column = !empty( $_column[ 'outer_select_column' ] ) ? $_column[ 'outer_select_column' ] : '';
|
894 |
+
$_aggr_function = !empty( $_column[ 'aggr_function' ] ) ? $_column[ 'aggr_function' ] : '';
|
895 |
+
$_column = $_column[ 'columns' ];
|
896 |
+
}
|
897 |
+
|
898 |
+
if ( !empty( $_as_column ) ) {
|
899 |
+
$_column = "$_column AS $_as_column";
|
900 |
+
}
|
901 |
+
else {
|
902 |
+
$_as_column = $_column;
|
903 |
+
}
|
904 |
+
|
905 |
+
$_where = self::get_combined_where( $_where, $_column );
|
906 |
+
|
907 |
+
return self::get_results( "
|
908 |
+
SELECT $_outer_select_column, ts1.aggrid as $_column, COUNT(*) counthits
|
909 |
+
FROM (
|
910 |
+
SELECT $_column, $_aggr_function(id) aggrid
|
911 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats
|
912 |
+
WHERE $_where
|
913 |
+
GROUP BY $_column
|
914 |
+
) AS ts1 JOIN {$GLOBALS['wpdb']->prefix}slim_stats t1 ON ts1.aggrid = t1.id
|
915 |
+
GROUP BY $_outer_select_column
|
916 |
+
ORDER BY counthits DESC
|
917 |
+
LIMIT 0, " . self::$filters_normalized[ 'misc' ][ 'limit_results' ],
|
918 |
+
$_outer_select_column,
|
919 |
+
'counthits DESC',
|
920 |
+
$_outer_select_column,
|
921 |
+
"$_aggr_function(aggrid), SUM(counthits)" );
|
922 |
+
}
|
923 |
+
|
924 |
+
public static function get_top_events() {
|
925 |
+
if ( empty( self::$filters_normalized[ 'columns' ] ) ) {
|
926 |
+
$from = "{$GLOBALS['wpdb']->prefix}slim_events te";
|
927 |
+
$where = wp_slimstat_db::get_combined_where( 'te.type > 1', 'notes' );
|
928 |
+
}
|
929 |
+
else {
|
930 |
+
$from = "{$GLOBALS['wpdb']->prefix}slim_events te INNER JOIN {$GLOBALS['wpdb']->prefix}slim_stats t1 ON te.id = t1.id";
|
931 |
+
$where = wp_slimstat_db::get_combined_where( 'te.type > 1', 'notes', true, 't1' );
|
932 |
+
}
|
933 |
+
|
934 |
+
return self::get_results( "
|
935 |
+
SELECT te.notes, te.type, COUNT(*) counthits
|
936 |
+
FROM $from
|
937 |
+
WHERE $where
|
938 |
+
GROUP BY te.notes, te.type
|
939 |
+
ORDER BY counthits DESC"
|
940 |
+
);
|
941 |
+
}
|
942 |
+
|
943 |
+
protected static function array_column( $input = array(), $columns = array() ) {
|
944 |
+
$output = array();
|
945 |
+
|
946 |
+
foreach ( $input as $a_key => $a_row ) {
|
947 |
+
foreach ( $columns as $a_column ) {
|
948 |
+
$a_column = trim( $a_column );
|
949 |
+
if ( $a_row[ $a_column ] != NULL ) {
|
950 |
+
$output[ $a_key ][ $a_column ] = $a_row[ $a_column ];
|
951 |
+
}
|
952 |
+
}
|
953 |
+
}
|
954 |
+
|
955 |
+
return $output;
|
956 |
+
}
|
957 |
}
|
admin/view/wp-slimstat-reports.php
CHANGED
@@ -85,7 +85,7 @@ class wp_slimstat_reports {
|
|
85 |
'callback' => array( __CLASS__, 'show_activity_log' ),
|
86 |
'callback_args' => array(
|
87 |
'type' => 'recent',
|
88 |
-
'columns' => '
|
89 |
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
90 |
),
|
91 |
'classes' => array( 'full-width', 'tall' ),
|
@@ -143,6 +143,7 @@ class wp_slimstat_reports {
|
|
143 |
'callback_args' => array(
|
144 |
'type' => 'recent',
|
145 |
'columns' => 'searchterms',
|
|
|
146 |
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
147 |
),
|
148 |
'classes' => array( 'normal' ),
|
@@ -169,7 +170,7 @@ class wp_slimstat_reports {
|
|
169 |
'callback_args' => array(
|
170 |
'type' => 'top',
|
171 |
'columns' => 'referer',
|
172 |
-
'where' => 'referer NOT LIKE "%' . home_url() . '%"',
|
173 |
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
174 |
),
|
175 |
'classes' => array( 'normal' ),
|
@@ -474,24 +475,27 @@ class wp_slimstat_reports {
|
|
474 |
'classes' => array( 'normal' ),
|
475 |
'screens' => array( 'wp-slim-view-5', 'dashboard' )
|
476 |
),
|
|
|
|
|
477 |
'slim_p3_11' => array(
|
478 |
'title' => __( 'Recent Exit Pages', 'wp-slimstat' ),
|
479 |
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
480 |
'callback_args' => array(
|
481 |
'type' => 'recent',
|
482 |
-
'columns' => 'visit_id', // raw_results_to_html knows to display the resource, when the column is visit_id
|
483 |
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
484 |
),
|
485 |
'classes' => array( 'normal' ),
|
486 |
'screens' => array( 'wp-slim-view-5' )
|
487 |
),
|
|
|
488 |
|
489 |
'slim_p4_01' => array(
|
490 |
'title' => __( 'Recent Outbound Links', 'wp-slimstat' ),
|
491 |
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
492 |
'callback_args' => array(
|
493 |
'type' => 'recent',
|
494 |
-
'columns' => 'outbound_resource',
|
495 |
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
496 |
),
|
497 |
'classes' => array( 'wide' ),
|
@@ -510,6 +514,7 @@ class wp_slimstat_reports {
|
|
510 |
'classes' => array( 'normal' ),
|
511 |
'screens' => array( 'wp-slim-view-4' )
|
512 |
),
|
|
|
513 |
'slim_p4_03' => array(
|
514 |
'title' => __( 'Recent Bounce Pages', 'wp-slimstat' ),
|
515 |
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
@@ -524,6 +529,7 @@ class wp_slimstat_reports {
|
|
524 |
'screens' => array( 'wp-slim-view-4' ),
|
525 |
'tooltip' => __( 'A <em>bounce page</em> is a single-page visit, or visit in which the person left your site from the entrance (landing) page.', 'wp-slimstat' )
|
526 |
),
|
|
|
527 |
'slim_p4_04' => array(
|
528 |
'title' => __( 'Recent Feeds', 'wp-slimstat' ),
|
529 |
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
@@ -1009,14 +1015,14 @@ class wp_slimstat_reports {
|
|
1009 |
break;
|
1010 |
|
1011 |
case 'searchterms':
|
1012 |
-
if ($_args[ 'type' ] == 'recent'){
|
1013 |
-
$domain = parse_url( $results[ $i ][ '
|
1014 |
-
|
1015 |
-
$row_details = '<br>'.__('Referrer','wp-slimstat').": $domain";
|
1016 |
-
$element_value = self::get_search_terms_info($results[$i]['searchterms'], $results[$i]['referer'], true);
|
1017 |
}
|
1018 |
else{
|
1019 |
-
$element_value = htmlentities($results[$i]['searchterms'], ENT_QUOTES, 'UTF-8');
|
1020 |
}
|
1021 |
break;
|
1022 |
case 'username':
|
85 |
'callback' => array( __CLASS__, 'show_activity_log' ),
|
86 |
'callback_args' => array(
|
87 |
'type' => 'recent',
|
88 |
+
'columns' => '*',
|
89 |
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
90 |
),
|
91 |
'classes' => array( 'full-width', 'tall' ),
|
143 |
'callback_args' => array(
|
144 |
'type' => 'recent',
|
145 |
'columns' => 'searchterms',
|
146 |
+
'more_columns' => 'referer, resource',
|
147 |
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
148 |
),
|
149 |
'classes' => array( 'normal' ),
|
170 |
'callback_args' => array(
|
171 |
'type' => 'top',
|
172 |
'columns' => 'referer',
|
173 |
+
'where' => 'referer NOT LIKE "%' . str_replace( 'www.', '', parse_url( home_url(), PHP_URL_HOST ) ) . '%"',
|
174 |
'raw' => array( 'wp_slimstat_db', 'get_top' )
|
175 |
),
|
176 |
'classes' => array( 'normal' ),
|
475 |
'classes' => array( 'normal' ),
|
476 |
'screens' => array( 'wp-slim-view-5', 'dashboard' )
|
477 |
),
|
478 |
+
|
479 |
+
/*
|
480 |
'slim_p3_11' => array(
|
481 |
'title' => __( 'Recent Exit Pages', 'wp-slimstat' ),
|
482 |
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
483 |
'callback_args' => array(
|
484 |
'type' => 'recent',
|
485 |
+
'columns' => 'visit_id, resource', // raw_results_to_html knows to display the resource, when the column is visit_id
|
486 |
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
487 |
),
|
488 |
'classes' => array( 'normal' ),
|
489 |
'screens' => array( 'wp-slim-view-5' )
|
490 |
),
|
491 |
+
*/
|
492 |
|
493 |
'slim_p4_01' => array(
|
494 |
'title' => __( 'Recent Outbound Links', 'wp-slimstat' ),
|
495 |
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
496 |
'callback_args' => array(
|
497 |
'type' => 'recent',
|
498 |
+
'columns' => 'outbound_resource',
|
499 |
'raw' => array( 'wp_slimstat_db', 'get_recent' )
|
500 |
),
|
501 |
'classes' => array( 'wide' ),
|
514 |
'classes' => array( 'normal' ),
|
515 |
'screens' => array( 'wp-slim-view-4' )
|
516 |
),
|
517 |
+
/*
|
518 |
'slim_p4_03' => array(
|
519 |
'title' => __( 'Recent Bounce Pages', 'wp-slimstat' ),
|
520 |
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
529 |
'screens' => array( 'wp-slim-view-4' ),
|
530 |
'tooltip' => __( 'A <em>bounce page</em> is a single-page visit, or visit in which the person left your site from the entrance (landing) page.', 'wp-slimstat' )
|
531 |
),
|
532 |
+
*/
|
533 |
'slim_p4_04' => array(
|
534 |
'title' => __( 'Recent Feeds', 'wp-slimstat' ),
|
535 |
'callback' => array( __CLASS__, 'raw_results_to_html' ),
|
1015 |
break;
|
1016 |
|
1017 |
case 'searchterms':
|
1018 |
+
if ( $_args[ 'type' ] == 'recent' ) {
|
1019 |
+
$domain = parse_url( $results[ $i ][ 'referer' ], PHP_URL_HOST );
|
1020 |
+
|
1021 |
+
$row_details = '<br>' . __( 'Referrer', 'wp-slimstat' ) . ": $domain";
|
1022 |
+
$element_value = self::get_search_terms_info( $results[ $i ][ 'searchterms' ], $results[ $i ][ 'referer' ], true );
|
1023 |
}
|
1024 |
else{
|
1025 |
+
$element_value = htmlentities( $results[ $i ][ 'searchterms' ], ENT_QUOTES, 'UTF-8' );
|
1026 |
}
|
1027 |
break;
|
1028 |
case 'username':
|
admin/wp-slimstat-admin.php
CHANGED
@@ -11,8 +11,8 @@ class wp_slimstat_admin{
|
|
11 |
*/
|
12 |
public static function init(){
|
13 |
if ((wp_slimstat::$options['enable_ads_network'] == 'yes' || wp_slimstat::$options['enable_ads_network'] == 'no')){
|
14 |
-
self::$admin_notice = "
|
15 |
-
// self::$admin_notice = "
|
16 |
self::$admin_notice .= '<br/><br/><a id="slimstat-hide-admin-notice" href="#" class="button-secondary">Got it, thanks</a>';
|
17 |
}
|
18 |
else {
|
11 |
*/
|
12 |
public static function init(){
|
13 |
if ((wp_slimstat::$options['enable_ads_network'] == 'yes' || wp_slimstat::$options['enable_ads_network'] == 'no')){
|
14 |
+
self::$admin_notice = "Isn't it nice when a WordPress Forum moderator <a href='https://wordpress.org/support/topic/statistics-30' target='_blank'>recommends Slimstat</a> to those who ask what analytics tool to use for their website? Thank you 1.6 million times for showing your appreciation and support, and making Slimstat one of the leading analytics tools for WordPress. We are celebrating by updating our website with a new homepage and new information on this plugin. <a href='http://www.wp-slimstat.com/' target='_blank'>Go take a look</a>.";
|
15 |
+
// self::$admin_notice = "Performance, performance, performance. This has been our mantra in the last few weeks. The new database API introduced in version 4 allowed us to clean up our code and reveal little hidden paths that lead to code perfection. <a href='https://wordpress.org/support/view/plugin-reviews/wp-slimstat#postform' target='_blank'>Let us know</a> if you notice any difference in the amount of time needed to generate your reports.";
|
16 |
self::$admin_notice .= '<br/><br/><a id="slimstat-hide-admin-notice" href="#" class="button-secondary">Got it, thanks</a>';
|
17 |
}
|
18 |
else {
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_i
|
|
4 |
Tags: analytics, tracking, reports, analyze, wassup, geolocation, online users, spider, tracker, pageviews, stats, maxmind, statistics, statpress
|
5 |
Requires at least: 3.8
|
6 |
Tested up to: 4.3
|
7 |
-
Stable tag: 4.1.6
|
8 |
|
9 |
== Description ==
|
10 |
[youtube https://www.youtube.com/watch?v=iJCtjxArq4U]
|
@@ -22,13 +22,13 @@ Stable tag: 4.1.6
|
|
22 |
* 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)
|
23 |
* Read all the [reviews](http://wordpress.org/support/view/plugin-reviews/wp-slimstat) and feel free to post your own!
|
24 |
|
25 |
-
= Requirements =
|
26 |
-
* WordPress 3.8
|
27 |
-
* PHP 5.3
|
28 |
-
* MySQL 5.0.3
|
29 |
-
*
|
30 |
-
*
|
31 |
-
*
|
32 |
* IE9+ or any browser supporting HTML5, to access the reports
|
33 |
|
34 |
= Premium Add-ons =
|
@@ -59,6 +59,17 @@ Our knowledge base is available on our [support center](http://docs.wp-slimstat.
|
|
59 |
|
60 |
== Changelog ==
|
61 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
= 4.1.6 =
|
63 |
* [New] Administrators can now set the maximum number of records that should be retrieved from the database when generating the reports (Settings > Reports). This allows those with powerful servers and unlimited PHP resources to increase this limit and get a more accurate picture of their visitors.
|
64 |
* [New] Extended the export functionality (via our premium Export to Excel add-on) to reports like At a Glance, Rankings, Audience Overview, etc (thank you, Tiffany).
|
@@ -158,42 +169,6 @@ Our knowledge base is available on our [support center](http://docs.wp-slimstat.
|
|
158 |
* [Fix] In Client Mode (aka Javascript mode), all page content types were being set to 'admin', under certain circumstances.
|
159 |
* [Fix] THe uninstall script was not removing the 'old' tables (wp_slim_stats_3, wp_slim_stats_archive_3).
|
160 |
|
161 |
-
= 4.0.2 =
|
162 |
-
* [Note] There seem to be some issues with the tracker not being updated throughout the CDN. If you are using this service, please disable it temporarily (Settings > Advanced > Enable CDN = No) until this is resolved. [We are in touch](https://github.com/jsdelivr/jsdelivr/issues/2632#issuecomment-101994217) with the team managing the CDN.
|
163 |
-
* [Fix] Some users reported a PHP syntax error message related to a short syntax used by the heuristic browser detection script (thank you, [engesco](https://wordpress.org/support/topic/error-with-new-plug-in-update?replies=27#post-6949271))
|
164 |
-
* [Fix] A PHP warning was being displayed for some undefined indexes (thank you, [mark_kay](https://wordpress.org/support/topic/error-with-new-plug-in-update?replies=29#post-6948972))
|
165 |
-
|
166 |
-
= 4.0.1 =
|
167 |
-
* [Note] Version 4.0 had a bumpy start, but that's expected when something radically new is released to the public. We thank you for your patience while we addressed the bugs that didn't surface during our tests.
|
168 |
-
* [Note] Make sure to uninstall the Dashboard Widgets add-on before upgrading to Slimstat 4.0, or you might get a white screen of death. If this is the case, please remove the folder wp-content/plugins/wp-slimstat-dashboard-widgets via FTP. You will not lose your data.
|
169 |
-
* [New] Say hello to your new Dashboard Widgets. We decided to merge our free add-on into the main plugin: this way you don't have to deal with a separate software, our update cycle is streamlined, and performance increases. You can always deactivate this integration by using the corresponding option under Settings > General.
|
170 |
-
* [Fix] A few people pointed out a Unexpected T_FUNCTION parse error. Slimstat officially requires PHP 5.3 to function properly. Nevertheless, we implemented a workaround so that people with PHP 5.2 can still enjoy all the power of our plugin. Thank you for your patience.
|
171 |
-
* [Fix] MySQL Error 121 was preventing the plugin from creating the new table structure, if MySQL was configured to work in strict mode (thank you, [wvploeg](https://wordpress.org/support/topic/after-update-it-stopped-working?replies=6))
|
172 |
-
* [Fix] If you compile PHP with certain flags on Ubuntu, gzopen is not available (thank you, [larryisthere](https://wordpress.org/support/topic/geolite-db-installation-issue-on-ubuntu-trusty?replies=2))
|
173 |
-
|
174 |
-
= 4.0 =
|
175 |
-
* [Note] A brave new world is now ready to be explored: Slimstat 4.0. This version introduces a totally redesigned database architecture, new streamlined tracking code, new heuristic user agent parser, new filters and much more. You will surely notice the performance improvements!
|
176 |
-
* [Note] Our dev team should have read [this article](http://blog.codinghorror.com/maybe-normalizing-isnt-normal/) a long time ago. But it's never too late, and we can guarantee you that the new denormalized table structure will make your report generation so quick that your jaw will drop. Sure, the table size will increase 50%, but in the age where space is cheap, the real precious resource is time. The time you won't have to wait for your report to appear!
|
177 |
-
* [Note] Upon update, Slimstat will convert the old table structure to the new one. Just to stay on the safe side, the old tables will not be removed (wp_slim_stats will be renamed to wp_slim_stats_3). After a transition period, we will offer the option to remove the old tables with a button in the settings.
|
178 |
-
* [Note] Please make sure that your MySQL user can issue a RENAME command.
|
179 |
-
* [Note] We are now working on our premium add-ons to make them compatible with Slimstat 4.0. Some of them might stop working until a new update is available.
|
180 |
-
* [New] MaxMind upload folder path can now be filtered (thank you, [chrisl27](https://wordpress.org/support/topic/filter-for-maxmind-path)).
|
181 |
-
* [New] The new tracker is measuring both the screen resolution and the viewport size. [Here](http://www.quirksmode.org/mobile/viewports.html) you can find more information on this topic.
|
182 |
-
* [New] The library wp-slimstat-db.php has been cleaned up and reorganized (20% smaller!). Please note: some of the function signatures have changed (order of parameters), please update your custom code accordingly or contact us for more information.
|
183 |
-
* [New] Internal downloads are now tracked as regular pageviews, with content_type = download. This allows to make our filters more intuitive and our reports faster.
|
184 |
-
* [New] The table wp_slim_events will now store all the information regarding events happening on your pages (including the coordinates of clicks for the heatmap).
|
185 |
-
* [New] Inline data attributes on links will tell you right away if an external URL will be tracked or not.
|
186 |
-
* [New] Custom reports can now be added to ANY screen, and soon you will be able to move any built-in report to any screen.
|
187 |
-
* [Update] We are making our source code easier to read, by applying some well established best practices about indentation, spacing and variable names.
|
188 |
-
* [Update] Removed the chart Average Pageviews per Visit, which required a complex SQL query to be generated, and didn't convey any key information, according to a quick survey we had among some of our users.
|
189 |
-
* [Update] The Spy View report under the Overview tab has been merged with the Real-Time log, since users were pointing out that it was confusing to have two separate reports displaying pretty much the same information.
|
190 |
-
* [Update] We decided to hide some reports under the Site Analysis tab by default. They are not gone, and can be quickly activated by enabling the corresponding checkbox under Screen Options.
|
191 |
-
* [Update] The browser CSS version is not tracked anymore.
|
192 |
-
* [Update] Google+1 clicks are not tracked/supported anymore.
|
193 |
-
* [Update] Vitaly has sent us the latest version of the Russian localization. Way to go!
|
194 |
-
* [Fix] Implemented a more robust fix for the issue with download_url throwing an undefined function error (this is supposed to be part of [WP Core](https://codex.wordpress.org/Function_Reference/download_url)!)
|
195 |
-
* [Fix] When dragging boxes around, the placeholder was not being displayed in the right place.
|
196 |
-
|
197 |
== Special Thanks To ==
|
198 |
|
199 |
* [Vitaly](http://www.visbiz.org/), who volunteers quite a lot of time for QA, testing, and for his Russian localization.
|
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.3
|
7 |
+
Stable tag: 4.1.6.1
|
8 |
|
9 |
== Description ==
|
10 |
[youtube https://www.youtube.com/watch?v=iJCtjxArq4U]
|
22 |
* 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)
|
23 |
* Read all the [reviews](http://wordpress.org/support/view/plugin-reviews/wp-slimstat) and feel free to post your own!
|
24 |
|
25 |
+
= Minimum Requirements =
|
26 |
+
* WordPress 3.8
|
27 |
+
* PHP 5.3
|
28 |
+
* MySQL 5.0.3
|
29 |
+
* 25 MB of free space on your filesystem
|
30 |
+
* 5 MB of free DB space
|
31 |
+
* 10 Mb of free PHP memory for the tracker (peak memory usage)
|
32 |
* IE9+ or any browser supporting HTML5, to access the reports
|
33 |
|
34 |
= Premium Add-ons =
|
59 |
|
60 |
== Changelog ==
|
61 |
|
62 |
+
= 4.1.6.1 =
|
63 |
+
* [New] Contextual counters are now added not just to pages and posts, but to other custom post types available on your website.
|
64 |
+
* [Update] Optimized SQL query that retrieves the data for the Access Log report.
|
65 |
+
* [Update] New link for GetSocial.io partnership.
|
66 |
+
* [Fix] Patched a remote XSS vulnerability related to forged referrer URLs.
|
67 |
+
* [Fix] Bug in refreshing Access Log (second try).
|
68 |
+
* [Fix] Bug in calculating Unique IP counters for pages and posts.
|
69 |
+
* [Fix] Link to install the GeoLocation DB was pointing to the wrong tab under Settings.
|
70 |
+
* [Fix] When selecting the filter in Overview > Top Pages, reports were returning empty datasets.
|
71 |
+
* [Fix] Resetting the report layout was not always working as expected, if Slimstat was displayed in the admin bar.
|
72 |
+
|
73 |
= 4.1.6 =
|
74 |
* [New] Administrators can now set the maximum number of records that should be retrieved from the database when generating the reports (Settings > Reports). This allows those with powerful servers and unlimited PHP resources to increase this limit and get a more accurate picture of their visitors.
|
75 |
* [New] Extended the export functionality (via our premium Export to Excel add-on) to reports like At a Glance, Rankings, Audience Overview, etc (thank you, Tiffany).
|
169 |
* [Fix] In Client Mode (aka Javascript mode), all page content types were being set to 'admin', under certain circumstances.
|
170 |
* [Fix] THe uninstall script was not removing the 'old' tables (wp_slim_stats_3, wp_slim_stats_archive_3).
|
171 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
== Special Thanks To ==
|
173 |
|
174 |
* [Vitaly](http://www.visbiz.org/), who volunteers quite a lot of time for QA, testing, and for his Russian localization.
|
wp-slimstat.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: WP Slimstat
|
4 |
Plugin URI: http://wordpress.org/plugins/wp-slimstat/
|
5 |
Description: The leading web analytics plugin for WordPress
|
6 |
-
Version: 4.1.6
|
7 |
Author: Camu
|
8 |
Author URI: http://www.wp-slimstat.com/
|
9 |
*/
|
@@ -11,7 +11,7 @@ Author URI: http://www.wp-slimstat.com/
|
|
11 |
if ( !empty( wp_slimstat::$options ) ) return true;
|
12 |
|
13 |
class wp_slimstat {
|
14 |
-
public static $version = '4.1.6';
|
15 |
public static $options = array();
|
16 |
|
17 |
public static $wpdb = '';
|
@@ -32,6 +32,13 @@ class wp_slimstat {
|
|
32 |
|
33 |
// Load all the settings
|
34 |
self::$options = ( is_network_admin() && ( empty($_GET[ 'page' ] ) || strpos( $_GET[ 'page' ], 'wp-slim-view' ) === false ) ) ? get_site_option( 'slimstat_options', array() ) : get_option( 'slimstat_options', array() );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
self::$options = array_merge( self::init_options(), self::$options );
|
36 |
|
37 |
// Allow third party tools to edit the options
|
@@ -1457,13 +1464,13 @@ class wp_slimstat {
|
|
1457 |
*/
|
1458 |
public static function init_options(){
|
1459 |
$val_yes = 'yes'; $val_no = 'no';
|
1460 |
-
if (is_network_admin() && (empty($_GET['page']) || strpos($_GET['page'], 'wp-slim-view') === false)){
|
1461 |
$val_yes = $val_no = 'null';
|
1462 |
}
|
1463 |
|
1464 |
$options = array(
|
1465 |
'version' => self::$version,
|
1466 |
-
'secret' => wp_hash(uniqid(time(), true)),
|
1467 |
'show_admin_notice' => 0,
|
1468 |
|
1469 |
// General
|
@@ -1482,18 +1489,17 @@ class wp_slimstat {
|
|
1482 |
|
1483 |
// Views
|
1484 |
'use_european_separators' => $val_yes,
|
1485 |
-
'date_format' => ($val_yes == 'null')?'':'m-d-y',
|
1486 |
-
'time_format' => ($val_yes == 'null')?'':'h:i a',
|
1487 |
'show_display_name' => $val_no,
|
1488 |
'convert_resource_urls_to_titles' => $val_yes,
|
1489 |
'convert_ip_addresses' => $val_no,
|
1490 |
'use_slimscroll' => $val_yes,
|
1491 |
'expand_details' => $val_no,
|
1492 |
-
'rows_to_show' => ($val_yes == 'null')?'0':'20',
|
1493 |
-
'limit_results' => ($val_yes == 'null')?'0':'
|
1494 |
-
'refresh_interval' => ($val_yes == 'null')?'0':'60',
|
1495 |
-
'number_results_raw_data' => ($val_yes == 'null')?'0':'50',
|
1496 |
-
// 'include_outbound_links_right_now' => $val_yes,
|
1497 |
'show_complete_user_agent_tooltip' => $val_no,
|
1498 |
'no_maxmind_warning' => $val_no,
|
1499 |
'enable_sov' => $val_no,
|
@@ -1519,9 +1525,9 @@ class wp_slimstat {
|
|
1519 |
|
1520 |
// Permissions
|
1521 |
'restrict_authors_view' => $val_yes,
|
1522 |
-
'capability_can_view' => ($val_yes == 'null')?'':'activate_plugins',
|
1523 |
'can_view' => '',
|
1524 |
-
'capability_can_admin' => ($val_yes == 'null')?'':'activate_plugins',
|
1525 |
'can_admin' => '',
|
1526 |
|
1527 |
// Advanced
|
3 |
Plugin Name: WP Slimstat
|
4 |
Plugin URI: http://wordpress.org/plugins/wp-slimstat/
|
5 |
Description: The leading web analytics plugin for WordPress
|
6 |
+
Version: 4.1.6.1
|
7 |
Author: Camu
|
8 |
Author URI: http://www.wp-slimstat.com/
|
9 |
*/
|
11 |
if ( !empty( wp_slimstat::$options ) ) return true;
|
12 |
|
13 |
class wp_slimstat {
|
14 |
+
public static $version = '4.1.6.1';
|
15 |
public static $options = array();
|
16 |
|
17 |
public static $wpdb = '';
|
32 |
|
33 |
// Load all the settings
|
34 |
self::$options = ( is_network_admin() && ( empty($_GET[ 'page' ] ) || strpos( $_GET[ 'page' ], 'wp-slim-view' ) === false ) ) ? get_site_option( 'slimstat_options', array() ) : get_option( 'slimstat_options', array() );
|
35 |
+
|
36 |
+
// If no settings were found, we might be in the Network Admin with no "Network View" add-on enabled
|
37 |
+
if ( empty( self::$options ) && is_network_admin() ) {
|
38 |
+
self::$options = get_blog_option( 1, 'slimstat_options', array() );
|
39 |
+
}
|
40 |
+
|
41 |
+
// Initialize the options, if needed
|
42 |
self::$options = array_merge( self::init_options(), self::$options );
|
43 |
|
44 |
// Allow third party tools to edit the options
|
1464 |
*/
|
1465 |
public static function init_options(){
|
1466 |
$val_yes = 'yes'; $val_no = 'no';
|
1467 |
+
if ( is_network_admin() && ( empty( $_GET[ 'page' ] ) || strpos( $_GET[ 'page' ], 'wp-slim-view' ) === false ) ) {
|
1468 |
$val_yes = $val_no = 'null';
|
1469 |
}
|
1470 |
|
1471 |
$options = array(
|
1472 |
'version' => self::$version,
|
1473 |
+
'secret' => wp_hash( uniqid( time(), true ) ),
|
1474 |
'show_admin_notice' => 0,
|
1475 |
|
1476 |
// General
|
1489 |
|
1490 |
// Views
|
1491 |
'use_european_separators' => $val_yes,
|
1492 |
+
'date_format' => ( $val_yes == 'null' ) ? '' : 'm-d-y',
|
1493 |
+
'time_format' => ( $val_yes == 'null' ) ? '' : 'h:i a',
|
1494 |
'show_display_name' => $val_no,
|
1495 |
'convert_resource_urls_to_titles' => $val_yes,
|
1496 |
'convert_ip_addresses' => $val_no,
|
1497 |
'use_slimscroll' => $val_yes,
|
1498 |
'expand_details' => $val_no,
|
1499 |
+
'rows_to_show' => ( $val_yes == 'null' ) ? '0' : '20',
|
1500 |
+
'limit_results' => ( $val_yes == 'null' ) ? '0' : '1000',
|
1501 |
+
'refresh_interval' => ( $val_yes == 'null' ) ? '0' : '60',
|
1502 |
+
'number_results_raw_data' => ( $val_yes == 'null' ) ? '0' : '50',
|
|
|
1503 |
'show_complete_user_agent_tooltip' => $val_no,
|
1504 |
'no_maxmind_warning' => $val_no,
|
1505 |
'enable_sov' => $val_no,
|
1525 |
|
1526 |
// Permissions
|
1527 |
'restrict_authors_view' => $val_yes,
|
1528 |
+
'capability_can_view' => ( $val_yes == 'null' ) ? '' : 'activate_plugins',
|
1529 |
'can_view' => '',
|
1530 |
+
'capability_can_admin' => ( $val_yes == 'null' ) ? '' : 'activate_plugins',
|
1531 |
'can_admin' => '',
|
1532 |
|
1533 |
// Advanced
|