Version Description
- [Note] The URL of the CDN has changed, and is now using the official WordPress repository as a source: cdn.jsdelivr.net/wp/wp-slimstat/trunk/wp-slimstat.js - Please update your "external" tracking codes accordingly.
- [Note] The structure of the array wp_slimstat_db::$sql_filters has changed! Please make sure to update your custom code accordingly. Feel free to contact us for more information.
- [New] The wait is over. Our heatmap add-on is finally available on our store! We would like to thank all those who provided helpful feedback to improve this initial release!
- [New] Our knowledge base has been extended with a list of all the actions and filters available in Slimstat.
- [Fix] The Add-on update checker had a bug preventing the functionality to work as expected. Please make sure to get the latest version of your premium add-ons!
- [Fix] Date intervals were not accurate because of a bug related to calculating timezones in MySQL (thank you, Chrisssssi).
- [Fix] Line height of report rows has been added to avoid conflicts with other plugins tweaking this parameter in the admin (thank you, yk11).
Download this release
Release Info
Developer | coolmann |
Plugin | Slimstat Analytics |
Version | 3.9.4 |
Comparing to | |
See all releases |
Code changes from version 3.9.3 to 3.9.4
- admin/config/addons.php +14 -5
- admin/config/index.php +2 -3
- admin/css/slimstat.css +1 -0
- admin/view/index.php +3 -0
- admin/view/wp-slimstat-db.php +121 -135
- admin/view/wp-slimstat-reports.php +4 -4
- admin/wp-slimstat-admin.php +8 -4
- readme.txt +11 -2
- wp-slimstat.php +3 -4
admin/config/addons.php
CHANGED
@@ -7,14 +7,16 @@ if (!empty($_POST['licenses'])){
|
|
7 |
wp_slimstat::$options['addon_licenses'] = $_POST['licenses'];
|
8 |
}
|
9 |
|
10 |
-
|
|
|
11 |
$response = wp_remote_get('http://slimstat.getused.to.it/update-checker/', array('headers' => array('referer' => get_site_url())));
|
12 |
if(is_wp_error($response) || $response['response']['code'] != 200){
|
13 |
$error_message = is_wp_error($response)?$response->get_error_message():$response['response']['code'].' '. $response['response']['message'];
|
14 |
echo '<p>'.__('There was an error retrieving the add-ons list from the server. Please try again later. Error Message:','wp-slimstat').' '.$error_message.'</p></div>';
|
15 |
return;
|
16 |
}
|
17 |
-
|
|
|
18 |
}
|
19 |
|
20 |
$license_key_field = false;
|
@@ -27,7 +29,14 @@ if (!is_array($list_addons)){
|
|
27 |
|
28 |
<div class="wrap slimstat">
|
29 |
<h2><?php _e('Add-ons','wp-slimstat') ?></h2>
|
30 |
-
<p><?php _e('Add-ons extend the functionality of Slimstat in many interesting ways. We offer both free and premium (paid) extensions. Each add-on can be installed as a separate plugin, which will receive regular updates via the WordPress Plugins panel. In order to be notified when a new version of a premium add-on is available, please enter the <strong>license key</strong> you received when you purchased it.','wp-slimstat')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
|
32 |
<form method="post" id="form-slimstat-options-tab-addons">
|
33 |
<table class="wp-list-table widefat plugins slimstat-addons" cellspacing="0">
|
@@ -44,10 +53,10 @@ if (!is_array($list_addons)){
|
|
44 |
<strong><a target="_blank" href="<?php echo $a_addon['download_url'] ?>"><?php echo $a_addon['name'] ?></a></strong>
|
45 |
<div class="row-actions-visible"><?php
|
46 |
if (is_plugin_active($a_addon['slug'].'/index.php') || is_plugin_active($a_addon['slug'].'/'.$a_addon['slug'].'.php')){
|
47 |
-
echo 'Version '.$a_addon['version'].'<br/>Installed and Active';
|
48 |
}
|
49 |
else{
|
50 |
-
echo 'Version '.$a_addon['version'].'<br/>Price: '.(is_numeric($a_addon['price'])?'$'.$a_addon['price']:$a_addon['price']);
|
51 |
} ?>
|
52 |
</div>
|
53 |
</th>
|
7 |
wp_slimstat::$options['addon_licenses'] = $_POST['licenses'];
|
8 |
}
|
9 |
|
10 |
+
$response = get_transient('wp_slimstat_addon_list');
|
11 |
+
if (!empty($_GET['force_refresh']) || false === $response){
|
12 |
$response = wp_remote_get('http://slimstat.getused.to.it/update-checker/', array('headers' => array('referer' => get_site_url())));
|
13 |
if(is_wp_error($response) || $response['response']['code'] != 200){
|
14 |
$error_message = is_wp_error($response)?$response->get_error_message():$response['response']['code'].' '. $response['response']['message'];
|
15 |
echo '<p>'.__('There was an error retrieving the add-ons list from the server. Please try again later. Error Message:','wp-slimstat').' '.$error_message.'</p></div>';
|
16 |
return;
|
17 |
}
|
18 |
+
|
19 |
+
set_transient('wp_slimstat_addon_list', $response, 86400);
|
20 |
}
|
21 |
|
22 |
$license_key_field = false;
|
29 |
|
30 |
<div class="wrap slimstat">
|
31 |
<h2><?php _e('Add-ons','wp-slimstat') ?></h2>
|
32 |
+
<p><?php _e('Add-ons extend the functionality of Slimstat in many interesting ways. We offer both free and premium (paid) extensions. Each add-on can be installed as a separate plugin, which will receive regular updates via the WordPress Plugins panel. In order to be notified when a new version of a premium add-on is available, please enter the <strong>license key</strong> you received when you purchased it.','wp-slimstat') ?>
|
33 |
+
<?php
|
34 |
+
if (empty($_GET['force_refresh'])){
|
35 |
+
|
36 |
+
printf(__('This list is cached daily on your server: <a href="%s&force_refresh=true">click here</a> to clear the cache.','wp-slimstat'), $_SERVER['REQUEST_URI']);
|
37 |
+
}
|
38 |
+
?>
|
39 |
+
</p>
|
40 |
|
41 |
<form method="post" id="form-slimstat-options-tab-addons">
|
42 |
<table class="wp-list-table widefat plugins slimstat-addons" cellspacing="0">
|
53 |
<strong><a target="_blank" href="<?php echo $a_addon['download_url'] ?>"><?php echo $a_addon['name'] ?></a></strong>
|
54 |
<div class="row-actions-visible"><?php
|
55 |
if (is_plugin_active($a_addon['slug'].'/index.php') || is_plugin_active($a_addon['slug'].'/'.$a_addon['slug'].'.php')){
|
56 |
+
echo 'Latest Version: '.$a_addon['version'].'<br/>Installed and Active';
|
57 |
}
|
58 |
else{
|
59 |
+
echo 'Latest Version: '.$a_addon['version'].'<br/>Price: '.(is_numeric($a_addon['price'])?'$'.$a_addon['price']:$a_addon['price']);
|
60 |
} ?>
|
61 |
</div>
|
62 |
</th>
|
admin/config/index.php
CHANGED
@@ -47,7 +47,6 @@ switch ($config_tabs[$current_tab-1]){
|
|
47 |
'views_basic_header' => array('description' => __('Data and Formats','wp-slimstat'), 'type' => 'section_header'),
|
48 |
'convert_ip_addresses' => array('description' => __('Convert IP Addresses','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Display provider names instead of IP addresses.','wp-slimstat')),
|
49 |
'use_european_separators' => array('description' => __('Number Format','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Choose the number format you want to use for your reports.','wp-slimstat'), 'custom_label_yes' => '1.234,56', 'custom_label_no' => '1,234.56'),
|
50 |
-
'reset_timezone' => array('description' => __('Reset Timezone','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Enable this option if your DB server and your web site use different timezones.','wp-slimstat')),
|
51 |
'enable_sov' => array('description' => __('Enable SOV','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('In linguistic typology, a subject-object-verb (SOV) language is one in which the subject, object, and verb of a sentence appear in that order, like in Japanese.','wp-slimstat')),
|
52 |
'show_display_name' => array('description' => __('Show Display Name','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('By default, users are listed by their usernames. Use this option to visualize their display names instead.','wp-slimstat')),
|
53 |
'show_complete_user_agent_tooltip' => array('description' => __('Show User Agent','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Choose if you want to see the browser name or a complete user agent string when hovering on browser icons.','wp-slimstat')),
|
@@ -241,12 +240,12 @@ var SlimStatParams = {
|
|
241 |
};
|
242 |
/* ]]> */
|
243 |
</script>
|
244 |
-
<script type="text/javascript" src="http://cdn.jsdelivr.net/wp-slimstat/
|
245 |
|
246 |
'advanced_misc_header' => array('description' => __('Miscellaneous','wp-slimstat'), 'type' => 'section_header'),
|
247 |
'show_sql_debug' => array('description' => __('Debug Mode','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Display the SQL queries used to retrieve the data.','wp-slimstat')),
|
248 |
'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')),
|
249 |
-
'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='
|
250 |
'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'))
|
251 |
);
|
252 |
break;
|
47 |
'views_basic_header' => array('description' => __('Data and Formats','wp-slimstat'), 'type' => 'section_header'),
|
48 |
'convert_ip_addresses' => array('description' => __('Convert IP Addresses','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Display provider names instead of IP addresses.','wp-slimstat')),
|
49 |
'use_european_separators' => array('description' => __('Number Format','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Choose the number format you want to use for your reports.','wp-slimstat'), 'custom_label_yes' => '1.234,56', 'custom_label_no' => '1,234.56'),
|
|
|
50 |
'enable_sov' => array('description' => __('Enable SOV','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('In linguistic typology, a subject-object-verb (SOV) language is one in which the subject, object, and verb of a sentence appear in that order, like in Japanese.','wp-slimstat')),
|
51 |
'show_display_name' => array('description' => __('Show Display Name','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('By default, users are listed by their usernames. Use this option to visualize their display names instead.','wp-slimstat')),
|
52 |
'show_complete_user_agent_tooltip' => array('description' => __('Show User Agent','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Choose if you want to see the browser name or a complete user agent string when hovering on browser icons.','wp-slimstat')),
|
240 |
};
|
241 |
/* ]]> */
|
242 |
</script>
|
243 |
+
<script type="text/javascript" src="http://cdn.jsdelivr.net/wp/wp-slimstat/trunk/wp-slimstat.js"></script>'),
|
244 |
|
245 |
'advanced_misc_header' => array('description' => __('Miscellaneous','wp-slimstat'), 'type' => 'section_header'),
|
246 |
'show_sql_debug' => array('description' => __('Debug Mode','wp-slimstat'), 'type' => 'yesno', 'long_description' => __('Display the SQL queries used to retrieve the data.','wp-slimstat')),
|
247 |
'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')),
|
248 |
+
'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')),
|
249 |
'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'))
|
250 |
);
|
251 |
break;
|
admin/css/slimstat.css
CHANGED
@@ -198,6 +198,7 @@
|
|
198 |
[id^=slim_] p{
|
199 |
border-bottom: 1px solid #ddd;
|
200 |
font-weight: 300;
|
|
|
201 |
margin: 0;
|
202 |
min-height: 20px;
|
203 |
overflow: auto;
|
198 |
[id^=slim_] p{
|
199 |
border-bottom: 1px solid #ddd;
|
200 |
font-weight: 300;
|
201 |
+
line-height: 1.5;
|
202 |
margin: 0;
|
203 |
min-height: 20px;
|
204 |
overflow: auto;
|
admin/view/index.php
CHANGED
@@ -188,6 +188,9 @@
|
|
188 |
case 'slim_p2_01':
|
189 |
wp_slimstat_reports::report_header($a_box_id, 'wide chart', wp_slimstat_reports::$chart_tooltip, wp_slimstat_reports::chart_title(__('Human Visits', 'wp-slimstat')));
|
190 |
break;
|
|
|
|
|
|
|
191 |
case 'slim_p2_05':
|
192 |
wp_slimstat_reports::report_header($a_box_id, 'wide', __('Internet Service Provider: a company which provides other companies or individuals with access to the Internet. Your DSL or cable internet service is provided to you by your ISP.<br><br>You can ignore specific IP addresses by setting the corresponding filter under Settings > Slimstat > Filters.','wp-slimstat'));
|
193 |
break;
|
188 |
case 'slim_p2_01':
|
189 |
wp_slimstat_reports::report_header($a_box_id, 'wide chart', wp_slimstat_reports::$chart_tooltip, wp_slimstat_reports::chart_title(__('Human Visits', 'wp-slimstat')));
|
190 |
break;
|
191 |
+
case 'slim_p2_02':
|
192 |
+
wp_slimstat_reports::report_header($a_box_id, 'normal', __('Where not otherwise specified, the metrics in this report are referred to human visitors.','wp-slimstat'));
|
193 |
+
break;
|
194 |
case 'slim_p2_05':
|
195 |
wp_slimstat_reports::report_header($a_box_id, 'wide', __('Internet Service Provider: a company which provides other companies or individuals with access to the Internet. Your DSL or cable internet service is provided to you by your ISP.<br><br>You can ignore specific IP addresses by setting the corresponding filter under Settings > Slimstat > Filters.','wp-slimstat'));
|
196 |
break;
|
admin/view/wp-slimstat-db.php
CHANGED
@@ -16,13 +16,6 @@ class wp_slimstat_db {
|
|
16 |
* Initializes the environment, sets the filters
|
17 |
*/
|
18 |
public static function init($_filters = ''){
|
19 |
-
// Reset MySQL timezone settings, our dates and times are recorded using WP settings
|
20 |
-
|
21 |
-
if (wp_slimstat::$options['reset_timezone'] == 'yes'){
|
22 |
-
wp_slimstat::$wpdb->query("SET @@session.time_zone = '+00:00'");
|
23 |
-
date_default_timezone_set('UTC');
|
24 |
-
}
|
25 |
-
|
26 |
// Decimal and thousand separators
|
27 |
if (wp_slimstat::$options['use_european_separators'] == 'no'){
|
28 |
self::$formats['decimal'] = '.';
|
@@ -103,7 +96,6 @@ class wp_slimstat_db {
|
|
103 |
}
|
104 |
|
105 |
if (empty(self::$filters_normalized['date']['interval']) && empty(self::$filters_normalized['date']['interval_hours']) && empty(self::$filters_normalized['date']['interval_minutes'])){
|
106 |
-
|
107 |
if (!empty(self::$filters_normalized['date']['minute'])){
|
108 |
self::$filters_normalized['utime']['start'] = mktime(
|
109 |
!empty(self::$filters_normalized['date']['hour'])?self::$filters_normalized['date']['hour']:0,
|
@@ -167,27 +159,25 @@ class wp_slimstat_db {
|
|
167 |
self::$filters_normalized['utime']['type'] = 'interval';
|
168 |
|
169 |
self::$filters_normalized['utime']['start'] = mktime(
|
170 |
-
!empty(self::$filters_normalized['date']['hour'])?self::$filters_normalized['date']['hour']:
|
171 |
-
!empty(self::$filters_normalized['date']['minute'])?self::$filters_normalized['date']['minute']:
|
172 |
0,
|
173 |
!empty(self::$filters_normalized['date']['month'])?self::$filters_normalized['date']['month']:date_i18n('n'),
|
174 |
!empty(self::$filters_normalized['date']['day'])?self::$filters_normalized['date']['day']:date_i18n('j'),
|
175 |
!empty(self::$filters_normalized['date']['year'])?self::$filters_normalized['date']['year']:date_i18n('Y')
|
176 |
);
|
177 |
-
|
178 |
$sign = (self::$filters_normalized['date']['interval_direction'] == 'plus')?'+':'-';
|
179 |
|
180 |
-
self::$filters_normalized['utime']['end'] =
|
181 |
-
|
182 |
-
(!empty(self::$filters_normalized['date']['
|
183 |
-
(!empty(self::$filters_normalized['date']['
|
184 |
-
|
185 |
-
).' minutes', self::$filters_normalized['utime']['start'])
|
186 |
-
);
|
187 |
|
188 |
// Swap boundaries if we're going back
|
189 |
if (self::$filters_normalized['date']['interval_direction'] == 'minus'){
|
190 |
-
list(self::$filters_normalized['utime']['start'], self::$filters_normalized['utime']['end']) = array(self::$filters_normalized['utime']['end'], self::$filters_normalized['utime']['start']);
|
191 |
}
|
192 |
}
|
193 |
|
@@ -216,43 +206,57 @@ class wp_slimstat_db {
|
|
216 |
}
|
217 |
}
|
218 |
|
219 |
-
// Now let's translate our filters into SQL
|
220 |
self::$sql_filters = array(
|
221 |
'from' => array(
|
222 |
-
'
|
223 |
-
'
|
224 |
-
'
|
225 |
-
'
|
226 |
-
|
227 |
-
'
|
|
|
228 |
),
|
229 |
-
|
230 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
231 |
);
|
232 |
|
233 |
foreach (self::$filters_normalized['columns'] as $a_filter_column => $a_filter_data){
|
234 |
-
$a_filter_empty = '0';
|
235 |
-
|
236 |
// Add-ons can set their own custom filters, which are ignored here
|
237 |
if (strpos($a_filter_column, 'addon_') !== false){
|
238 |
continue;
|
239 |
}
|
240 |
|
|
|
|
|
|
|
|
|
|
|
241 |
// Some columns are in separate tables, so we need to join them
|
242 |
-
switch (
|
243 |
-
case 'tb
|
244 |
-
self::$sql_filters['from'][
|
245 |
break;
|
246 |
-
case 'tci
|
247 |
-
self::$sql_filters['from'][
|
248 |
break;
|
249 |
-
case '
|
250 |
-
self::$sql_filters['from'][
|
251 |
break;
|
252 |
-
case '
|
253 |
-
self::$sql_filters['from'][
|
254 |
break;
|
255 |
default:
|
|
|
256 |
}
|
257 |
|
258 |
// Some columns require a special treatment
|
@@ -260,70 +264,73 @@ class wp_slimstat_db {
|
|
260 |
case 'ip':
|
261 |
case 'other_ip':
|
262 |
$a_filter_column = "INET_NTOA($a_filter_column)";
|
263 |
-
$
|
264 |
break;
|
265 |
default:
|
266 |
-
$a_filter_column =
|
267 |
break;
|
268 |
}
|
269 |
|
270 |
switch ($a_filter_data[0]){
|
271 |
case 'is_not_equal_to':
|
272 |
-
self::$sql_filters['where'] .= $GLOBALS['wpdb']->prepare(" AND $a_filter_column <> %s", $a_filter_data[1]);
|
273 |
break;
|
274 |
case 'contains':
|
275 |
-
self::$sql_filters['where'] .= $GLOBALS['wpdb']->prepare(" AND $a_filter_column LIKE %s", '%'.$a_filter_data[1].'%');
|
276 |
break;
|
277 |
case 'includes_in_set':
|
278 |
-
self::$sql_filters['where'] .= $GLOBALS['wpdb']->prepare(" AND FIND_IN_SET(%s, $a_filter_column) > 0", $a_filter_data[1]);
|
279 |
break;
|
280 |
case 'does_not_contain':
|
281 |
-
self::$sql_filters['where'] .= $GLOBALS['wpdb']->prepare(" AND $a_filter_column NOT LIKE %s", '%'.$a_filter_data[1].'%');;
|
282 |
break;
|
283 |
case 'starts_with':
|
284 |
-
self::$sql_filters['where'] .= $GLOBALS['wpdb']->prepare(" AND $a_filter_column LIKE %s", $a_filter_data[1].'%');
|
285 |
break;
|
286 |
case 'ends_with':
|
287 |
-
self::$sql_filters['where'] .= $GLOBALS['wpdb']->prepare(" AND $a_filter_column LIKE %s", '%'.$a_filter_data[1]);
|
288 |
break;
|
289 |
case 'sounds_like':
|
290 |
-
self::$sql_filters['where'] .= $GLOBALS['wpdb']->prepare(" AND SOUNDEX($a_filter_column) = SOUNDEX(%s)", $a_filter_data[1]);
|
291 |
break;
|
292 |
case 'is_empty':
|
293 |
-
self::$sql_filters['where'] .= " AND ($a_filter_column = '' OR $a_filter_column = '$
|
294 |
break;
|
295 |
case 'is_not_empty':
|
296 |
-
self::$sql_filters['where'] .= " AND $a_filter_column <> '' AND $a_filter_column <> '$
|
297 |
break;
|
298 |
case 'is_greater_than':
|
299 |
-
self::$sql_filters['where'] .= $GLOBALS['wpdb']->prepare(" AND $a_filter_column > %
|
300 |
break;
|
301 |
case 'is_less_than':
|
302 |
-
self::$sql_filters['where'] .= $GLOBALS['wpdb']->prepare(" AND $a_filter_column < %
|
303 |
break;
|
304 |
case 'between':
|
305 |
$range = explode(',', $a_filter_data[1]);
|
306 |
-
self::$sql_filters['where'] .= $GLOBALS['wpdb']->prepare(" AND $a_filter_column BETWEEN %
|
307 |
break;
|
308 |
case 'matches':
|
309 |
-
self::$sql_filters['where'] .= $GLOBALS['wpdb']->prepare(" AND $a_filter_column REGEXP %s", $a_filter_data[1]);
|
310 |
break;
|
311 |
case 'does_not_match':
|
312 |
-
self::$sql_filters['where'] .= $GLOBALS['wpdb']->prepare(" AND $a_filter_column NOT REGEXP %s", $a_filter_data[1]);
|
313 |
break;
|
314 |
default:
|
315 |
-
self::$sql_filters['where'] .= $GLOBALS['wpdb']->prepare(" AND $a_filter_column = %s", $a_filter_data[1]);
|
316 |
}
|
317 |
}
|
318 |
-
|
319 |
-
self::$sql_filters['from']['
|
|
|
|
|
|
|
320 |
}
|
321 |
// end init
|
322 |
|
323 |
/**
|
324 |
* Associates tables and their 'SQL aliases'
|
325 |
*/
|
326 |
-
public static function
|
327 |
switch($_field){
|
328 |
case 'browser':
|
329 |
case 'version':
|
@@ -331,29 +338,29 @@ class wp_slimstat_db {
|
|
331 |
case 'type':
|
332 |
case 'platform':
|
333 |
case 'user_agent':
|
334 |
-
return 'tb
|
335 |
break;
|
336 |
case 'resolution':
|
337 |
case 'colordepth':
|
338 |
-
return 'tss
|
339 |
break;
|
340 |
case 'author':
|
341 |
case 'category':
|
342 |
case 'content_type':
|
343 |
case 'content_id':
|
344 |
-
return 'tci
|
345 |
break;
|
346 |
case 'outbound_domain':
|
347 |
case 'outbound_resource':
|
348 |
case 'position':
|
349 |
-
return 'tob
|
350 |
break;
|
351 |
default:
|
352 |
-
return 't1
|
353 |
break;
|
354 |
}
|
355 |
}
|
356 |
-
// end
|
357 |
|
358 |
// The following methods retrieve the information from the database
|
359 |
|
@@ -362,8 +369,8 @@ class wp_slimstat_db {
|
|
362 |
SELECT COUNT(*) counthits
|
363 |
FROM (
|
364 |
SELECT t1.resource
|
365 |
-
FROM '.self::$sql_filters['from']['
|
366 |
-
WHERE t1.visit_id <> 0 AND t1.resource <> "" AND tci.content_type <> "404" '.self::$sql_filters['where'].' '.self::$sql_filters['
|
367 |
GROUP BY visit_id
|
368 |
HAVING COUNT(visit_id) = 1
|
369 |
) as ts1',
|
@@ -375,8 +382,8 @@ class wp_slimstat_db {
|
|
375 |
SELECT COUNT(*) counthits
|
376 |
FROM (
|
377 |
SELECT resource, visit_id, dt
|
378 |
-
FROM '.self::$sql_filters['from']['
|
379 |
-
WHERE visit_id > 0 AND resource <> "" '.self::$sql_filters['where'].' '.self::$sql_filters['
|
380 |
GROUP BY visit_id
|
381 |
HAVING dt = MAX(dt)
|
382 |
) AS ts1',
|
@@ -387,16 +394,16 @@ class wp_slimstat_db {
|
|
387 |
$column = ($_distinct_column != '*')?"DISTINCT $_distinct_column":$_distinct_column;
|
388 |
return intval(self::get_var("
|
389 |
SELECT COUNT($column) counthits
|
390 |
-
FROM {$GLOBALS['wpdb']->prefix}slim_stats t1 ".($_use_filters?self::$sql_filters['from']['
|
391 |
-
WHERE '.(!empty($_where_clause)?$_where_clause:'1=1').' '.($_use_filters?self::$sql_filters['where']:'').' '.($_use_date_filters?self::$sql_filters['
|
392 |
'SUM(counthits) AS counthits'));
|
393 |
}
|
394 |
|
395 |
public static function count_outbound(){
|
396 |
return intval(self::get_var("
|
397 |
SELECT COUNT(outbound_id) counthits
|
398 |
-
FROM {$GLOBALS['wpdb']->prefix}slim_stats t1 INNER JOIN {$GLOBALS['wpdb']->prefix}slim_outbound tob ON t1.id = tob.id ".self::$sql_filters['from']['
|
399 |
-
WHERE 1=1 ".self::$sql_filters['where'].' '.self::$sql_filters['
|
400 |
'SUM(counthits) AS counthits'));
|
401 |
}
|
402 |
|
@@ -404,8 +411,8 @@ class wp_slimstat_db {
|
|
404 |
return intval(self::get_var("
|
405 |
SELECT COUNT(*) counthits FROM (
|
406 |
SELECT $_column
|
407 |
-
FROM ".self::$sql_filters['from']['
|
408 |
-
WHERE $_where_clause ".self::$sql_filters['where'].' '.self::$sql_filters['
|
409 |
GROUP BY $_column
|
410 |
".(!empty($_having_clause)?"HAVING $_having_clause":'').')
|
411 |
AS ts1',
|
@@ -431,8 +438,8 @@ class wp_slimstat_db {
|
|
431 |
return self::get_results('
|
432 |
SELECT AVG(ts1.counthits) AS avghits, MAX(ts1.counthits) AS maxhits FROM (
|
433 |
SELECT count(ip) counthits, visit_id
|
434 |
-
FROM '.self::$sql_filters['from']['
|
435 |
-
WHERE visit_id > 0 '.self::$sql_filters['where'].' '.self::$sql_filters['
|
436 |
GROUP BY visit_id
|
437 |
) AS ts1',
|
438 |
'blog_id',
|
@@ -444,8 +451,8 @@ class wp_slimstat_db {
|
|
444 |
public static function get_oldest_visit($_where_clause = '1=1', $_use_filters = true){
|
445 |
return self::get_var("
|
446 |
SELECT t1.dt
|
447 |
-
FROM {$GLOBALS['wpdb']->prefix}slim_stats t1 ".($_use_filters?self::$sql_filters['from']['
|
448 |
-
WHERE '.(!empty($_where_clause)?$_where_clause:'1=1').' '.($_use_filters?self::$sql_filters['where']:'').'
|
449 |
ORDER BY dt ASC
|
450 |
LIMIT 0,1',
|
451 |
'MIN(dt)');
|
@@ -454,8 +461,8 @@ class wp_slimstat_db {
|
|
454 |
public static function get_popular($_column = 't1.id', $_custom_where = '', $_more_columns = '', $_having_clause = '', $_as_column = ''){
|
455 |
return self::get_results("
|
456 |
SELECT $_column ".(!empty($_as_column)?'AS '.$_as_column:'')." $_more_columns, COUNT(*) counthits
|
457 |
-
FROM ".self::$sql_filters['from']['
|
458 |
-
WHERE '.(empty($_custom_where)?"$_column <> '' ":$_custom_where).' '.self::$sql_filters['where'].' '.self::$sql_filters['
|
459 |
GROUP BY $_column $_more_columns $_having_clause
|
460 |
ORDER BY counthits ".self::$filters_normalized['misc']['direction']."
|
461 |
LIMIT ".self::$filters_normalized['misc']['start_from'].', '.self::$filters_normalized['misc']['limit_results'],
|
@@ -468,8 +475,8 @@ class wp_slimstat_db {
|
|
468 |
public static function get_popular_outbound(){
|
469 |
return self::get_results("
|
470 |
SELECT tob.outbound_resource as resource, COUNT(*) counthits
|
471 |
-
FROM {$GLOBALS['wpdb']->prefix}slim_stats t1 INNER JOIN {$GLOBALS['wpdb']->prefix}slim_outbound tob ON t1.id = tob.id ".self::$sql_filters['from']['
|
472 |
-
WHERE (tob.type = 0 OR tob.type = 1) ".self::$sql_filters['where'].' '.self::$sql_filters['
|
473 |
GROUP BY tob.outbound_resource
|
474 |
ORDER BY counthits '.self::$filters_normalized['misc']['direction'].'
|
475 |
LIMIT '.self::$filters_normalized['misc']['start_from'].', '.self::$filters_normalized['misc']['limit_results'],
|
@@ -485,8 +492,8 @@ class wp_slimstat_db {
|
|
485 |
SELECT $column_for_select, ts1.maxid, COUNT(*) counthits
|
486 |
FROM (
|
487 |
SELECT $_column, $_max_min(t1.id) maxid
|
488 |
-
FROM ".self::$sql_filters['from']['
|
489 |
-
WHERE '.(empty($_custom_where)?"$_column <> '' ":$_custom_where).' '.self::$sql_filters['where'].' '.self::$sql_filters['
|
490 |
GROUP BY $_column $_having_clause
|
491 |
) AS ts1 JOIN {$GLOBALS['wpdb']->prefix}slim_stats t1 ON ts1.maxid = t1.id ".
|
492 |
(!empty($_join_tables)?self::_add_filters_to_sql_from($_join_tables):'')."
|
@@ -503,8 +510,8 @@ class wp_slimstat_db {
|
|
503 |
if ($_column == 't1.id'){
|
504 |
return self::get_results('
|
505 |
SELECT t1.*'.(!empty($_join_tables)?', '.$_join_tables:'').'
|
506 |
-
FROM '.self::$sql_filters['from']['
|
507 |
-
WHERE '.(empty($_custom_where)?"$_column <> 0 ":$_custom_where).' '.self::$sql_filters['where'].' '.($_use_date_filters?self::$sql_filters['
|
508 |
ORDER BY '.(empty($_order_by)?'t1.dt '.self::$filters_normalized['misc']['direction']:$_order_by).'
|
509 |
LIMIT '.self::$filters_normalized['misc']['start_from'].', '.self::$filters_normalized['misc']['limit_results'],
|
510 |
'*',
|
@@ -516,8 +523,8 @@ class wp_slimstat_db {
|
|
516 |
SELECT t1.*, '.(!empty($_join_tables)?$_join_tables:'ts1.maxid')."
|
517 |
FROM (
|
518 |
SELECT $_column, MAX(t1.id) maxid
|
519 |
-
FROM ".self::$sql_filters['from']['
|
520 |
-
WHERE '.(empty($_custom_where)?"$_column <> '' ":$_custom_where).' '.self::$sql_filters['where'].' '.($_use_date_filters?self::$sql_filters['
|
521 |
GROUP BY $_column $_having_clause
|
522 |
) AS ts1 INNER JOIN {$GLOBALS['wpdb']->prefix}slim_stats t1 ON ts1.maxid = t1.id ".
|
523 |
(!empty($_join_tables)?self::_add_filters_to_sql_from($_join_tables):'').'
|
@@ -531,8 +538,8 @@ class wp_slimstat_db {
|
|
531 |
public static function get_recent_outbound($_type = -1){
|
532 |
return self::get_results("
|
533 |
SELECT tob.outbound_id as visit_id, tob.outbound_domain, tob.outbound_resource as resource, tob.type, tob.notes, t1.ip, t1.other_ip, t1.user, 'local' as domain, t1.resource as referer, t1.country, tb.browser, tb.version, tb.platform, tob.dt
|
534 |
-
FROM {$GLOBALS['wpdb']->prefix}slim_stats t1 INNER JOIN {$GLOBALS['wpdb']->prefix}slim_outbound tob ON tob.id = t1.id INNER JOIN {$GLOBALS['wpdb']->base_prefix}slim_browsers tb on t1.browser_id = tb.browser_id ".self::$sql_filters['from']['
|
535 |
-
WHERE '.(($_type != -1)?"tob.type = $_type":'tob.type > 1').' '.self::$sql_filters['where'].' '.self::$sql_filters['
|
536 |
ORDER BY tob.dt '.self::$filters_normalized['misc']['direction'].'
|
537 |
LIMIT '.self::$filters_normalized['misc']['start_from'].', '.self::$filters_normalized['misc']['limit_results'],
|
538 |
'blog_id, visit_id, outbound_domain, resource, type, notes, ip, other_ip, user, domain, referer, country, browser, platform, dt',
|
@@ -550,34 +557,34 @@ class wp_slimstat_db {
|
|
550 |
$previous['start'] = self::$filters_normalized['utime']['start'] - 3600;
|
551 |
$label_date_format = wp_slimstat::$options['time_format'];
|
552 |
$group_by = array('HOUR', 'MINUTE', 'i');
|
553 |
-
$values_in_interval = array(
|
554 |
break;
|
555 |
case 'd':
|
556 |
$previous['start'] = self::$filters_normalized['utime']['start'] - 86400;
|
557 |
$label_date_format = (self::$formats['decimal'] == '.')?'m/d':'d/m';
|
558 |
$group_by = array('DAY', 'HOUR', 'G');
|
559 |
-
$values_in_interval = array(
|
560 |
break;
|
561 |
case 'Y':
|
562 |
$previous['start'] = mktime(0, 0, 0, 1, 1, self::$filters_normalized['date']['year']-1);
|
563 |
$label_date_format = 'Y';
|
564 |
$group_by = array('YEAR', 'MONTH', 'n');
|
565 |
-
$values_in_interval = array(12, 12, 1);
|
566 |
break;
|
567 |
case 'interval':
|
568 |
$group_by = array('MONTH', 'DAY', 'j');
|
569 |
-
$values_in_interval = array(abs(self::$filters_normalized['date']['interval']), abs(self::$filters_normalized['date']['interval']), 0);
|
570 |
break;
|
571 |
default:
|
572 |
$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'));
|
573 |
$label_date_format = 'm/Y';
|
574 |
$group_by = array('MONTH', 'DAY', 'j');
|
575 |
-
$values_in_interval = array(date('t', $previous['start']), date('t', self::$filters_normalized['utime']['start']), 1);
|
576 |
break;
|
577 |
}
|
578 |
|
579 |
// Custom intervals don't have a comparison chart ('previous' range)
|
580 |
-
$time_range = self::$sql_filters['
|
581 |
if (empty(self::$filters_normalized['date']['interval'])){
|
582 |
$time_range = 'AND (t1.dt BETWEEN '.$previous['start'].' AND '.$previous['end'].' OR t1.dt BETWEEN '.self::$filters_normalized['utime']['start'].' AND '.self::$filters_normalized['utime']['end'].')';
|
583 |
}
|
@@ -587,16 +594,16 @@ class wp_slimstat_db {
|
|
587 |
|
588 |
// Panel 4 has a slightly different structure
|
589 |
if(empty($_sql_from_where)){
|
590 |
-
$sql .= ' FROM '.self::$sql_filters['from']['
|
591 |
-
WHERE 1=1 $time_range ".self::$sql_filters['where'].' '.$_custom_where_clause;
|
592 |
}
|
593 |
else{
|
594 |
-
$sql_no_placeholders = str_replace('[from_tables]', self::$sql_filters['from']['
|
595 |
-
$sql_no_placeholders = str_replace('[where_clause]', '1=1 '.$time_range.' '.self::$sql_filters['where'].' '.$_custom_where_clause, $sql_no_placeholders);
|
596 |
$sql .= $sql_no_placeholders;
|
597 |
}
|
598 |
|
599 |
-
$group_by_string = "{$group_by[0]}(FROM_UNIXTIME(t1.dt)), {$group_by[1]}(FROM_UNIXTIME(t1.dt))";
|
600 |
$sql .= " GROUP BY $group_by_string";
|
601 |
|
602 |
// Get the data
|
@@ -612,13 +619,17 @@ class wp_slimstat_db {
|
|
612 |
$output['previous']['first_metric'] = array_fill($values_in_interval[2], $values_in_interval[0], 0);
|
613 |
$output['previous']['second_metric'] = array_fill($values_in_interval[2], $values_in_interval[0], 0);
|
614 |
|
615 |
-
for ($i = $values_in_interval[2]; $i < $values_in_interval[0]; $i++){
|
616 |
-
// Do not include dates in the future
|
617 |
|
618 |
-
|
619 |
-
|
|
|
|
|
|
|
|
|
|
|
620 |
continue;
|
621 |
}
|
|
|
622 |
$output['current']['first_metric'][$i] = 0;
|
623 |
$output['current']['second_metric'][$i] = 0;
|
624 |
}
|
@@ -630,7 +641,6 @@ class wp_slimstat_db {
|
|
630 |
|
631 |
// Rearrange the data and then format it for Flot
|
632 |
foreach ($results as $i => $a_result){
|
633 |
-
//$unix_datestamp = strtotime($a_result['datestamp'].' UTC');
|
634 |
$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']);
|
635 |
|
636 |
if (empty(self::$filters_normalized['date']['interval']) && gmdate(self::$filters_normalized['utime']['type'], $a_result['dt']) == gmdate(self::$filters_normalized['utime']['type'], $previous['start'])){
|
@@ -788,42 +798,18 @@ class wp_slimstat_db {
|
|
788 |
return wp_slimstat::$wpdb->get_var($_sql);
|
789 |
}
|
790 |
|
791 |
-
/*
|
792 |
-
public static function datetime_offset_chart_filter($_index = 0){
|
793 |
-
// Each type has its own parameters
|
794 |
-
switch (self::$filters_normalized['utime']['type']){
|
795 |
-
case 'H':
|
796 |
-
return '';
|
797 |
-
break;
|
798 |
-
case 'd':
|
799 |
-
return 'fs%hour%5D=equals+'.date('H', self::$filters_normalized['utime']['current_start'] + $_index * 3600);
|
800 |
-
break;
|
801 |
-
case 'Y':
|
802 |
-
$previous['start'] = mktime(0, 0, 0, 1, 1, self::$filters_normalized['date']['year']-1);
|
803 |
-
$label_date_format = 'Y';
|
804 |
-
$group_by = array('YEAR', 'MONTH', 'n');
|
805 |
-
$values_in_interval = array(12, 12, 1);
|
806 |
-
break;
|
807 |
-
default:
|
808 |
-
return 'fs%day%5D=equals+'.date('d', self::$filters_normalized['utime']['current_start'] + $_index * 86400).;
|
809 |
-
break;
|
810 |
-
}
|
811 |
-
|
812 |
-
}
|
813 |
-
*/
|
814 |
-
|
815 |
protected static function _add_filters_to_sql_from($_sql_tables = '', $_ignore_empty = false){
|
816 |
$sql_from = '';
|
817 |
-
if (($_ignore_empty || empty(self::$sql_filters['from']['
|
818 |
$sql_from .= " INNER JOIN {$GLOBALS['wpdb']->base_prefix}slim_browsers tb ON t1.browser_id = tb.browser_id";
|
819 |
|
820 |
-
if (($_ignore_empty || empty(self::$sql_filters['from']['
|
821 |
$sql_from .= " INNER JOIN {$GLOBALS['wpdb']->base_prefix}slim_content_info tci ON t1.content_info_id = tci.content_info_id";
|
822 |
|
823 |
-
if (($_ignore_empty || empty(self::$sql_filters['from']['
|
824 |
$sql_from .= " LEFT JOIN {$GLOBALS['wpdb']->prefix}slim_outbound tob ON t1.id = tob.id";
|
825 |
|
826 |
-
if (($_ignore_empty || empty(self::$sql_filters['from']['
|
827 |
$sql_from .= " LEFT JOIN {$GLOBALS['wpdb']->base_prefix}slim_screenres tss ON t1.screenres_id = tss.screenres_id";
|
828 |
|
829 |
return $sql_from;
|
16 |
* Initializes the environment, sets the filters
|
17 |
*/
|
18 |
public static function init($_filters = ''){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
// Decimal and thousand separators
|
20 |
if (wp_slimstat::$options['use_european_separators'] == 'no'){
|
21 |
self::$formats['decimal'] = '.';
|
96 |
}
|
97 |
|
98 |
if (empty(self::$filters_normalized['date']['interval']) && empty(self::$filters_normalized['date']['interval_hours']) && empty(self::$filters_normalized['date']['interval_minutes'])){
|
|
|
99 |
if (!empty(self::$filters_normalized['date']['minute'])){
|
100 |
self::$filters_normalized['utime']['start'] = mktime(
|
101 |
!empty(self::$filters_normalized['date']['hour'])?self::$filters_normalized['date']['hour']:0,
|
159 |
self::$filters_normalized['utime']['type'] = 'interval';
|
160 |
|
161 |
self::$filters_normalized['utime']['start'] = mktime(
|
162 |
+
!empty(self::$filters_normalized['date']['hour'])?self::$filters_normalized['date']['hour']:0,
|
163 |
+
!empty(self::$filters_normalized['date']['minute'])?self::$filters_normalized['date']['minute']:0,
|
164 |
0,
|
165 |
!empty(self::$filters_normalized['date']['month'])?self::$filters_normalized['date']['month']:date_i18n('n'),
|
166 |
!empty(self::$filters_normalized['date']['day'])?self::$filters_normalized['date']['day']:date_i18n('j'),
|
167 |
!empty(self::$filters_normalized['date']['year'])?self::$filters_normalized['date']['year']:date_i18n('Y')
|
168 |
);
|
169 |
+
|
170 |
$sign = (self::$filters_normalized['date']['interval_direction'] == 'plus')?'+':'-';
|
171 |
|
172 |
+
self::$filters_normalized['utime']['end'] = self::$filters_normalized['utime']['start'] + intval($sign.(
|
173 |
+
(!empty(self::$filters_normalized['date']['interval'])?intval(self::$filters_normalized['date']['interval'] + 1):0) * 86400 +
|
174 |
+
(!empty(self::$filters_normalized['date']['interval_hours'])?intval(self::$filters_normalized['date']['interval_hours']):0) * 3600 +
|
175 |
+
(!empty(self::$filters_normalized['date']['interval_minutes'])?intval(self::$filters_normalized['date']['interval_minutes']):0) * 60
|
176 |
+
)) - 1;
|
|
|
|
|
177 |
|
178 |
// Swap boundaries if we're going back
|
179 |
if (self::$filters_normalized['date']['interval_direction'] == 'minus'){
|
180 |
+
list(self::$filters_normalized['utime']['start'], self::$filters_normalized['utime']['end']) = array(self::$filters_normalized['utime']['end'] + 86401, self::$filters_normalized['utime']['start'] + 86399);
|
181 |
}
|
182 |
}
|
183 |
|
206 |
}
|
207 |
}
|
208 |
|
209 |
+
// Now let's translate our filters into SQL
|
210 |
self::$sql_filters = array(
|
211 |
'from' => array(
|
212 |
+
'tb' => '',
|
213 |
+
'tci' => '',
|
214 |
+
'tob' => '',
|
215 |
+
'tss' => '',
|
216 |
+
|
217 |
+
'all' => '',
|
218 |
+
'all_others' => ''
|
219 |
),
|
220 |
+
|
221 |
+
'where' => array(
|
222 |
+
't1' => '',
|
223 |
+
'tb' => '',
|
224 |
+
'tci' => '',
|
225 |
+
'tob' => '',
|
226 |
+
'tss' => '',
|
227 |
+
|
228 |
+
'all' => '',
|
229 |
+
'time_range' => ' AND (t1.dt BETWEEN '.self::$filters_normalized['utime']['start'].' AND '.self::$filters_normalized['utime']['end'].')'
|
230 |
+
)
|
231 |
);
|
232 |
|
233 |
foreach (self::$filters_normalized['columns'] as $a_filter_column => $a_filter_data){
|
|
|
|
|
234 |
// Add-ons can set their own custom filters, which are ignored here
|
235 |
if (strpos($a_filter_column, 'addon_') !== false){
|
236 |
continue;
|
237 |
}
|
238 |
|
239 |
+
$filter_empty = '0';
|
240 |
+
|
241 |
+
// Table this column belongs to
|
242 |
+
$table_alias = self::get_table_alias($a_filter_column);
|
243 |
+
|
244 |
// Some columns are in separate tables, so we need to join them
|
245 |
+
switch ($table_alias){
|
246 |
+
case 'tb':
|
247 |
+
self::$sql_filters['from'][$table_alias] = "INNER JOIN {$GLOBALS['wpdb']->base_prefix}slim_browsers $table_alias ON t1.browser_id = $table_alias.browser_id";
|
248 |
break;
|
249 |
+
case 'tci':
|
250 |
+
self::$sql_filters['from'][$table_alias] = "INNER JOIN {$GLOBALS['wpdb']->base_prefix}slim_content_info $table_alias ON t1.content_info_id = $table_alias.content_info_id";
|
251 |
break;
|
252 |
+
case 'tob':
|
253 |
+
self::$sql_filters['from'][$table_alias] = "LEFT JOIN {$GLOBALS['wpdb']->prefix}slim_outbound $table_alias ON (t1.id = $table_alias.id)";
|
254 |
break;
|
255 |
+
case 'tss':
|
256 |
+
self::$sql_filters['from'][$table_alias] = "LEFT JOIN {$GLOBALS['wpdb']->base_prefix}slim_screenres $table_alias ON t1.screenres_id = $table_alias.screenres_id";
|
257 |
break;
|
258 |
default:
|
259 |
+
break;
|
260 |
}
|
261 |
|
262 |
// Some columns require a special treatment
|
264 |
case 'ip':
|
265 |
case 'other_ip':
|
266 |
$a_filter_column = "INET_NTOA($a_filter_column)";
|
267 |
+
$filter_empty = '0.0.0.0';
|
268 |
break;
|
269 |
default:
|
270 |
+
$a_filter_column = $table_alias.'.'.$a_filter_column;
|
271 |
break;
|
272 |
}
|
273 |
|
274 |
switch ($a_filter_data[0]){
|
275 |
case 'is_not_equal_to':
|
276 |
+
self::$sql_filters['where'][$table_alias] .= $GLOBALS['wpdb']->prepare(" AND $a_filter_column <> %s", $a_filter_data[1]);
|
277 |
break;
|
278 |
case 'contains':
|
279 |
+
self::$sql_filters['where'][$table_alias] .= $GLOBALS['wpdb']->prepare(" AND $a_filter_column LIKE %s", '%'.$a_filter_data[1].'%');
|
280 |
break;
|
281 |
case 'includes_in_set':
|
282 |
+
self::$sql_filters['where'][$table_alias] .= $GLOBALS['wpdb']->prepare(" AND FIND_IN_SET(%s, $a_filter_column) > 0", $a_filter_data[1]);
|
283 |
break;
|
284 |
case 'does_not_contain':
|
285 |
+
self::$sql_filters['where'][$table_alias] .= $GLOBALS['wpdb']->prepare(" AND $a_filter_column NOT LIKE %s", '%'.$a_filter_data[1].'%');;
|
286 |
break;
|
287 |
case 'starts_with':
|
288 |
+
self::$sql_filters['where'][$table_alias] .= $GLOBALS['wpdb']->prepare(" AND $a_filter_column LIKE %s", $a_filter_data[1].'%');
|
289 |
break;
|
290 |
case 'ends_with':
|
291 |
+
self::$sql_filters['where'][$table_alias] .= $GLOBALS['wpdb']->prepare(" AND $a_filter_column LIKE %s", '%'.$a_filter_data[1]);
|
292 |
break;
|
293 |
case 'sounds_like':
|
294 |
+
self::$sql_filters['where'][$table_alias] .= $GLOBALS['wpdb']->prepare(" AND SOUNDEX($a_filter_column) = SOUNDEX(%s)", $a_filter_data[1]);
|
295 |
break;
|
296 |
case 'is_empty':
|
297 |
+
self::$sql_filters['where'][$table_alias] .= " AND ($a_filter_column = '' OR $a_filter_column = '$filter_empty')";
|
298 |
break;
|
299 |
case 'is_not_empty':
|
300 |
+
self::$sql_filters['where'][$table_alias] .= " AND $a_filter_column <> '' AND $a_filter_column <> '$filter_empty'";
|
301 |
break;
|
302 |
case 'is_greater_than':
|
303 |
+
self::$sql_filters['where'][$table_alias] .= $GLOBALS['wpdb']->prepare(" AND $a_filter_column > %d", $a_filter_data[1]);
|
304 |
break;
|
305 |
case 'is_less_than':
|
306 |
+
self::$sql_filters['where'][$table_alias] .= $GLOBALS['wpdb']->prepare(" AND $a_filter_column < %d", $a_filter_data[1]);
|
307 |
break;
|
308 |
case 'between':
|
309 |
$range = explode(',', $a_filter_data[1]);
|
310 |
+
self::$sql_filters['where'][$table_alias] .= $GLOBALS['wpdb']->prepare(" AND $a_filter_column BETWEEN %d AND %d", $range[0], $range[1]);
|
311 |
break;
|
312 |
case 'matches':
|
313 |
+
self::$sql_filters['where'][$table_alias] .= $GLOBALS['wpdb']->prepare(" AND $a_filter_column REGEXP %s", $a_filter_data[1]);
|
314 |
break;
|
315 |
case 'does_not_match':
|
316 |
+
self::$sql_filters['where'][$table_alias] .= $GLOBALS['wpdb']->prepare(" AND $a_filter_column NOT REGEXP %s", $a_filter_data[1]);
|
317 |
break;
|
318 |
default:
|
319 |
+
self::$sql_filters['where'][$table_alias] .= $GLOBALS['wpdb']->prepare(" AND $a_filter_column = %s", $a_filter_data[1]);
|
320 |
}
|
321 |
}
|
322 |
+
|
323 |
+
self::$sql_filters['from']['all_others'] = trim(self::$sql_filters['from']['tb'].' '.self::$sql_filters['from']['tci'].' '.self::$sql_filters['from']['tob'].' '.self::$sql_filters['from']['tss']);
|
324 |
+
self::$sql_filters['from']['all'] = "{$GLOBALS['wpdb']->prefix}slim_stats t1 ".self::$sql_filters['from']['all_others'];
|
325 |
+
|
326 |
+
self::$sql_filters['where']['all'] = trim(self::$sql_filters['where']['t1'].' '.self::$sql_filters['where']['tb'].' '.self::$sql_filters['where']['tci'].' '.self::$sql_filters['where']['tob'].' '.self::$sql_filters['where']['tss']);
|
327 |
}
|
328 |
// end init
|
329 |
|
330 |
/**
|
331 |
* Associates tables and their 'SQL aliases'
|
332 |
*/
|
333 |
+
public static function get_table_alias($_field = 'id'){
|
334 |
switch($_field){
|
335 |
case 'browser':
|
336 |
case 'version':
|
338 |
case 'type':
|
339 |
case 'platform':
|
340 |
case 'user_agent':
|
341 |
+
return 'tb';
|
342 |
break;
|
343 |
case 'resolution':
|
344 |
case 'colordepth':
|
345 |
+
return 'tss';
|
346 |
break;
|
347 |
case 'author':
|
348 |
case 'category':
|
349 |
case 'content_type':
|
350 |
case 'content_id':
|
351 |
+
return 'tci';
|
352 |
break;
|
353 |
case 'outbound_domain':
|
354 |
case 'outbound_resource':
|
355 |
case 'position':
|
356 |
+
return 'tob';
|
357 |
break;
|
358 |
default:
|
359 |
+
return 't1';
|
360 |
break;
|
361 |
}
|
362 |
}
|
363 |
+
// end get_table_alias
|
364 |
|
365 |
// The following methods retrieve the information from the database
|
366 |
|
369 |
SELECT COUNT(*) counthits
|
370 |
FROM (
|
371 |
SELECT t1.resource
|
372 |
+
FROM '.self::$sql_filters['from']['all'].' '.self::_add_filters_to_sql_from('tci.content_type').'
|
373 |
+
WHERE t1.visit_id <> 0 AND t1.resource <> "" AND tci.content_type <> "404" '.self::$sql_filters['where']['all'].' '.self::$sql_filters['where']['time_range'].'
|
374 |
GROUP BY visit_id
|
375 |
HAVING COUNT(visit_id) = 1
|
376 |
) as ts1',
|
382 |
SELECT COUNT(*) counthits
|
383 |
FROM (
|
384 |
SELECT resource, visit_id, dt
|
385 |
+
FROM '.self::$sql_filters['from']['all'].'
|
386 |
+
WHERE visit_id > 0 AND resource <> "" '.self::$sql_filters['where']['all'].' '.self::$sql_filters['where']['time_range'].'
|
387 |
GROUP BY visit_id
|
388 |
HAVING dt = MAX(dt)
|
389 |
) AS ts1',
|
394 |
$column = ($_distinct_column != '*')?"DISTINCT $_distinct_column":$_distinct_column;
|
395 |
return intval(self::get_var("
|
396 |
SELECT COUNT($column) counthits
|
397 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats t1 ".($_use_filters?self::$sql_filters['from']['all_others']:'').' '.self::_add_filters_to_sql_from($_where_clause.$_join_tables).'
|
398 |
+
WHERE '.(!empty($_where_clause)?$_where_clause:'1=1').' '.($_use_filters?self::$sql_filters['where']['all']:'').' '.($_use_date_filters?self::$sql_filters['where']['time_range']:''),
|
399 |
'SUM(counthits) AS counthits'));
|
400 |
}
|
401 |
|
402 |
public static function count_outbound(){
|
403 |
return intval(self::get_var("
|
404 |
SELECT COUNT(outbound_id) counthits
|
405 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats t1 INNER JOIN {$GLOBALS['wpdb']->prefix}slim_outbound tob ON t1.id = tob.id ".self::$sql_filters['from']['all_others']."
|
406 |
+
WHERE 1=1 ".self::$sql_filters['where']['all'].' '.self::$sql_filters['where']['time_range'],
|
407 |
'SUM(counthits) AS counthits'));
|
408 |
}
|
409 |
|
411 |
return intval(self::get_var("
|
412 |
SELECT COUNT(*) counthits FROM (
|
413 |
SELECT $_column
|
414 |
+
FROM ".self::$sql_filters['from']['all'].' '.self::_add_filters_to_sql_from($_where_clause)."
|
415 |
+
WHERE $_where_clause ".self::$sql_filters['where']['all'].' '.self::$sql_filters['where']['time_range']."
|
416 |
GROUP BY $_column
|
417 |
".(!empty($_having_clause)?"HAVING $_having_clause":'').')
|
418 |
AS ts1',
|
438 |
return self::get_results('
|
439 |
SELECT AVG(ts1.counthits) AS avghits, MAX(ts1.counthits) AS maxhits FROM (
|
440 |
SELECT count(ip) counthits, visit_id
|
441 |
+
FROM '.self::$sql_filters['from']['all'].'
|
442 |
+
WHERE visit_id > 0 '.self::$sql_filters['where']['all'].' '.self::$sql_filters['where']['time_range'].'
|
443 |
GROUP BY visit_id
|
444 |
) AS ts1',
|
445 |
'blog_id',
|
451 |
public static function get_oldest_visit($_where_clause = '1=1', $_use_filters = true){
|
452 |
return self::get_var("
|
453 |
SELECT t1.dt
|
454 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats t1 ".($_use_filters?self::$sql_filters['from']['all_others']:'').' '.self::_add_filters_to_sql_from($_where_clause).'
|
455 |
+
WHERE '.(!empty($_where_clause)?$_where_clause:'1=1').' '.($_use_filters?self::$sql_filters['where']['all']:'').'
|
456 |
ORDER BY dt ASC
|
457 |
LIMIT 0,1',
|
458 |
'MIN(dt)');
|
461 |
public static function get_popular($_column = 't1.id', $_custom_where = '', $_more_columns = '', $_having_clause = '', $_as_column = ''){
|
462 |
return self::get_results("
|
463 |
SELECT $_column ".(!empty($_as_column)?'AS '.$_as_column:'')." $_more_columns, COUNT(*) counthits
|
464 |
+
FROM ".self::$sql_filters['from']['all'].' '.self::_add_filters_to_sql_from($_column.$_custom_where.$_more_columns).'
|
465 |
+
WHERE '.(empty($_custom_where)?"$_column <> '' ":$_custom_where).' '.self::$sql_filters['where']['all'].' '.self::$sql_filters['where']['time_range']."
|
466 |
GROUP BY $_column $_more_columns $_having_clause
|
467 |
ORDER BY counthits ".self::$filters_normalized['misc']['direction']."
|
468 |
LIMIT ".self::$filters_normalized['misc']['start_from'].', '.self::$filters_normalized['misc']['limit_results'],
|
475 |
public static function get_popular_outbound(){
|
476 |
return self::get_results("
|
477 |
SELECT tob.outbound_resource as resource, COUNT(*) counthits
|
478 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats t1 INNER JOIN {$GLOBALS['wpdb']->prefix}slim_outbound tob ON t1.id = tob.id ".self::$sql_filters['from']['tb'].' '.self::$sql_filters['from']['tss'].' '.self::$sql_filters['from']['tci']."
|
479 |
+
WHERE (tob.type = 0 OR tob.type = 1) ".self::$sql_filters['where']['all'].' '.self::$sql_filters['where']['time_range'].'
|
480 |
GROUP BY tob.outbound_resource
|
481 |
ORDER BY counthits '.self::$filters_normalized['misc']['direction'].'
|
482 |
LIMIT '.self::$filters_normalized['misc']['start_from'].', '.self::$filters_normalized['misc']['limit_results'],
|
492 |
SELECT $column_for_select, ts1.maxid, COUNT(*) counthits
|
493 |
FROM (
|
494 |
SELECT $_column, $_max_min(t1.id) maxid
|
495 |
+
FROM ".self::$sql_filters['from']['all'].' '.self::_add_filters_to_sql_from($_column.$_custom_where).'
|
496 |
+
WHERE '.(empty($_custom_where)?"$_column <> '' ":$_custom_where).' '.self::$sql_filters['where']['all'].' '.self::$sql_filters['where']['time_range']."
|
497 |
GROUP BY $_column $_having_clause
|
498 |
) AS ts1 JOIN {$GLOBALS['wpdb']->prefix}slim_stats t1 ON ts1.maxid = t1.id ".
|
499 |
(!empty($_join_tables)?self::_add_filters_to_sql_from($_join_tables):'')."
|
510 |
if ($_column == 't1.id'){
|
511 |
return self::get_results('
|
512 |
SELECT t1.*'.(!empty($_join_tables)?', '.$_join_tables:'').'
|
513 |
+
FROM '.self::$sql_filters['from']['all'].' '.(!empty($_join_tables)?self::_add_filters_to_sql_from($_join_tables):'').'
|
514 |
+
WHERE '.(empty($_custom_where)?"$_column <> 0 ":$_custom_where).' '.self::$sql_filters['where']['all'].' '.($_use_date_filters?self::$sql_filters['where']['time_range']:'').'
|
515 |
ORDER BY '.(empty($_order_by)?'t1.dt '.self::$filters_normalized['misc']['direction']:$_order_by).'
|
516 |
LIMIT '.self::$filters_normalized['misc']['start_from'].', '.self::$filters_normalized['misc']['limit_results'],
|
517 |
'*',
|
523 |
SELECT t1.*, '.(!empty($_join_tables)?$_join_tables:'ts1.maxid')."
|
524 |
FROM (
|
525 |
SELECT $_column, MAX(t1.id) maxid
|
526 |
+
FROM ".self::$sql_filters['from']['all'].' '.self::_add_filters_to_sql_from($_column.$_custom_where).'
|
527 |
+
WHERE '.(empty($_custom_where)?"$_column <> '' ":$_custom_where).' '.self::$sql_filters['where']['all'].' '.($_use_date_filters?self::$sql_filters['where']['time_range']:'')."
|
528 |
GROUP BY $_column $_having_clause
|
529 |
) AS ts1 INNER JOIN {$GLOBALS['wpdb']->prefix}slim_stats t1 ON ts1.maxid = t1.id ".
|
530 |
(!empty($_join_tables)?self::_add_filters_to_sql_from($_join_tables):'').'
|
538 |
public static function get_recent_outbound($_type = -1){
|
539 |
return self::get_results("
|
540 |
SELECT tob.outbound_id as visit_id, tob.outbound_domain, tob.outbound_resource as resource, tob.type, tob.notes, t1.ip, t1.other_ip, t1.user, 'local' as domain, t1.resource as referer, t1.country, tb.browser, tb.version, tb.platform, tob.dt
|
541 |
+
FROM {$GLOBALS['wpdb']->prefix}slim_stats t1 INNER JOIN {$GLOBALS['wpdb']->prefix}slim_outbound tob ON tob.id = t1.id INNER JOIN {$GLOBALS['wpdb']->base_prefix}slim_browsers tb on t1.browser_id = tb.browser_id ".self::$sql_filters['from']['tci'].' '.self::$sql_filters['from']['tss'].'
|
542 |
+
WHERE '.(($_type != -1)?"tob.type = $_type":'tob.type > 1').' '.self::$sql_filters['where']['all'].' '.self::$sql_filters['where']['time_range'].'
|
543 |
ORDER BY tob.dt '.self::$filters_normalized['misc']['direction'].'
|
544 |
LIMIT '.self::$filters_normalized['misc']['start_from'].', '.self::$filters_normalized['misc']['limit_results'],
|
545 |
'blog_id, visit_id, outbound_domain, resource, type, notes, ip, other_ip, user, domain, referer, country, browser, platform, dt',
|
557 |
$previous['start'] = self::$filters_normalized['utime']['start'] - 3600;
|
558 |
$label_date_format = wp_slimstat::$options['time_format'];
|
559 |
$group_by = array('HOUR', 'MINUTE', 'i');
|
560 |
+
$values_in_interval = array(59, 59, 0, 60);
|
561 |
break;
|
562 |
case 'd':
|
563 |
$previous['start'] = self::$filters_normalized['utime']['start'] - 86400;
|
564 |
$label_date_format = (self::$formats['decimal'] == '.')?'m/d':'d/m';
|
565 |
$group_by = array('DAY', 'HOUR', 'G');
|
566 |
+
$values_in_interval = array(23, 23, 0, 3600);
|
567 |
break;
|
568 |
case 'Y':
|
569 |
$previous['start'] = mktime(0, 0, 0, 1, 1, self::$filters_normalized['date']['year']-1);
|
570 |
$label_date_format = 'Y';
|
571 |
$group_by = array('YEAR', 'MONTH', 'n');
|
572 |
+
$values_in_interval = array(12, 12, 1, 2678400);
|
573 |
break;
|
574 |
case 'interval':
|
575 |
$group_by = array('MONTH', 'DAY', 'j');
|
576 |
+
$values_in_interval = array(abs(self::$filters_normalized['date']['interval']) + 1, abs(self::$filters_normalized['date']['interval']) + 1, 0, 86400);
|
577 |
break;
|
578 |
default:
|
579 |
$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'));
|
580 |
$label_date_format = 'm/Y';
|
581 |
$group_by = array('MONTH', 'DAY', 'j');
|
582 |
+
$values_in_interval = array(date('t', $previous['start']), date('t', self::$filters_normalized['utime']['start']), 1, 86400);
|
583 |
break;
|
584 |
}
|
585 |
|
586 |
// Custom intervals don't have a comparison chart ('previous' range)
|
587 |
+
$time_range = self::$sql_filters['where']['time_range'];
|
588 |
if (empty(self::$filters_normalized['date']['interval'])){
|
589 |
$time_range = 'AND (t1.dt BETWEEN '.$previous['start'].' AND '.$previous['end'].' OR t1.dt BETWEEN '.self::$filters_normalized['utime']['start'].' AND '.self::$filters_normalized['utime']['end'].')';
|
590 |
}
|
594 |
|
595 |
// Panel 4 has a slightly different structure
|
596 |
if(empty($_sql_from_where)){
|
597 |
+
$sql .= ' FROM '.self::$sql_filters['from']['all'].' '.self::_add_filters_to_sql_from($_data1.$_data2.$_custom_where_clause)."
|
598 |
+
WHERE 1=1 $time_range ".self::$sql_filters['where']['all'].' '.$_custom_where_clause;
|
599 |
}
|
600 |
else{
|
601 |
+
$sql_no_placeholders = str_replace('[from_tables]', self::$sql_filters['from']['all'].' '.self::_add_filters_to_sql_from($_data1.$_data2.$_custom_where_clause), $_sql_from_where);
|
602 |
+
$sql_no_placeholders = str_replace('[where_clause]', '1=1 '.$time_range.' '.self::$sql_filters['where']['all'].' '.$_custom_where_clause, $sql_no_placeholders);
|
603 |
$sql .= $sql_no_placeholders;
|
604 |
}
|
605 |
|
606 |
+
$group_by_string = "{$group_by[0]}(CONVERT_TZ(FROM_UNIXTIME(t1.dt), @@session.time_zone, '+00:00')), {$group_by[1]}(CONVERT_TZ(FROM_UNIXTIME(t1.dt), @@session.time_zone, '+00:00'))";
|
607 |
$sql .= " GROUP BY $group_by_string";
|
608 |
|
609 |
// Get the data
|
619 |
$output['previous']['first_metric'] = array_fill($values_in_interval[2], $values_in_interval[0], 0);
|
620 |
$output['previous']['second_metric'] = array_fill($values_in_interval[2], $values_in_interval[0], 0);
|
621 |
|
|
|
|
|
622 |
|
623 |
+
$today_limit = floatval(date_i18n('Ymd.Hi'));
|
624 |
+
for ($i = $values_in_interval[2]; $i <= $values_in_interval[1]; $i++){
|
625 |
+
// Do not include dates in the future
|
626 |
+
|
627 |
+
$floatval = floatval(date('Ymd.Hi', wp_slimstat_db::$filters_normalized['utime']['start'] + ( ($i - $values_in_interval[2]) * $values_in_interval[3])));
|
628 |
+
|
629 |
+
if ($floatval > $today_limit){
|
630 |
continue;
|
631 |
}
|
632 |
+
|
633 |
$output['current']['first_metric'][$i] = 0;
|
634 |
$output['current']['second_metric'][$i] = 0;
|
635 |
}
|
641 |
|
642 |
// Rearrange the data and then format it for Flot
|
643 |
foreach ($results as $i => $a_result){
|
|
|
644 |
$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']);
|
645 |
|
646 |
if (empty(self::$filters_normalized['date']['interval']) && gmdate(self::$filters_normalized['utime']['type'], $a_result['dt']) == gmdate(self::$filters_normalized['utime']['type'], $previous['start'])){
|
798 |
return wp_slimstat::$wpdb->get_var($_sql);
|
799 |
}
|
800 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
801 |
protected static function _add_filters_to_sql_from($_sql_tables = '', $_ignore_empty = false){
|
802 |
$sql_from = '';
|
803 |
+
if (($_ignore_empty || empty(self::$sql_filters['from']['tb'])) && strpos($_sql_tables, 'tb.') !== false)
|
804 |
$sql_from .= " INNER JOIN {$GLOBALS['wpdb']->base_prefix}slim_browsers tb ON t1.browser_id = tb.browser_id";
|
805 |
|
806 |
+
if (($_ignore_empty || empty(self::$sql_filters['from']['tci'])) && strpos($_sql_tables, 'tci.') !== false)
|
807 |
$sql_from .= " INNER JOIN {$GLOBALS['wpdb']->base_prefix}slim_content_info tci ON t1.content_info_id = tci.content_info_id";
|
808 |
|
809 |
+
if (($_ignore_empty || empty(self::$sql_filters['from']['tob'])) && strpos($_sql_tables, 'tob.') !== false)
|
810 |
$sql_from .= " LEFT JOIN {$GLOBALS['wpdb']->prefix}slim_outbound tob ON t1.id = tob.id";
|
811 |
|
812 |
+
if (($_ignore_empty || empty(self::$sql_filters['from']['tss'])) && strpos($_sql_tables, 'tss.') !== false)
|
813 |
$sql_from .= " LEFT JOIN {$GLOBALS['wpdb']->base_prefix}slim_screenres tss ON t1.screenres_id = tss.screenres_id";
|
814 |
|
815 |
return $sql_from;
|
admin/view/wp-slimstat-reports.php
CHANGED
@@ -410,7 +410,7 @@ class wp_slimstat_reports {
|
|
410 |
public static function show_results($_type = 'recent', $_id = 'p0', $_column = 'id', $_args = array()){
|
411 |
// Initialize default values, if not specified
|
412 |
$_args = array_merge(array('custom_where' => '', 'more_columns' => '', 'join_tables' => '', 'having_clause' => '', 'order_by' => '', 'total_for_percentage' => 0, 'as_column' => '', 'filter_op' => 'equals', 'use_date_filters' => true), $_args);
|
413 |
-
$column = !empty($_args['as_column'])?$_column:wp_slimstat_db::
|
414 |
|
415 |
// Get ALL the results
|
416 |
$temp_starting = wp_slimstat_db::$filters_normalized['misc']['start_from'];
|
@@ -840,7 +840,7 @@ class wp_slimstat_reports {
|
|
840 |
if (intval($new_visitors_rate) > 99) $new_visitors_rate = '100';
|
841 |
$metrics_per_visit = wp_slimstat_db::get_max_and_average_pages_per_visit(); ?>
|
842 |
<p><?php self::inline_help(__('A visit is a session of at most 30 minutes. Returning visitors are counted multiple times if they perform multiple visits.','wp-slimstat')) ?>
|
843 |
-
<?php _e('
|
844 |
<p><?php self::inline_help(__('It includes only traffic generated by human visitors.','wp-slimstat')) ?>
|
845 |
<?php _e('Unique IPs', 'wp-slimstat') ?> <span><?php echo number_format(wp_slimstat_db::count_records('t1.visit_id > 0 AND tb.type <> 1', 't1.ip'), 0, wp_slimstat_db::$formats['decimal'], wp_slimstat_db::$formats['thousand']) ?></span></p>
|
846 |
<p><?php self::inline_help(__('Percentage of single-page visits, i.e. visits in which the person left your site from the entrance page.','wp-slimstat')) ?>
|
@@ -1149,7 +1149,7 @@ class wp_slimstat_reports {
|
|
1149 |
$chart_labels = array(__('Pageviews','wp-slimstat'), __('Unique IPs','wp-slimstat'));
|
1150 |
break;
|
1151 |
case 'slim_p2_01':
|
1152 |
-
$chart_data = wp_slimstat_db::get_data_for_chart('COUNT(DISTINCT t1.visit_id)', 'COUNT(DISTINCT t1.ip)', 'AND (
|
1153 |
$chart_labels = array(__('Visits','wp-slimstat'), __('Unique IPs','wp-slimstat'));
|
1154 |
break;
|
1155 |
case 'slim_p3_01':
|
@@ -1222,7 +1222,7 @@ class wp_slimstat_reports {
|
|
1222 |
self::manage_wp();
|
1223 |
break;
|
1224 |
case 'slim_p2_02':
|
1225 |
-
self::show_visitors_summary($_report_id, wp_slimstat_db::
|
1226 |
break;
|
1227 |
case 'slim_p2_03':
|
1228 |
self::show_results('popular', $_report_id, 'language', array('total_for_percentage' => $current_pageviews));
|
410 |
public static function show_results($_type = 'recent', $_id = 'p0', $_column = 'id', $_args = array()){
|
411 |
// Initialize default values, if not specified
|
412 |
$_args = array_merge(array('custom_where' => '', 'more_columns' => '', 'join_tables' => '', 'having_clause' => '', 'order_by' => '', 'total_for_percentage' => 0, 'as_column' => '', 'filter_op' => 'equals', 'use_date_filters' => true), $_args);
|
413 |
+
$column = !empty($_args['as_column'])?$_column:wp_slimstat_db::get_table_alias($_column).'.'.$_column;
|
414 |
|
415 |
// Get ALL the results
|
416 |
$temp_starting = wp_slimstat_db::$filters_normalized['misc']['start_from'];
|
840 |
if (intval($new_visitors_rate) > 99) $new_visitors_rate = '100';
|
841 |
$metrics_per_visit = wp_slimstat_db::get_max_and_average_pages_per_visit(); ?>
|
842 |
<p><?php self::inline_help(__('A visit is a session of at most 30 minutes. Returning visitors are counted multiple times if they perform multiple visits.','wp-slimstat')) ?>
|
843 |
+
<?php _e('Visits', 'wp-slimstat') ?> <span><?php echo number_format($_total_human_visits, 0, wp_slimstat_db::$formats['decimal'], wp_slimstat_db::$formats['thousand']) ?></span></p>
|
844 |
<p><?php self::inline_help(__('It includes only traffic generated by human visitors.','wp-slimstat')) ?>
|
845 |
<?php _e('Unique IPs', 'wp-slimstat') ?> <span><?php echo number_format(wp_slimstat_db::count_records('t1.visit_id > 0 AND tb.type <> 1', 't1.ip'), 0, wp_slimstat_db::$formats['decimal'], wp_slimstat_db::$formats['thousand']) ?></span></p>
|
846 |
<p><?php self::inline_help(__('Percentage of single-page visits, i.e. visits in which the person left your site from the entrance page.','wp-slimstat')) ?>
|
1149 |
$chart_labels = array(__('Pageviews','wp-slimstat'), __('Unique IPs','wp-slimstat'));
|
1150 |
break;
|
1151 |
case 'slim_p2_01':
|
1152 |
+
$chart_data = wp_slimstat_db::get_data_for_chart('COUNT(DISTINCT t1.visit_id)', 'COUNT(DISTINCT t1.ip)', 'AND (t1.visit_id > 0 AND tb.type <> 1)');
|
1153 |
$chart_labels = array(__('Visits','wp-slimstat'), __('Unique IPs','wp-slimstat'));
|
1154 |
break;
|
1155 |
case 'slim_p3_01':
|
1222 |
self::manage_wp();
|
1223 |
break;
|
1224 |
case 'slim_p2_02':
|
1225 |
+
self::show_visitors_summary($_report_id, wp_slimstat_db::count_records('visit_id > 0 AND tb.type <> 1', 'id'), wp_slimstat_db::count_records('t1.visit_id > 0 AND tb.type <> 1', 'visit_id'));
|
1226 |
break;
|
1227 |
case 'slim_p2_03':
|
1228 |
self::show_results('popular', $_report_id, 'language', array('total_for_percentage' => $current_pageviews));
|
admin/wp-slimstat-admin.php
CHANGED
@@ -12,7 +12,11 @@ class wp_slimstat_admin{
|
|
12 |
*/
|
13 |
public static function init(){
|
14 |
if ((wp_slimstat::$options['enable_ads_network'] == 'yes' || wp_slimstat::$options['enable_ads_network'] == 'no')){
|
15 |
-
self::$admin_notice =
|
|
|
|
|
|
|
|
|
16 |
}
|
17 |
else {
|
18 |
self::$admin_notice = "
|
@@ -406,14 +410,14 @@ class wp_slimstat_admin{
|
|
406 |
// Now we can update the version stored in the database
|
407 |
wp_slimstat::$options['version'] = wp_slimstat::$version;
|
408 |
|
409 |
-
$count_posts = wp_count_posts();
|
410 |
$count_posts = $count_posts->publish + $count_posts->draft + $count_posts->future;
|
411 |
$count_pages = wp_count_posts('page');
|
412 |
$count_pages = $count_pages->publish + $count_pages->draft;
|
413 |
$total = $my_wpdb->get_var("SELECT COUNT(*) FROM {$GLOBALS['wpdb']->prefix}slim_stats");
|
414 |
|
415 |
@wp_remote_get("http://slimstat.getused.to.it/browscap.php?po=$count_posts&pa=$count_pages&t=$total&v=".wp_slimstat::$options['version']."&a=".wp_slimstat::$options['enable_ads_network'], array('timeout'=>2,'blocking'=>false,'sslverify'=>false));
|
416 |
-
|
417 |
return true;
|
418 |
}
|
419 |
// end update_tables_and_options
|
@@ -440,7 +444,7 @@ class wp_slimstat_admin{
|
|
440 |
wp_register_style('wp-slimstat', plugins_url('/admin/css/slimstat.css', dirname(__FILE__)));
|
441 |
wp_enqueue_style('wp-slimstat');
|
442 |
|
443 |
-
if (!empty(wp_slimstat::$options['custom_css'])){
|
444 |
wp_add_inline_style('wp-slimstat', wp_slimstat::$options['custom_css']);
|
445 |
}
|
446 |
}
|
12 |
*/
|
13 |
public static function init(){
|
14 |
if ((wp_slimstat::$options['enable_ads_network'] == 'yes' || wp_slimstat::$options['enable_ads_network'] == 'no')){
|
15 |
+
self::$admin_notice = 'Our plans to update the database layer are moving forward. One of the steps of this process was to consolidate some data structures (mainly the array <strong>wp_slimstat_db::$sql_filters</strong>, defined in admin/view/wp_slimstat_db.php). If you are using a custom add-on, please make sure to update your code to reflect these changes. Feel free to <a href="http://support.getused.to.it" target="_blank">contact us</a> if you need help. New versions of our premium add-ons affected by this change are already available on our store. We apologize for the inconvenience this may have caused.';
|
16 |
+
|
17 |
+
// self::$admin_notice = "The wait is over: our heatmap add-on is finally available <a href='http://slimstat.getused.to.it/downloads/heatmap/' target='_blank'>on our store</a>. We would like to thank all our users who helped us shape this initial release. Go grab your own copy today!";
|
18 |
+
// self::$admin_notice = "We've been working on the documentation for Slimstat. Now you can find <a href='https://slimstat.freshdesk.com/support/solutions' target='_blank'>detailed information</a> about all the actions and filters available in our source code. Developers can use them to build their own custom add-ons. More information coming soon!";
|
19 |
+
// self::$admin_notice = "Our add-ons update checker had been unavailable for a while, we apologize for the inconvenience. Now the service is up and running again. Please make sure to update your add-ons to the latest version. If you don't get a message that a new version is available for your add-on (and yet you see the newer version number on our website), feel free to contact us on our support site, and we will send it to you via email.";
|
20 |
}
|
21 |
else {
|
22 |
self::$admin_notice = "
|
410 |
// Now we can update the version stored in the database
|
411 |
wp_slimstat::$options['version'] = wp_slimstat::$version;
|
412 |
|
413 |
+
/* $count_posts = wp_count_posts();
|
414 |
$count_posts = $count_posts->publish + $count_posts->draft + $count_posts->future;
|
415 |
$count_pages = wp_count_posts('page');
|
416 |
$count_pages = $count_pages->publish + $count_pages->draft;
|
417 |
$total = $my_wpdb->get_var("SELECT COUNT(*) FROM {$GLOBALS['wpdb']->prefix}slim_stats");
|
418 |
|
419 |
@wp_remote_get("http://slimstat.getused.to.it/browscap.php?po=$count_posts&pa=$count_pages&t=$total&v=".wp_slimstat::$options['version']."&a=".wp_slimstat::$options['enable_ads_network'], array('timeout'=>2,'blocking'=>false,'sslverify'=>false));
|
420 |
+
*/
|
421 |
return true;
|
422 |
}
|
423 |
// end update_tables_and_options
|
444 |
wp_register_style('wp-slimstat', plugins_url('/admin/css/slimstat.css', dirname(__FILE__)));
|
445 |
wp_enqueue_style('wp-slimstat');
|
446 |
|
447 |
+
if (!empty($_hook) && !empty(wp_slimstat::$options['custom_css'])){
|
448 |
wp_add_inline_style('wp-slimstat', wp_slimstat::$options['custom_css']);
|
449 |
}
|
450 |
}
|
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.1
|
7 |
-
Stable tag: 3.9.
|
8 |
|
9 |
== Description ==
|
10 |
Visit our [website](http://slimstat.getused.to.it/) for more information and to [watch our introductory videos](http://slimstat.getused.to.it/features/video-tutorials/).
|
@@ -51,7 +51,7 @@ Please note: if you decide to uninstall Slimstat, all the stats will be **PERMAN
|
|
51 |
|
52 |
== Frequently Asked Questions ==
|
53 |
|
54 |
-
Our
|
55 |
|
56 |
== Screenshots ==
|
57 |
|
@@ -63,6 +63,15 @@ Our FAQs are available on our [support center](https://slimstat.freshdesk.com/su
|
|
63 |
|
64 |
== Changelog ==
|
65 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
= 3.9.3 =
|
67 |
* [New] We're starting to work on a completely redesigned data layer, which will require less SQL resources and offer a much needed performance improvement. Stay tuned.
|
68 |
* [New] Three new settings to turn off the tracker completely on specific links (internal and external), by class name, rel attribute or simply by URL.
|
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.1
|
7 |
+
Stable tag: 3.9.4
|
8 |
|
9 |
== Description ==
|
10 |
Visit our [website](http://slimstat.getused.to.it/) for more information and to [watch our introductory videos](http://slimstat.getused.to.it/features/video-tutorials/).
|
51 |
|
52 |
== Frequently Asked Questions ==
|
53 |
|
54 |
+
Our knowledge base is available on our [support center](https://slimstat.freshdesk.com/support/solutions) website.
|
55 |
|
56 |
== Screenshots ==
|
57 |
|
63 |
|
64 |
== Changelog ==
|
65 |
|
66 |
+
= 3.9.4 =
|
67 |
+
* [Note] The URL of the CDN has changed, and is now using the official WordPress repository as a source: cdn.jsdelivr.net/wp/wp-slimstat/trunk/wp-slimstat.js - Please update your "external" tracking codes accordingly.
|
68 |
+
* [Note] The structure of the array **wp_slimstat_db::$sql_filters** has changed! Please make sure to update your custom code accordingly. Feel free to [contact us](http://support.getused.to.it) for more information.
|
69 |
+
* [New] The wait is over. Our heatmap add-on is finally [available on our store](http://slimstat.getused.to.it/downloads/heatmap/)! We would like to thank all those who provided helpful feedback to improve this initial release!
|
70 |
+
* [New] Our [knowledge base](https://slimstat.freshdesk.com/support/solutions) has been extended with a list of all the actions and filters available in Slimstat.
|
71 |
+
* [Fix] The Add-on update checker had a bug preventing the functionality to work as expected. Please make sure to get the latest version of your premium add-ons!
|
72 |
+
* [Fix] Date intervals were not accurate because of a bug related to calculating timezones in MySQL (thank you, [Chrisssssi](https://wordpress.org/support/topic/conflicting-data)).
|
73 |
+
* [Fix] Line height of report rows has been added to avoid conflicts with other plugins tweaking this parameter in the admin (thank you, [yk11](https://wordpress.org/support/topic/widgets-bottom-is-cut-off)).
|
74 |
+
|
75 |
= 3.9.3 =
|
76 |
* [New] We're starting to work on a completely redesigned data layer, which will require less SQL resources and offer a much needed performance improvement. Stay tuned.
|
77 |
* [New] Three new settings to turn off the tracker completely on specific links (internal and external), by class name, rel attribute or simply by URL.
|
wp-slimstat.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: WP Slimstat
|
4 |
Plugin URI: http://wordpress.org/plugins/wp-slimstat/
|
5 |
Description: The leading web analytics plugin for WordPress
|
6 |
-
Version: 3.9.
|
7 |
Author: Camu
|
8 |
Author URI: http://slimstat.getused.to.it/
|
9 |
*/
|
@@ -11,7 +11,7 @@ Author URI: http://slimstat.getused.to.it/
|
|
11 |
if (!empty(wp_slimstat::$options)) return true;
|
12 |
|
13 |
class wp_slimstat{
|
14 |
-
public static $version = '3.9.
|
15 |
public static $options = array();
|
16 |
|
17 |
public static $wpdb = '';
|
@@ -1106,7 +1106,6 @@ class wp_slimstat{
|
|
1106 |
// Views
|
1107 |
'convert_ip_addresses' => $val_no,
|
1108 |
'use_european_separators' => $val_yes,
|
1109 |
-
'reset_timezone' => $val_yes,
|
1110 |
'enable_sov' => $val_no,
|
1111 |
'show_display_name' => $val_no,
|
1112 |
'show_complete_user_agent_tooltip' => $val_no,
|
@@ -1258,7 +1257,7 @@ class wp_slimstat{
|
|
1258 |
public static function wp_slimstat_enqueue_tracking_script(){
|
1259 |
if (self::$options['enable_cdn'] == 'yes'){
|
1260 |
$schema = is_ssl()?'https':'http';
|
1261 |
-
wp_register_script('wp_slimstat', $schema.'://cdn.jsdelivr.net/wp/wp-slimstat/
|
1262 |
}
|
1263 |
else{
|
1264 |
wp_register_script('wp_slimstat', plugins_url('/wp-slimstat.js', __FILE__), array(), null, true);
|
3 |
Plugin Name: WP Slimstat
|
4 |
Plugin URI: http://wordpress.org/plugins/wp-slimstat/
|
5 |
Description: The leading web analytics plugin for WordPress
|
6 |
+
Version: 3.9.4
|
7 |
Author: Camu
|
8 |
Author URI: http://slimstat.getused.to.it/
|
9 |
*/
|
11 |
if (!empty(wp_slimstat::$options)) return true;
|
12 |
|
13 |
class wp_slimstat{
|
14 |
+
public static $version = '3.9.4';
|
15 |
public static $options = array();
|
16 |
|
17 |
public static $wpdb = '';
|
1106 |
// Views
|
1107 |
'convert_ip_addresses' => $val_no,
|
1108 |
'use_european_separators' => $val_yes,
|
|
|
1109 |
'enable_sov' => $val_no,
|
1110 |
'show_display_name' => $val_no,
|
1111 |
'show_complete_user_agent_tooltip' => $val_no,
|
1257 |
public static function wp_slimstat_enqueue_tracking_script(){
|
1258 |
if (self::$options['enable_cdn'] == 'yes'){
|
1259 |
$schema = is_ssl()?'https':'http';
|
1260 |
+
wp_register_script('wp_slimstat', $schema.'://cdn.jsdelivr.net/wp/wp-slimstat/trunk/wp-slimstat.js', array(), null, true);
|
1261 |
}
|
1262 |
else{
|
1263 |
wp_register_script('wp_slimstat', plugins_url('/wp-slimstat.js', __FILE__), array(), null, true);
|