Count per Day - Version 3.1

Version Description

  • New: memory check before backup to avoid "out of memory" error
  • New: create temporary backup files for download only
  • New: delete backup files in wp-content on settings page
  • Bugfix: all posts shows 1 read in posts list
  • Bugfix: clean database shows 0 entries deleted
Download this release

Release Info

Developer Tom Braider
Plugin Icon 128x128 Count per Day
Version 3.1
Comparing to
See all releases

Code changes from version 2.0 to 3.1

Files changed (76) hide show
  1. ajax.php +32 -0
  2. counter-core.php +1301 -0
  3. counter-options.php +747 -107
  4. counter-rtl.css +20 -0
  5. counter.css +369 -0
  6. counter.php +1037 -718
  7. download.php +14 -0
  8. geoip/GeoIP.dat +0 -0
  9. geoip/geoip.inc +502 -0
  10. geoip/geoip.php +124 -0
  11. img/cpd_blau.png +0 -0
  12. img/cpd_calendar.png +0 -0
  13. img/cpd_clients.png +0 -0
  14. img/cpd_flags.png +0 -0
  15. img/cpd_menu.gif +0 -0
  16. img/cpd_pen.png +0 -0
  17. img/cpd_rot.png +0 -0
  18. img/cpd_sprites.png +0 -0
  19. img/cpd_trans.png +0 -0
  20. js/excanvas.min.js +1 -0
  21. js/jquery.flot.min.js +6 -0
  22. locale/cpd-az_AZ.mo +0 -0
  23. locale/cpd-az_AZ.po +972 -0
  24. locale/cpd-be_BY.mo +0 -0
  25. locale/cpd-be_BY.po +784 -0
  26. locale/cpd-bg_BG.mo +0 -0
  27. locale/cpd-bg_BG.po +972 -0
  28. locale/cpd-by_BY.mo +0 -0
  29. locale/cpd-by_BY.po +0 -177
  30. locale/cpd-da_DK.mo +0 -0
  31. locale/cpd-da_DK.po +973 -0
  32. locale/cpd-de_DE.mo +0 -0
  33. locale/cpd-de_DE.po +831 -99
  34. locale/cpd-el.mo +0 -0
  35. locale/cpd-el.po +973 -0
  36. locale/cpd-es_ES.mo +0 -0
  37. locale/cpd-es_ES.po +972 -0
  38. locale/cpd-fr_FR.mo +0 -0
  39. locale/cpd-fr_FR.po +971 -0
  40. locale/cpd-it_IT.mo +0 -0
  41. locale/cpd-it_IT.po +869 -67
  42. locale/cpd-ja.mo +0 -0
  43. locale/cpd-ja.po +972 -0
  44. locale/cpd-lt_LT.mo +0 -0
  45. locale/cpd-lt_LT.po +784 -0
  46. locale/cpd-nb_NO.mo +0 -0
  47. locale/cpd-nb_NO.po +972 -0
  48. locale/cpd-nl_NL.mo +0 -0
  49. locale/cpd-nl_NL.po +971 -0
  50. locale/cpd-pl_PL.mo +0 -0
  51. locale/cpd-pl_PL.po +972 -0
  52. locale/cpd-pt_BR.mo +0 -0
  53. locale/cpd-pt_BR.po +858 -62
  54. locale/cpd-pt_PT.mo +0 -0
  55. locale/cpd-pt_PT.po +971 -0
  56. locale/cpd-ru_RU.mo +0 -0
  57. locale/cpd-ru_RU.po +972 -0
  58. locale/cpd-sv_SE.mo +0 -0
  59. locale/cpd-sv_SE.po +972 -0
  60. locale/cpd-tr_TR.mo +0 -0
  61. locale/cpd-tr_TR.po +971 -0
  62. locale/cpd-ua_UA.mo +0 -0
  63. locale/cpd-ua_UA.po +972 -0
  64. map/ammap.swf +0 -0
  65. map/data.xml.php +68 -0
  66. map/map.php +25 -0
  67. map/settings.xml.php +63 -0
  68. map/swfobject.js +8 -0
  69. map/world.swf +0 -0
  70. massbots.php +70 -0
  71. notes.php +121 -0
  72. readme.txt +402 -68
  73. screenshot-1.png +0 -0
  74. screenshot-2.png +0 -0
  75. screenshot-3.png +0 -0
  76. userperspan.php +105 -0
ajax.php ADDED
@@ -0,0 +1,32 @@
1
+ <?php
2
+ if ( $_GET['f'] == 'count' )
3
+ {
4
+ if (!session_id()) session_start();
5
+ $cpd_wp = (!empty($_SESSION['cpd_wp'])) ? $_SESSION['cpd_wp'] : '../../../';
6
+ require_once($cpd_wp.'wp-load.php');
7
+
8
+ $cpd_funcs = array ( 'show',
9
+ 'getReadsAll', 'getReadsToday', 'getReadsYesterday', 'getReadsLastWeek', 'getReadsThisMonth',
10
+ 'getUserAll', 'getUserToday', 'getUserYesterday', 'getUserLastWeek', 'getUserThisMonth',
11
+ 'getUserPerDay', 'getUserOnline', 'getFirstCount' );
12
+
13
+ $page = (int) $_GET['page'];
14
+ if ( is_numeric($page) )
15
+ {
16
+ $count_per_day->count( '', $page );
17
+ foreach ( $cpd_funcs as $f )
18
+ {
19
+ if ( ($f == 'show' && $page) || $f != 'show' )
20
+ {
21
+ echo $f.'===';
22
+ if ( $f == 'getUserPerDay' )
23
+ eval('echo $count_per_day->getUserPerDay('.$count_per_day->options['dashboard_last_days'].');');
24
+ else if ( $f == 'show' )
25
+ eval('echo $count_per_day->show("", "", false, false, '.$page.');');
26
+ else
27
+ eval('echo $count_per_day->'.$f.'();');
28
+ echo '|';
29
+ }
30
+ }
31
+ }
32
+ }
counter-core.php ADDED
@@ -0,0 +1,1301 @@
1
+ <?php
2
+ /**
3
+ * Filename: counter-core.php
4
+ * Count Per Day - core functions
5
+ */
6
+
7
+ /**
8
+ * include GeoIP addon
9
+ */
10
+ if ( file_exists($cpd_path.'geoip/geoip.php') )
11
+ include_once($cpd_path.'geoip/geoip.php');
12
+ $cpd_geoip = ( class_exists('CpdGeoIp') && file_exists($cpd_path.'geoip/GeoIP.dat') ) ? 1 : 0;
13
+
14
+ /**
15
+ * helper functions
16
+ */
17
+ class CountPerDayCore
18
+ {
19
+
20
+ var $options; // options array
21
+ var $dir; // this plugin dir
22
+ var $dbcon; // database connection
23
+ var $queries = array(); // queries times for debug
24
+ var $page; // Post/Page-ID
25
+ var $installed = false; // CpD installed in subblogs?
26
+
27
+ /**
28
+ * Constructor
29
+ */
30
+ function init()
31
+ {
32
+ // variables
33
+ global $wpdb, $cpd_path, $cpd_dir_name;
34
+
35
+ define('CPD_METABOX', 'cpd_metaboxes');
36
+
37
+ // multisite table names
38
+ foreach ( array('cpd_counter','cpd_counter_useronline','cpd_notes') as $t )
39
+ {
40
+ $wpdb->tables[] = $t;
41
+ $wpdb->$t = $wpdb->get_blog_prefix().$t;
42
+ }
43
+
44
+ // use local time, not UTC
45
+ get_option('gmt_offset');
46
+
47
+ $this->options = get_option('count_per_day');
48
+
49
+ // manual debug mode
50
+ if (!empty($_GET['debug']) && WP_DEBUG )
51
+ $this->options['debug'] = 1;
52
+
53
+ $this->dir = get_bloginfo('wpurl').'/'.PLUGINDIR.'/'.$cpd_dir_name;
54
+ $this->queries[0] = 0;
55
+
56
+ // update online counter
57
+ add_action('wp', array(&$this,'deleteOnlineCounter'));
58
+
59
+ // settings link on plugin page
60
+ add_filter('plugin_action_links', array(&$this,'pluginActions'), 10, 2);
61
+
62
+ // auto counter
63
+ if ($this->options['autocount'])
64
+ add_action('wp', array(&$this,'count'));
65
+
66
+ // javascript to count cached posts
67
+ if ($this->options['ajax'])
68
+ {
69
+ wp_enqueue_script('jquery');
70
+ add_action('wp_footer', array(&$this,'addAjaxScript'));
71
+ }
72
+
73
+ if (is_admin())
74
+ {
75
+ // admin menu
76
+ add_action('admin_menu', array(&$this,'menu'));
77
+ // widget on dashboard page
78
+ add_action('wp_dashboard_setup', array(&$this,'dashboardWidgetSetup'));
79
+ // CpD dashboard page
80
+ add_filter('screen_layout_columns', array(&$this,'screenLayoutColumns'), 10, 2);
81
+ // CpD dashboard
82
+ add_action('admin_menu', array(&$this,'setAdminMenu'));
83
+ // column page list
84
+ add_action('manage_pages_custom_column', array(&$this,'cpdColumnContent'), 10, 2);
85
+ add_filter('manage_edit-page_columns', array(&$this,'cpdColumn'));
86
+ // column post list
87
+ add_action('manage_posts_custom_column', array(&$this,'cpdColumnContent'), 10, 2);
88
+ // add_filter('manage_posts_columns', array(&$this,'cpdColumn'));
89
+ add_filter('manage_edit-post_columns', array(&$this,'cpdColumn'));
90
+ // add_filter('manage_edit-post_sortable_columns', array(&$this,'cpdSortableColumns'));
91
+
92
+ // add_filter('request', array(&$this,'cpdReadsOrderby'));
93
+
94
+ // adds javascript
95
+ add_action('admin_head', array(&$this,'addJS'));
96
+ // check version
97
+ add_action('admin_head', array(&$this,'checkInstalledVersion'));
98
+ }
99
+
100
+ // locale support
101
+ if (defined('WPLANG') && function_exists('load_plugin_textdomain'))
102
+ load_plugin_textdomain('cpd', false, $cpd_dir_name.'/locale');
103
+
104
+ // adds stylesheet
105
+ if (is_admin())
106
+ add_action('admin_head', array(&$this,'addCss'));
107
+ if ( empty($this->options['no_front_css']) )
108
+ add_action('wp_head', array(&$this,'addCss'));
109
+
110
+ // widget setup
111
+ add_action('widgets_init', array( &$this,'register_widgets'));
112
+
113
+ // activation hook
114
+ register_activation_hook(ABSPATH.PLUGINDIR.'/count-per-day/counter.php', array(&$this,'checkVersion'));
115
+
116
+ // update hook
117
+ if (function_exists('register_update_hook'))
118
+ register_update_hook(ABSPATH.PLUGINDIR.'/count-per-day/counter.php', array(&$this,'checkVersion'));
119
+
120
+ // uninstall hook
121
+ register_uninstall_hook($cpd_path.'counter.php', 'count_per_day_uninstall');
122
+
123
+ // query times debug
124
+ if ($this->options['debug'])
125
+ {
126
+ add_action('wp_footer', array(&$this,'showQueries'));
127
+ add_action('admin_footer', array(&$this,'showQueries'));
128
+ }
129
+
130
+ // add shortcode support
131
+ $this->addShortcodes();
132
+
133
+ // thickbox in backend only
134
+ if (strpos($_SERVER['SCRIPT_NAME'], '/wp-admin/') !== false )
135
+ {
136
+ wp_enqueue_script('thickbox');
137
+ wp_enqueue_script('cpd_flot', $this->dir.'/js/jquery.flot.min.js', 'jQuery');
138
+ }
139
+
140
+ // Session
141
+ add_action('init', array(&$this,'startSession'), 1);
142
+ }
143
+
144
+ function cpdReadsOrderby( $vars )
145
+ {
146
+ if ( isset($vars['orderby']) && $vars['orderby'] == 'cpd_reads' )
147
+ {
148
+ $vars = array_merge( $vars, array(
149
+ 'meta_key' => 'cpd_reads',
150
+ 'orderby' => 'meta_value_num'
151
+ ));
152
+ }
153
+ return $vars;
154
+ }
155
+
156
+
157
+
158
+ /**
159
+ * starts session to provide WP variables to "addons"
160
+ */
161
+ function startSession()
162
+ {
163
+ if (!session_id())
164
+ session_start();
165
+ $_SESSION['cpd_wp'] = ABSPATH;
166
+ }
167
+
168
+ /**
169
+ * get result from database
170
+ * @param string $kind kind of result
171
+ * @param string $sql sql query
172
+ * @param string $func name for debug info
173
+ */
174
+ function mysqlQuery( $kind = '', $sql, $func = '' )
175
+ {
176
+ global $wpdb;
177
+ $t = microtime(true);
178
+ $con = $wpdb->dbh;
179
+
180
+ $preparedSql = $wpdb->prepare($sql);
181
+
182
+ if ($kind == 'var')
183
+ $r = $wpdb->get_var( $preparedSql );
184
+ else if ($kind == 'count')
185
+ {
186
+ $sql = 'SELECT COUNT(*) FROM ('.trim($sql,';').') t';
187
+ $r = $wpdb->get_var( $wpdb->prepare($sql) );
188
+ }
189
+ else if ($kind = 'rows')
190
+ $r = $wpdb->get_results( $preparedSql );
191
+ else
192
+ $wpdb->query( $preparedSql );
193
+
194
+ if ( $this->options['debug'] )
195
+ {
196
+ $d = number_format( microtime(true) - $t , 5);
197
+ $m = sprintf("%.2f", memory_get_usage()/1048576).' MB';
198
+ $error = (!$r && mysql_errno($con)) ? '<b style="color:red">ERROR:</b> '.mysql_errno($con).' - '.mysql_error($con).' - ' : '';
199
+ $this->queries[] = $func." : <b>$d</b> - $m<br/><code>$preparedSql</code><br/>$error";
200
+ $this->queries[0] += $d;
201
+ }
202
+
203
+ return $r;
204
+ }
205
+
206
+ /**
207
+ * update DB if neccessary
208
+ */
209
+ function checkInstalledVersion()
210
+ {
211
+ global $cpd_version, $cpd_dir_name;
212
+ if ( $this->options['version'] != $cpd_version )
213
+ {
214
+ $this->checkVersion();
215
+ echo '<div class="updated"><p>'.sprintf(__('"Count per Day" updated to version %s.', 'cpd'), $cpd_version).'</p></div>';
216
+ }
217
+ }
218
+
219
+ /**
220
+ * anonymize IP address (last bit) if option is set
221
+ * @param $ip real IP address
222
+ * @return new IP address
223
+ */
224
+ function anonymize_ip( $ip )
225
+ {
226
+ if ( $this->options['debug'] )
227
+ $this->queries[] = 'called Function: <b style="color:blue">anonymize_ip</b> IP: <code>'.$ip.'</code>';
228
+ if ($this->options['anoip'])
229
+ {
230
+ $i = explode('.', $ip);
231
+ $i[3] += round( array_sum($i) / 4 + date_i18n('d') );
232
+ if ( $i[3] > 255 )
233
+ $i[3] -= 255;
234
+ return implode('.', $i);
235
+ }
236
+ else
237
+ return $ip;
238
+ }
239
+
240
+ /**
241
+ * gets PostID
242
+ */
243
+ function getPostID()
244
+ {
245
+ global $wp_query;
246
+ // find PostID
247
+ if ( !is_404() ) :
248
+ if ( $this->options['autocount'] && is_singular() )
249
+ {
250
+ // single page with autocount on
251
+ // make loop before regular loop is defined
252
+ if (have_posts()) :
253
+ while ( have_posts() && empty($p) ) :
254
+ the_post();
255
+ $p = get_the_ID();
256
+ endwhile;
257
+ endif;
258
+ rewind_posts();
259
+ }
260
+ else if (is_singular())
261
+ // single page with template tag show() or count()
262
+ $p = get_the_ID();
263
+ // "index" pages only with autocount
264
+ else if ( is_category() || is_tag() )
265
+ // category or tag => negativ ID in CpD DB
266
+ $p = 0 - $wp_query->get_queried_object_id();
267
+ else
268
+ // index, date, search and other "list" pages will count only once
269
+ $p = 0;
270
+ $this->page = $p;
271
+ if ( $this->options['debug'] )
272
+ $this->queries[] = 'called Function: <b style="color:blue">getPostID</b> page ID: <code>'.$p.'</code>';
273
+ return $p;
274
+ endif;
275
+
276
+ return false;
277
+ }
278
+
279
+ /**
280
+ * bot or human?
281
+ * @param string $client USER_AGENT
282
+ * @param array $bots strings to check
283
+ * @param string $ip IP adress
284
+ */
285
+ function isBot( $client = '', $bots = '', $ip = '' )
286
+ {
287
+ if ( empty($client) && isset($_SERVER['HTTP_USER_AGENT']) )
288
+ $client = $_SERVER['HTTP_USER_AGENT'];
289
+ if (empty($ip))
290
+ $ip = $_SERVER['REMOTE_ADDR'];
291
+
292
+ // empty/short client -> not normal browser -> bot
293
+ if ( empty($client) || strlen($client) < 20 )
294
+ return true;
295
+
296
+ if (empty($bots))
297
+ $bots = explode( "\n", $this->options['bots'] );
298
+
299
+ $isBot = false;
300
+ foreach ( $bots as $bot )
301
+ {
302
+ if (!$isBot) // loop until first bot was found only
303
+ {
304
+ $b = trim($bot);
305
+ if ( !empty($b) && ( $ip == $b || strpos( strtolower($client), strtolower($b) ) !== false ) )
306
+ $isBot = true;
307
+ }
308
+ }
309
+ return $isBot;
310
+ }
311
+
312
+ /**
313
+ * checks installation in sub blogs
314
+ */
315
+ function checkVersion()
316
+ {
317
+ global $wpdb;
318
+ if ( function_exists('is_multisite') && is_multisite() )
319
+ {
320
+ // check if it is a network activation
321
+ if (!empty($_GET['networkwide']))
322
+ {
323
+ $old_blog = $wpdb->blogid;
324
+ $blogids = $wpdb->get_col($wpdb->prepare("SELECT blog_id FROM $wpdb->blogs"));
325
+ foreach ($blogids as $blog_id)
326
+ {
327
+ // create tables in all sub blogs
328
+ switch_to_blog($blog_id);
329
+ $this->createTables();
330
+ }
331
+ switch_to_blog($old_blog);
332
+ return;
333
+ }
334
+ }
335
+ // create tables in main blog
336
+ $this->createTables();
337
+ }
338
+
339
+ /**
340
+ * creates tables if not exists
341
+ */
342
+ function createTables()
343
+ {
344
+ global $wpdb;
345
+ // for plugin activation, creates $wpdb
346
+ require_once(ABSPATH.'wp-admin/includes/upgrade.php');
347
+
348
+ // variables for subblogs
349
+ $cpd_c = $wpdb->cpd_counter;
350
+ $cpd_o = $wpdb->cpd_counter_useronline;
351
+ $cpd_n = $wpdb->cpd_notes;
352
+
353
+ if (!empty ($wpdb->charset))
354
+ $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
355
+ if (!empty ($wpdb->collate))
356
+ $charset_collate .= " COLLATE $wpdb->collate";
357
+
358
+ // table "counter"
359
+ $sql = "CREATE TABLE IF NOT EXISTS `$cpd_c` (
360
+ `id` int(10) NOT NULL auto_increment,
361
+ `ip` int(10) unsigned NOT NULL,
362
+ `client` varchar(150) NOT NULL,
363
+ `date` date NOT NULL,
364
+ `page` mediumint(9) NOT NULL,
365
+ `referer` varchar(100) NOT NULL,
366
+ PRIMARY KEY (`id`),
367
+ KEY `idx_page` (`page`),
368
+ KEY `idx_dateip` (`date`,`ip`) )
369
+ $charset_collate;";
370
+ $this->mysqlQuery('', $sql, 'createTables '.__LINE__);
371
+
372
+ // update fields in old table
373
+ $field = $this->mysqlQuery('rows', "SHOW FIELDS FROM `$cpd_c` LIKE 'ip'", 'createTables '.__LINE__);
374
+ $row = $field[0];
375
+ if ( strpos(strtolower($row->Type), 'int') === false )
376
+ {
377
+ $queries = array (
378
+ "ALTER TABLE `$cpd_c` ADD `ip2` INT(10) UNSIGNED NOT NULL AFTER `ip`",
379
+ "UPDATE `$cpd_c` SET ip2 = INET_ATON(ip)",
380
+ "ALTER TABLE `$cpd_c` DROP `ip`",
381
+ "ALTER TABLE `$cpd_c` CHANGE `ip2` `ip` INT( 10 ) UNSIGNED NOT NULL",
382
+ "ALTER TABLE `$cpd_c` CHANGE `date` `date` date NOT NULL",
383
+ "ALTER TABLE `$cpd_c` CHANGE `page` `page` mediumint(9) NOT NULL");
384
+ foreach ($queries as $sql)
385
+ $this->mysqlQuery('', $sql, 'update old fields '.__LINE__);
386
+ }
387
+
388
+ // make new keys
389
+ $keys = $this->mysqlQuery('rows', "SHOW KEYS FROM `$cpd_c`", 'make keys '.__LINE__);
390
+ $s = array();
391
+ foreach ($keys as $row)
392
+ if ( $row->Key_name != 'PRIMARY' )
393
+ $s[] = "DROP INDEX `$row->Key_name`";
394
+ $s = array_unique($s);
395
+
396
+ $sql = "ALTER TABLE `$cpd_c` ";
397
+ if (sizeof($s))
398
+ $sql .= implode(',', $s).', ';
399
+ $sql .= 'ADD KEY `idx_dateip` (`date`,`ip`), ADD KEY `idx_page` (`page`)';
400
+ $this->mysqlQuery('', $sql, 'make keys '.__LINE__);
401
+
402
+ // if GeoIP installed we need row "country"
403
+ if ( class_exists('CpdGeoIp') )
404
+ {
405
+ $this->mysqlQuery('', "SELECT country FROM `$cpd_c` LIMIT 1", 'check country '.__LINE__);
406
+ if ((int) mysql_errno() == 1054)
407
+ $this->mysqlQuery('', "ALTER TABLE `$cpd_c` ADD `country` CHAR(2) NOT NULL", 'make country '.__LINE__);
408
+ }
409
+
410
+ // referrer
411
+ $this->mysqlQuery('', "SELECT referer FROM `$cpd_c` LIMIT 1", 'check referer '.__LINE__);
412
+ if ((int) mysql_errno() == 1054)
413
+ $this->mysqlQuery('', "ALTER TABLE `$cpd_c` ADD `referer` VARCHAR(100) NOT NULL", 'make referer '.__LINE__);
414
+
415
+ // delete table "counter-online", since v3.0
416
+ $this->mysqlQuery('', "DROP TABLE IF EXISTS `$cpd_o`", 'table online '.__LINE__);
417
+
418
+ // delete table "notes", since v3.0
419
+ if (!get_option('count_per_day_notes'))
420
+ {
421
+ $table = $this->mysqlQuery('rows', "SHOW TABLES LIKE '$cpd_n'", 'table notes '.__LINE__);
422
+ if (!empty($table))
423
+ {
424
+ $ndb = $this->mysqlQuery('rows', "SELECT * FROM $cpd_n", 'table notes '.__LINE__);
425
+ $n = array();
426
+ foreach ($ndb as $note)
427
+ $n[] = array( $note->date, $note->note );
428
+ update_option('count_per_day_notes', $n);
429
+ }
430
+ }
431
+ $this->mysqlQuery('', "DROP TABLE IF EXISTS `$cpd_n`", 'table notes '.__LINE__);
432
+
433
+ // update options to array
434
+ $this->UpdateOptions();
435
+
436
+ // set directory mode
437
+ @chmod(ABSPATH.PLUGINDIR.'/count-per-day/geoip', 0777);
438
+ }
439
+
440
+ /**
441
+ * calls widget class
442
+ */
443
+ function register_widgets()
444
+ {
445
+ register_widget('CountPerDay_Widget');
446
+ }
447
+
448
+ /**
449
+ * shows debug infos
450
+ */
451
+ function showQueries()
452
+ {
453
+ global $wpdb, $cpd_path, $cpd_version;
454
+ echo '<div style="position:absolute;margin:10px;padding:10px;border:1px red solid">
455
+ <b>Count per Day - DEBUG: '.round($this->queries[0], 3).' s</b><ol>'."\n";
456
+ echo '<li>'
457
+ .'<b>Server:</b> '.$_SERVER['SERVER_SOFTWARE'].'<br/>'
458
+ .'<b>PHP:</b> '.phpversion().'<br/>'
459
+ .'<b>mySQL Server:</b> '.mysql_get_server_info($wpdb->dbh).'<br/>'
460
+ .'<b>mySQL Client:</b> '.mysql_get_client_info().'<br/>'
461
+ .'<b>WordPress:</b> '.get_bloginfo('version').'<br/>'
462
+ .'<b>Count per Day:</b> '.$cpd_version.'<br/>'
463
+ .'<b>Time for Count per Day:</b> '.date_i18n('Y-m-d H:i').'<br/>'
464
+ .'<b>URL:</b> '.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'].'<br/>'
465
+ .'<b>Referrer:</b> '.(isset($_SERVER['HTTP_REFERER']) ? htmlentities($_SERVER['HTTP_REFERER']) : '').'<br/>'
466
+ .'<b>PHP-Memory:</b> peak: '.$this->formatBytes(memory_get_peak_usage()).', limit: '.ini_get('memory_limit')
467
+ .'</li>';
468
+ echo "\n<li><b>POST:</b><br/>\n";
469
+ var_dump($_POST);
470
+ echo '</li>';
471
+ echo "\n<li><b>SESSION:</b><br/>\n";
472
+ var_dump($_SESSION);
473
+ echo '</li>';
474
+ echo "\n<li><b>Table:</b><br /><b>$wpdb->cpd_counter</b>:\n";
475
+ $res = $this->mysqlQuery('rows', "SHOW FIELDS FROM `$wpdb->cpd_counter`", 'showFields' );
476
+ foreach ($res as $c)
477
+ echo '<span style="color:blue">'.$c->Field.'</span> = '.$c->Type.' &nbsp; ';
478
+ echo "\n</li>";
479
+ echo "\n<li><b>Options:</b><br />\n";
480
+ foreach ( $this->options as $k=>$v )
481
+ if ( $k != 'bots') // hoster restrictions
482
+ echo "$k = $v<br />\n";
483
+ echo "</li>";
484
+ foreach($this->queries as $q)
485
+ if ($q != $this->queries[0])
486
+ echo "\n<li>$q</li>";
487
+ echo "</ol>\n";
488
+ ?>
489
+ <p>GeoIP:
490
+ d_ir=<?php echo substr(decoct(fileperms($cpd_path.'geoip/')), -3) ?>
491
+ f_ile=<?php echo (is_file($cpd_path.'geoip/GeoIP.dat')) ? substr(decoct(fileperms($cpd_path.'geoip/GeoIP.dat')), -3) : '-'; ?>
492
+ f_open=<?php echo (function_exists('fopen')) ? 'true' : 'false' ?>
493
+ g_zopen=<?php echo (function_exists('gzopen')) ? 'true' : 'false' ?>
494
+ a_llow_url_fopen=<?php echo (ini_get('allow_url_fopen')) ? 'true' : 'false' ?>
495
+ </p>
496
+ <?php
497
+ echo '</div>';
498
+ }
499
+
500
+ /**
501
+ * adds style sheet to admin header
502
+ */
503
+ function addCss()
504
+ {
505
+ global $text_direction;
506
+ echo "\n".'<link rel="stylesheet" href="'.$this->dir.'/counter.css" type="text/css" />'."\n";
507
+ if ( $text_direction == 'rtl' )
508
+ echo "\n".'<link rel="stylesheet" href="'.$this->dir.'/counter-rtl.css" type="text/css" />'."\n";
509
+ // thickbox style here because add_thickbox() breaks RTL in he_IL
510
+ if ( strpos($_SERVER['SCRIPT_NAME'], '/wp-admin/') !== false )
511
+ echo '<link rel="stylesheet" href="'.get_bloginfo('wpurl').'/wp-includes/js/thickbox/thickbox.css" type="text/css" />'."\n";
512
+ }
513
+
514
+ /**
515
+ * adds javascript to admin header
516
+ */
517
+ function addJS()
518
+ {
519
+ echo '<!--[if IE]><script type="text/javascript" src="'.$this->dir.'/js/excanvas.min.js"></script><![endif]-->'."\n";
520
+ }
521
+
522
+ /**
523
+ * adds ajax script to count cached posts
524
+ */
525
+ function addAjaxScript()
526
+ {
527
+ $this->getPostID();
528
+ echo <<< JSEND
529
+ <script type="text/javascript">
530
+ // Count per Day
531
+ //<![CDATA[
532
+ jQuery(document).ready( function($)
533
+ {
534
+ jQuery.get('{$this->dir}/ajax.php?f=count&page={$this->page}', function(text)
535
+ {
536
+ var cpd_funcs = text.split('|');
537
+ for(var i = 0; i < cpd_funcs.length; i++)
538
+ {
539
+ var cpd_daten = cpd_funcs[i].split('===');
540
+ var cpd_fields = document.getElementById('cpd_number_' + cpd_daten[0].toLowerCase());
541
+ if (!cpd_fields) { cpd_fields.innerHTML = cpd_daten[1]; }
542
+ }
543
+ });
544
+ } );
545
+ //]]>
546
+ </script>
547
+ JSEND;
548
+
549
+ // name not valide in span or div...
550
+ // var cpd_fields = document.getElementsByName('cpd_number_' + cpd_daten[0].toLowerCase());
551
+ // for(var x = 0; x < cpd_fields.length; x++)
552
+ // {
553
+ // cpd_fields[x].innerHTML = cpd_daten[1];
554
+ // }
555
+ }
556
+
557
+ /**
558
+ * deletes spam in table, if you add new bot pattern you can clean the db
559
+ */
560
+ function cleanDB()
561
+ {
562
+ global $wpdb;
563
+
564
+ // get trimed bot array
565
+ function trim_value(&$value) { $value = trim($value); }
566
+ $bots = explode( "\n", $this->options['bots'] );
567
+ array_walk($bots, 'trim_value');
568
+
569
+ $rows_before = $this->mysqlQuery('var', "SELECT COUNT(*) FROM $wpdb->cpd_counter", 'cleanDB '.__LINE__);
570
+
571
+ // delete by ip
572
+ foreach( $bots as $ip )
573
+ if ( ip2long($ip) !== false )
574
+ $this->mysqlQuery('', "DELETE FROM $wpdb->cpd_counter WHERE INET_NTOA(ip) LIKE '".$ip."%%", 'clenaDB_ip'.__LINE__);
575
+
576
+ // delete by client
577
+ foreach ($bots as $bot)
578
+ $this->mysqlQuery('', "DELETE FROM $wpdb->cpd_counter WHERE client LIKE '%%".$bot."%%'", 'cleanDB_client'.__LINE__);
579
+
580
+ // delete if a previously countered page was deleted
581
+ $this->mysqlQuery('', "DELETE FROM $wpdb->cpd_counter WHERE page NOT IN ( SELECT id FROM $wpdb->posts) AND page > 0", 'cleanDB_delPosts'.__LINE__);
582
+
583
+ $rows_after = $this->mysqlQuery('var', "SELECT COUNT(*) FROM $wpdb->cpd_counter", 'cleanDB '.__LINE__);
584
+ return $rows_before - $rows_after;
585
+ }
586
+
587
+ /**
588
+ * adds menu entry to backend
589
+ * @param string $content WP-"Content"
590
+ */
591
+ function menu($content)
592
+ {
593
+ global $cpd_dir_name;
594
+ if (function_exists('add_options_page'))
595
+ {
596
+ $menutitle = '<img src="'.$this->img('cpd_menu.gif').'" alt="/" style="width:9px;height:12px;" /> Count per Day';
597
+ add_options_page('CountPerDay', $menutitle, 'manage_options', $cpd_dir_name.'/counter-options.php') ;
598
+ }
599
+ }
600
+
601
+ /**
602
+ * adds an "settings" link to the plugins page
603
+ */
604
+ function pluginActions($links, $file)
605
+ {
606
+ global $cpd_dir_name;
607
+ if( $file == $cpd_dir_name.'/counter.php'
608
+ && strpos( $_SERVER['SCRIPT_NAME'], '/network/') === false ) // not on network plugin page
609
+ {
610
+ $link = '<a href="options-general.php?page='.$cpd_dir_name.'/counter-options.php">'.__('Settings').'</a>';
611
+ array_unshift( $links, $link );
612
+ }
613
+ return $links;
614
+ }
615
+
616
+ /**
617
+ * combines the options to one array, update from previous versions
618
+ */
619
+ function updateOptions()
620
+ {
621
+ global $cpd_version;
622
+
623
+ $o = get_option('count_per_day', array());
624
+ $this->options = array('version' => $cpd_version);
625
+ $odefault = array(
626
+ 'onlinetime' => 300,
627
+ 'user' => 0,
628
+ 'user_level' => 0,
629
+ 'autocount' => 1,
630
+ 'bots' => "bot\nspider\nsearch\ncrawler\nask.com\nvalidator\nsnoopy\nsuchen.de\nsuchbaer.de\nshelob\nsemager\nxenu\nsuch_de\nia_archiver\nMicrosoft URL Control\nnetluchs",
631
+ 'dashboard_posts' => 20,
632
+ 'dashboard_last_posts' => 20,
633
+ 'dashboard_last_days' => 7,
634
+ 'show_in_lists' => 1,
635
+ 'chart_days' => 60,
636
+ 'chart_height' => 100,
637
+ 'countries' => 20,
638
+ 'startdate' => '',
639
+ 'startcount' => '',
640
+ 'startreads' => '',
641
+ 'anoip' => 0,
642
+ 'massbotlimit' => 25,
643
+ 'clients' => 'Firefox, MSIE, Chrome, Safari, Opera',
644
+ 'ajax' => 0,
645
+ 'debug' => 0,
646
+ 'referers' => 1,
647
+ 'referers_cut' => 0,
648
+ 'localref' => 1,
649
+ 'dashboard_referers' => 20,
650
+ 'referers_last_days' => 7,
651
+ 'no_front_css' => 0,
652
+ 'whocansee' => 'publish_posts',
653
+ 'backup_part' => 10000
654
+ );
655
+ foreach ($odefault as $k => $v)
656
+ $this->options[$k] = (isset($o[$k])) ? $o[$k] : $v;
657
+ update_option('count_per_day', $this->options);
658
+ }
659
+
660
+ /**
661
+ * adds widget to dashboard page
662
+ */
663
+ function dashboardWidgetSetup()
664
+ {
665
+ wp_add_dashboard_widget( 'cpdDashboardWidget', 'Count per Day', array(&$this,'dashboardWidget') );
666
+ }
667
+
668
+ /**
669
+ * add counter column to page/post lists
670
+ */
671
+ function cpdColumn($defaults)
672
+ {
673
+ if ( $this->options['show_in_lists'] )
674
+ $defaults['cpd_reads'] = '<img src="'.$this->img('cpd_menu.gif').'" alt="'.__('Reads', 'cpd').'" title="'.__('Reads', 'cpd').'" style="width:12px;height:12px;" />';
675
+ return $defaults;
676
+ }
677
+
678
+ function cpdSortableColumns($columns)
679
+ {
680
+ // meta column id => sortby value used in query
681
+ $custom = array('cpd_reads' => 'cpd_reads');
682
+ return wp_parse_args($custom, $columns);
683
+ }
684
+
685
+ /**
686
+ * adds content to the counter column
687
+ */
688
+ function cpdColumnContent($column_name, $id = 0)
689
+ {
690
+ global $wpdb;
691
+ if( $column_name == 'cpd_reads' )
692
+ {
693
+ $c = $this->mysqlQuery('count', "SELECT 1 FROM $wpdb->cpd_counter WHERE page='$id'", 'cpdColumn_'.$id.'_'.__LINE__);
694
+ $coll = get_option('count_per_day_posts');
695
+ if ( $coll && isset($coll['p-'.$id]) )
696
+ $c += $coll['p-'.$id];
697
+ echo $c;
698
+ }
699
+ }
700
+
701
+ /**
702
+ * gets image recource with given name
703
+ */
704
+ function img( $r )
705
+ {
706
+ return trailingslashit( $this->dir ).'img/'.$r;
707
+ }
708
+
709
+ /**
710
+ * sets columns on dashboard page
711
+ */
712
+ function screenLayoutColumns($columns, $screen)
713
+ {
714
+ if ($screen == $this->pagehook)
715
+ $columns[$this->pagehook] = 4;
716
+ return $columns;
717
+ }
718
+
719
+ /**
720
+ * extends the admin menu
721
+ */
722
+ function setAdminMenu()
723
+ {
724
+ $menutitle = '<img src="'.$this->img('cpd_menu.gif').'" alt="" style="width:12px;height:12px;" /> Count per Day';
725
+ $this->pagehook = add_submenu_page('index.php', 'CountPerDay', $menutitle, $this->options['whocansee'], CPD_METABOX, array(&$this, 'onShowPage'));
726
+ add_action('load-'.$this->pagehook, array(&$this, 'onLoadPage'));
727
+ }
728
+
729
+ /**
730
+ * backlink to Plugin homepage
731
+ */
732
+ function cpdInfo()
733
+ {
734
+ global $cpd_version;
735
+ $t = '<span style="white-space:nowrap">'.date_i18n('Y-m-d H:i').'</span>';
736
+ echo '<p style="margin:0">Count per Day: <code>'.$cpd_version.'</code><br/>';
737
+ printf(__('Time for Count per Day: <code>%s</code>.', 'cpd'), $t);
738
+ echo '<br />'.__('Bug? Problem? Question? Hint? Praise?', 'cpd').' ';
739
+ printf(__('Write a comment on the <a href="%s">plugin page</a>.', 'cpd'), 'http://www.tomsdimension.de/wp-plugins/count-per-day');
740
+ echo '<br />'.__('License').': <a href="http://www.tomsdimension.de/postcards">Postcardware :)</a>';
741
+ echo '<br /><a href="'.$this->dir.'/readme.txt?KeepThis=true&amp;TB_iframe=true" title="Count per Day - Readme.txt" class="thickbox"><strong>Readme.txt</strong></a></p>';
742
+ }
743
+
744
+ /**
745
+ * function calls from metabox default parameters
746
+ */
747
+ function getMostVisitedPostsMeta() { $this->getMostVisitedPosts(); }
748
+ function getUserPerPostMeta() { $this->getUserPerPost(); }
749
+ function getVisitedPostsOnDayMeta() { $this->getVisitedPostsOnDay(0, 100); }
750
+ function dashboardChartMeta() { $this->dashboardChart(0, false, false); }
751
+ function dashboardChartVisitorsMeta() { $this->dashboardChartVisitors(0, false, false); }
752
+ function getCountriesMeta() { $this->getCountries(0, false); }
753
+ function getCountriesVisitorsMeta() { $this->getCountries(0, false, true); }
754
+ function getReferersMeta() { $this->getReferers(0, false, 0); }
755
+ function getUserOnlineMeta() { $this->getUserOnline(false, true); }
756
+ function getUserPerMonthMeta() { $this->getUserPerMonth(); }
757
+ function getReadsPerMonthMeta() { $this->getReadsPerMonth(); }
758
+
759
+ /**
760
+ * will be executed if wordpress core detects this page has to be rendered
761
+ */
762
+ function onLoadPage()
763
+ {
764
+ global $cpd_geoip;
765
+ // needed javascripts
766
+ wp_enqueue_script('common');
767
+ wp_enqueue_script('wp-lists');
768
+ wp_enqueue_script('postbox');
769
+
770
+ // add the metaboxes
771
+ add_meta_box('reads_at_all', '<span class="cpd_icon cpd_summary">&nbsp;</span> '.__('Total visitors', 'cpd'), array(&$this,'dashboardReadsAtAll'), $this->pagehook, 'cpdrow1', 'core');
772
+ add_meta_box('user_online', '<span class="cpd_icon cpd_online">&nbsp;</span> '.__('Visitors online', 'cpd'), array(&$this,'getUserOnlineMeta'), $this->pagehook, 'cpdrow1', 'default');
773
+ add_meta_box('user_per_month', '<span class="cpd_icon cpd_user">&nbsp;</span> '.__('Visitors per month', 'cpd'), array(&$this,'getUserPerMonthMeta'), $this->pagehook, 'cpdrow2', 'default');
774
+ add_meta_box('reads_per_month', '<span class="cpd_icon cpd_reads">&nbsp;</span> '.__('Reads per month', 'cpd'), array(&$this,'getReadsPerMonthMeta'), $this->pagehook, 'cpdrow3', 'default');
775
+ add_meta_box('reads_per_post', '<span class="cpd_icon cpd_post">&nbsp;</span> '.__('Visitors per post', 'cpd'), array(&$this,'getUserPerPostMeta'), $this->pagehook, 'cpdrow3', 'default');
776
+ add_meta_box('last_reads', '<span class="cpd_icon cpd_calendar">&nbsp;</span> '.__('Latest Counts', 'cpd'), array(&$this,'getMostVisitedPostsMeta'), $this->pagehook, 'cpdrow4', 'default');
777
+ add_meta_box('day_reads', '<span class="cpd_icon cpd_day">&nbsp;</span> '.__('Visitors per day', 'cpd'), array(&$this,'getVisitedPostsOnDayMeta'), $this->pagehook, 'cpdrow4', 'default');
778
+ add_meta_box('cpd_info', '<span class="cpd_icon cpd_help">&nbsp;</span> '.__('Plugin'), array(&$this,'cpdInfo'), $this->pagehook, 'cpdrow1', 'low');
779
+ if ($this->options['referers'])
780
+ {
781
+ add_meta_box('browsers', '<span class="cpd_icon cpd_computer">&nbsp;</span> '.__('Browsers', 'cpd'), array(&$this,'getClients'), $this->pagehook, 'cpdrow2', 'default');
782
+ add_meta_box('referers', '<span class="cpd_icon cpd_referrer">&nbsp;</span> '.__('Referrer', 'cpd'), array(&$this,'getReferersMeta'), $this->pagehook, 'cpdrow3', 'default');
783
+ }
784
+ if ($cpd_geoip)
785
+ {
786
+ add_meta_box('countries', '<span class="cpd_icon cpd_reads">&nbsp;</span> '.__('Reads per Country', 'cpd'), array(&$this,'getCountriesMeta'), $this->pagehook, 'cpdrow2', 'default');
787
+ add_meta_box('countries2', '<span class="cpd_icon cpd_user">&nbsp;</span> '.__('Visitors per Country', 'cpd'), array(&$this,'getCountriesVisitorsMeta'), $this->pagehook, 'cpdrow2', 'default');
788
+ }
789
+ }
790
+
791
+ /**
792
+ * creates dashboard page
793
+ */
794
+ function onShowPage()
795
+ {
796
+ global $screen_layout_columns, $count_per_day;
797
+ if ( empty($screen_layout_columns) )
798
+ $screen_layout_columns = 4;
799
+ $data = '';
800
+ ?>
801
+ <div id="cpd-metaboxes" class="wrap">
802
+ <h2><img src="<?php echo $this->img('cpd_menu.gif') ?>" alt="" style="width:24px;height:24px" /> Count per Day - <?php _e('Statistics', 'cpd') ?></h2>
803
+ <?php
804
+ wp_nonce_field('cpd-metaboxes');
805
+ wp_nonce_field('closedpostboxes', 'closedpostboxesnonce', false);
806
+ wp_nonce_field('meta-box-order', 'meta-box-order-nonce', false);
807
+ $css = 'style="width:'.round(98 / $screen_layout_columns, 1).'%;"';
808
+ $this->getFlotChart();
809
+ ?>
810
+ <div id="dashboard-widgets" class="metabox-holder cpd-dashboard">
811
+ <div class="postbox-container" <?php echo $css; ?>><?php do_meta_boxes($this->pagehook, 'cpdrow1', $data); ?></div>
812
+ <div class="postbox-container" <?php echo $css; ?>><?php do_meta_boxes($this->pagehook, 'cpdrow2', $data); ?></div>
813
+ <div class="postbox-container" <?php echo $css; ?>><?php do_meta_boxes($this->pagehook, 'cpdrow3', $data); ?></div>
814
+ <div class="postbox-container" <?php echo $css; ?>><?php do_meta_boxes($this->pagehook, 'cpdrow4', $data); ?></div>
815
+ <br class="clear"/>
816
+ </div>
817
+ </div>
818
+ <script type="text/javascript">
819
+ //<![CDATA[
820
+ jQuery(document).ready( function($) {
821
+ $('.if-js-closed').removeClass('if-js-closed').addClass('closed');
822
+ postboxes.add_postbox_toggles('<?php echo $this->pagehook; ?>');
823
+ });
824
+ //]]>
825
+ </script>
826
+ <?php
827
+ }
828
+
829
+ /**
830
+ * adds some shortcodes to use functions in frontend
831
+ */
832
+ function addShortcodes()
833
+ {
834
+ add_shortcode('CPD_READS_THIS', array(&$this,'shortShow'));
835
+ add_shortcode('CPD_READS_TOTAL', array(&$this,'shortReadsTotal'));
836
+ add_shortcode('CPD_READS_TODAY', array(&$this,'shortReadsToday'));
837
+ add_shortcode('CPD_READS_YESTERDAY', array(&$this,'shortReadsYesterday'));
838
+ add_shortcode('CPD_READS_LAST_WEEK', array(&$this,'shortReadsLastWeek'));
839
+ add_shortcode('CPD_READS_PER_MONTH', array(&$this,'shortReadsPerMonth'));
840
+ add_shortcode('CPD_READS_THIS_MONTH', array(&$this,'shortReadsThisMonth'));
841
+ add_shortcode('CPD_VISITORS_TOTAL', array(&$this,'shortUserAll'));
842
+ add_shortcode('CPD_VISITORS_ONLINE', array(&$this,'shortUserOnline'));
843
+ add_shortcode('CPD_VISITORS_TODAY', array(&$this,'shortUserToday'));
844
+ add_shortcode('CPD_VISITORS_YESTERDAY', array(&$this,'shortUserYesterday'));
845
+ add_shortcode('CPD_VISITORS_LAST_WEEK', array(&$this,'shortUserLastWeek'));
846
+ add_shortcode('CPD_VISITORS_THIS_MONTH', array(&$this,'shortUserThisMonth'));
847
+ add_shortcode('CPD_VISITORS_PER_DAY', array(&$this,'shortUserPerDay'));
848
+ add_shortcode('CPD_FIRST_COUNT', array(&$this,'shortFirstCount'));
849
+ add_shortcode('CPD_CLIENTS', array(&$this,'shortClients'));
850
+ add_shortcode('CPD_VISITORS_PER_MONTH', array(&$this,'shortUserPerMonth'));
851
+ add_shortcode('CPD_VISITORS_PER_POST', array(&$this,'shortUserPerPost'));
852
+ add_shortcode('CPD_COUNTRIES', array(&$this,'shortCountries'));
853
+ add_shortcode('CPD_MOST_VISITED_POSTS', array(&$this,'shortMostVisitedPosts'));
854
+ add_shortcode('CPD_REFERERS', array(&$this,'shortReferers'));
855
+ add_shortcode('CPD_POSTS_ON_DAY', array(&$this,'shortPostsOnDay'));
856
+ add_shortcode('CPD_MAP', array(&$this,'shortShowMap'));
857
+ add_shortcode('CPD_DAY_MOST_READS', array(&$this,'shortDayWithMostReads'));
858
+ add_shortcode('CPD_DAY_MOST_USERS', array(&$this,'shortDayWithMostUsers'));
859
+ }
860
+ function shortShow() { return $this->show('', '', false, false); }
861
+ function shortReadsTotal() { return $this->getReadsAll(true); }
862
+ function shortReadsToday() { return $this->getReadsToday(true); }
863
+ function shortReadsYesterday() { return $this->getReadsYesterday(true); }
864
+ function shortReadsThisMonth() { return $this->getReadsThisMonth(true); }
865
+ function shortReadsLastWeek() { return $this->getReadsLastWeek(true); }
866
+ function shortReadsPerMonth() { return $this->getReadsPerMonth(true, true); }
867
+ function shortUserAll() { return $this->getUserAll(true); }
868
+ function shortUserOnline() { return $this->getUserOnline(false, false, true); }
869
+ function shortUserToday() { return $this->getUserToday(true); }
870
+ function shortUserYesterday() { return $this->getUserYesterday(true); }
871
+ function shortUserLastWeek() { return $this->getUserLastWeek(true); }
872
+ function shortUserThisMonth() { return $this->getUserThisMonth(true); }
873
+ function shortUserPerDay() { return $this->getUserPerDay($this->options['dashboard_last_days'], true); }
874
+ function shortFirstCount() { return $this->getFirstCount(true); }
875
+ function shortClients() { return $this->getClients(true); }
876
+ function shortUserPerMonth() { return $this->getUserPerMonth(true, true); }
877
+ function shortUserPerPost() { return $this->getUserPerPost(0, true, true); }
878
+ function shortCountries() { return $this->getCountries(0, true, false, true); }
879
+ function shortMostVisitedPosts(){ return $this->getMostVisitedPosts(0, 0, true, false, true); }
880
+ function shortReferers() { return $this->getReferers(0, true, 0); }
881
+ function shortDayWithMostReads(){ return $this->getDayWithMostReads(true, true); }
882
+ function shortDayWithMostUsers(){ return $this->getDayWithMostUsers(true, true); }
883
+ function shortPostsOnDay( $atts )
884
+ {
885
+ extract( shortcode_atts( array(
886
+ 'date' => 0,
887
+ 'limit' => 0
888
+ ), $atts) );
889
+ return $this->getVisitedPostsOnDay( $date, $limit, false, false, true, true );
890
+ }
891
+ function shortShowMap( $atts )
892
+ {
893
+ extract( shortcode_atts( array(
894
+ 'width' => 500,
895
+ 'height' => 340,
896
+ 'what' => 'reads',
897
+ 'min' => 0
898
+ ), $atts) );
899
+ return $this->getMap( $what, $width, $height, $min );
900
+ }
901
+
902
+ /**
903
+ * adds charts to lists on dashboard
904
+ * @param string $id HTML-id of the DIV
905
+ * @param array $data data
906
+ * @param string $html given list code to add the chart
907
+ */
908
+ function includeChartJS( $id, $data, $html )
909
+ {
910
+ $d = array_reverse($data);
911
+ $d = '[['.implode(',', $d).']]';
912
+ $code = '<div id="'.$id.'" class="cpd-list-chart" style="width:100%;height:50px"></div>
913
+ <script type="text/javascript">
914
+ //<![CDATA[
915
+ if (jQuery("#'.$id.'").width() > 0)
916
+ jQuery(function(){jQuery.plot(jQuery("#'.$id.'"),'.$d.',{series:{lines:{fill:true,lineWidth:1}},colors:["red"],grid:{show:false}});});
917
+ //]]>
918
+ </script>
919
+ '.$html;
920
+ return $code;
921
+ }
922
+
923
+ /**
924
+ * get mass bots
925
+ */
926
+ function getMassBots( $limit )
927
+ {
928
+ global $wpdb;
929
+ $sql = $wpdb->prepare("
930
+ SELECT t.id, t.ip AS longip, INET_NTOA(t.ip) AS ip, t.date, t.posts, c.client
931
+ FROM ( SELECT id, ip, date, count(*) posts
932
+ FROM $wpdb->cpd_counter
933
+ GROUP BY ip, date
934
+ ORDER BY posts DESC ) AS t
935
+ LEFT JOIN $wpdb->cpd_counter c
936
+ ON c.id = t.id
937
+ WHERE posts > %d", (int) $limit );
938
+ return $this->mysqlQuery('rows', $sql, 'getMassBots '.__LINE__);
939
+ }
940
+
941
+ /**
942
+ * backup the counter table to wp-content dir, gz-compressed if possible
943
+ */
944
+ function backup()
945
+ {
946
+ global $wpdb;
947
+
948
+ $t = $wpdb->cpd_counter;
949
+ $gz = ( function_exists('gzopen') && is_writable(WP_CONTENT_DIR) ) ? 1 : 0;
950
+ $tname = $t.'_backup_'.date_i18n('Y-m-d_H-i-s').'.sql';
951
+ if ($gz) $tname .= '.gz';
952
+ $name = '/'.$tname;
953
+
954
+ // wp-content or tempdir?
955
+ $path = ( empty($_POST['downloadonly']) && is_writable(WP_CONTENT_DIR) ) ? WP_CONTENT_DIR.$name : tempnam('', 'cpd');
956
+
957
+ // open file
958
+ $f = ($gz) ? gzopen($path,'w9') : fopen($path,'w');
959
+
960
+ @ob_start();
961
+
962
+ if (!$f) :
963
+ echo '<div class="error"><p>'.__('Backup failed! Cannot open file', 'cpd').' '.$path.'.</p></div>';
964
+ else :
965
+ set_time_limit(300);
966
+
967
+ // write backup to file
968
+ $d = "DROP TABLE IF EXISTS `$t`;\n";
969
+ ($gz) ? gzwrite($f, $d) : fwrite($f, $d);
970
+ if ( $res = $this->mysqlQuery('rows', "SHOW CREATE TABLE `$t`", 'backupCollect'.__LINE__) )
971
+ {
972
+ // create table command
973
+ $create = $res[0];
974
+ $create->{'Create Table'} .= ';';
975
+ $line = str_replace("\n", "", $create->{'Create Table'})."\n";
976
+ ($gz) ? gzwrite($f, $line) : fwrite($f, $line);
977
+ $line = false;
978
+
979
+ // number of entries
980
+ $entries = $this->mysqlQuery('count', "SELECT 1 FROM `$t`", 'backupCollect'.__LINE__);
981
+ $part = (int) $this->options['backup_part'];
982
+ if (empty($part))
983
+ $part = 10000;
984
+ // check free memory, save 8MB for script, 5000 entries needs ~ 10MB
985
+ $freeMemory = ($this->getBytes(ini_get('memory_limit')) - memory_get_usage()) - 8000000;
986
+ $part = min(array( round($freeMemory/1000000)*500, $part ));
987
+
988
+ // show progress
989
+ echo '<div id="cpd_progress" class="updated"><p>'.sprintf(__('Backup of %s entries in progress. Every point complies %s entries.', 'cpd'), $entries, $part).'<br />';
990
+ $this->flush_buffers();
991
+
992
+ // get data
993
+ for ($i = 0; $i <= $entries; $i = $i + $part)
994
+ {
995
+ if ( $data = $this->mysqlQuery('rows', "SELECT * FROM `$t` LIMIT $i, $part", 'backupCollect'.__LINE__) )
996
+ {
997
+ foreach ($data as $row)
998
+ {
999
+ $row = (array) $row;
1000
+
1001
+ // columns names
1002
+ if (empty($cols))
1003
+ $cols = array_keys($row);
1004
+
1005
+ // create line
1006
+ if (!$line)
1007
+ {
1008
+ $line = "INSERT INTO `$t` (`".implode('`,`',$cols)."`) VALUES\n";
1009
+ if (isset($v))
1010
+ $line .= "$v\n";
1011
+ }
1012
+
1013
+ // add values
1014
+ $v = '';
1015
+ foreach ($row as $val)
1016
+ $v .= "'".mysql_real_escape_string($val)."',";
1017
+ $v = '('.substr($v,0,-1).'),';
1018
+
1019
+ if ( strlen($line) < 50000 - strlen($v) )
1020
+ $line .= "$v\n";
1021
+ else
1022
+ {
1023
+ $line = substr($line,0,-2).";\n";
1024
+ ($gz) ? gzwrite($f, $line) : fwrite($f, $line);
1025
+ $line = false;
1026
+ }
1027
+ }
1028
+ }
1029
+ // echo $this->formatBytes(memory_get_peak_usage());
1030
+ echo '| ';
1031
+ $this->flush_buffers();
1032
+ }
1033
+
1034
+ // write leftover
1035
+ if ($line)
1036
+ {
1037
+ $line = substr($line,0,-2).";\n";
1038
+ ($gz) ? gzwrite($f, $line) : fwrite($f, $line);
1039
+ }
1040
+
1041
+ // reindex command
1042
+ $line = "REPAIR TABLE `$t`;";
1043
+ ($gz) ? gzwrite($f, $line) : fwrite($f, $line);
1044
+
1045
+ echo '</p></div>';
1046
+
1047
+ // hide progress
1048
+ echo '<script type="text/javascript">'
1049
+ .'document.getElementById("cpd_progress").style.display="none";'
1050
+ .'</script>'."\n";
1051
+ $this->flush_buffers();
1052
+ }
1053
+
1054
+ // close file
1055
+ ($gz) ? gzclose($f) : fclose($f);
1056
+
1057
+ // save collection and options
1058
+ $toname = 'count_per_day_options_'.date_i18n('Y-m-d_H-i-s').'.txt';
1059
+ if ($gz) $toname .= '.gz';
1060
+ $oname = '/'.$toname;
1061
+ $opath = ( empty($_POST['downloadonly']) && is_writable(WP_CONTENT_DIR) ) ? WP_CONTENT_DIR.$oname : tempnam('', 'cpd');
1062
+ $f = ($gz) ? gzopen($opath,'w9') : fopen($opath,'w');
1063
+
1064
+ foreach (array('count_per_day', 'count_per_day_summary', 'count_per_day_collected', 'count_per_day_posts', 'count_per_day_notes') as $o)
1065
+ {
1066
+ $c = get_option($o);
1067
+ $line = "=== begin $o ===\n".serialize($c)."\n=== end $o ===\n\n";
1068
+ ($gz) ? gzwrite($f, $line) : fwrite($f, $line);
1069
+ }
1070
+ ($gz) ? gzclose($f) : fclose($f);
1071
+
1072
+ // message
1073
+ echo '<div class="updated"><p>';
1074
+ if ( strpos($path, WP_CONTENT_DIR) === false )
1075
+ {
1076
+ // show download links
1077
+ _e('Your can download the backup files here and now.', 'cpd');
1078
+ echo '<br/>';
1079
+ $tfile = basename($path);
1080
+ $tofile = basename($opath);
1081
+ echo sprintf(__('Backup of counter table saved in %s.', 'cpd'),
1082
+ '<a href="'.$this->dir.'/download.php?f='.$tfile.'&amp;n='.$tname.'">'.$tname.'</a>').'<br/>';
1083
+ echo sprintf(__('Backup of counter options and collection saved in %s.', 'cpd'),
1084
+ '<a href="'.$this->dir.'/download.php?f='.$tofile.'&amp;n='.$toname.'">'.$toname.'</a>');
1085
+ }
1086
+ else
1087
+ {
1088
+ // show link
1089
+ echo sprintf(__('Backup of counter table saved in %s.', 'cpd'),
1090
+ '<a href="'.content_url().$name.'">'.content_url().$name.'</a>').'<br/>';
1091
+ echo sprintf(__('Backup of counter options and collection saved in %s.', 'cpd'),
1092
+ '<a href="'.content_url().$oname.'">'.content_url().$oname.'</a>');
1093
+ }
1094
+ echo '</p></div>';
1095
+ endif;
1096
+ $this->flush_buffers();
1097
+ }
1098
+
1099
+
1100
+
1101
+ function addCollectionToCountries( $visitors, $limit = false )
1102
+ {
1103
+ global $wpdb;
1104
+ if ( $visitors )
1105
+ // visitors
1106
+ $sql = "SELECT country, COUNT(*) c
1107
+ FROM ( SELECT country, COUNT(*) c
1108
+ FROM $wpdb->cpd_counter
1109
+ WHERE ip > 0
1110
+ GROUP BY country, date, ip ) as t
1111
+ GROUP BY country
1112
+ ORDER BY c desc";
1113
+ else
1114
+ // reads
1115
+ $sql = "SELECT country, COUNT(*) c
1116
+ FROM $wpdb->cpd_counter
1117
+ WHERE ip > 0
1118
+ GROUP BY country
1119
+ ORDER BY c DESC";
1120
+ $res = $this->mysqlQuery('rows', $sql, 'getCountries '.__LINE__);
1121
+
1122
+ foreach ( $res as $r )
1123
+ $temp[$r->country] = $r->c;
1124
+
1125
+ // add collection values
1126
+ $coll = get_option('count_per_day_collected');
1127
+ if ($coll)
1128
+ {
1129
+ foreach ($coll as $month)
1130
+ {
1131
+ $countries = explode(';', $month['country']);
1132
+ // country:reads|visitors
1133
+ foreach ($countries as $v)
1134
+ {
1135
+ if (!empty($v))
1136
+ {
1137
+ $x = explode(':', $v);
1138
+ $country = $x[0];
1139
+ $y = explode('|', $x[1]);
1140
+ $value = ($visitors) ? $y[1] : $y[0];
1141
+ if (isset($temp[$country]))
1142
+ $temp[$country] += $value;
1143
+ else
1144
+ $temp[$country] = $value;
1145
+ }
1146
+ }
1147
+ }
1148
+ }
1149
+
1150
+ // max $limit biggest values
1151
+ $keys = array_keys($temp);
1152
+ array_multisort($temp, SORT_NUMERIC, SORT_DESC, $keys);
1153
+ if ($limit)
1154
+ $temp = array_slice($temp, 0, $limit);
1155
+
1156
+ return $temp;
1157
+ }
1158
+
1159
+ /* get collected data */
1160
+
1161
+ function getLastCollectedMonth()
1162
+ {
1163
+ $s = get_option('count_per_day_summary');
1164
+ return (isset($s['lastcollectedmonth'])) ? $s['lastcollectedmonth'] : false;
1165
+ }
1166
+
1167
+ function getCollectedReads()
1168
+ {
1169
+ $s = get_option('count_per_day_summary');
1170
+ return (isset($s['reads'])) ? $s['reads'] : 0;
1171
+ }
1172
+
1173
+ function getCollectedUsers()
1174
+ {
1175
+ $s = get_option('count_per_day_summary');
1176
+ return (isset($s['users'])) ? $s['users'] : 0;
1177
+ }
1178
+
1179
+ function getCollectedDayMostReads()
1180
+ {
1181
+ $s = get_option('count_per_day_summary');
1182
+ return (isset($s['mostreads'])) ? $s['mostreads'] : 0;
1183
+ }
1184
+
1185
+ function getCollectedDayMostUsers()
1186
+ {
1187
+ $s = get_option('count_per_day_summary');
1188
+ return (isset($s['mostusers'])) ? $s['mostusers'] : 0;
1189
+ }
1190
+
1191
+ function getCollectedData( $month ) // YYYYMM
1192
+ {
1193
+ $d = get_option('count_per_day_collected');
1194
+ if ($d)
1195
+ {
1196
+ $m = $d[$month];
1197
+ unset($d);
1198
+ return $m;
1199
+ }
1200
+ }
1201
+
1202
+ /* update if new count is bigger than collected */
1203
+
1204
+ function updateCollectedDayMostReads( $new )
1205
+ {
1206
+ $n = array ($new->date, $new->count);
1207
+ $s = get_option('count_per_day_summary', array());
1208
+ if ( empty($s['mostreads']) || $n[1] > $s['mostreads'][1] )
1209
+ $s['mostreads'] = $n;
1210
+ update_option('count_per_day_summary', $s);
1211
+ return $s['mostreads'];
1212
+ }
1213
+
1214
+ function updateCollectedDayMostUsers( $new )
1215
+ {
1216
+ $n = array ($new->date, $new->count);
1217
+ $s = get_option('count_per_day_summary', array());
1218
+ if ( empty($s['mostusers']) || $n[1] > $s['mostusers'][1] )
1219
+ $s['mostusers'] = $n;
1220
+ update_option('count_per_day_summary', $s);
1221
+ return $s['mostusers'];
1222
+ }
1223
+
1224
+ /**
1225
+ * sets first date in summary
1226
+ */
1227
+ function updateFirstCount()
1228
+ {
1229
+ global $wpdb;
1230
+ // first day in summary
1231
+ $s = get_option('count_per_day_summary', array());
1232
+ if ( empty($s['firstcount']) )
1233
+ {
1234
+ // first day from table ORDER BY date LIMIT 1
1235
+ $res = $this->mysqlQuery('var', "SELECT MIN(date) FROM $wpdb->cpd_counter", 'getFirstCount'.__LINE__);
1236
+ if ($res)
1237
+ {
1238
+ $s['firstcount'] = $res;
1239
+ update_option('count_per_day_summary', $s);
1240
+ }
1241
+ }
1242
+ return $s['firstcount'];
1243
+ }
1244
+
1245
+ /**
1246
+ * returns table size in KB or MB
1247
+ */
1248
+ function getTableSize( $table )
1249
+ {
1250
+ $res = $this->mysqlQuery('rows', "SHOW TABLE STATUS");
1251
+ if ($res)
1252
+ foreach ($res as $row)
1253
+ if ($row->Name == $table)
1254
+ $size = $this->formatBytes( $row->Data_length + $row->Index_length );
1255
+ if ($size)
1256
+ return $size;
1257
+ }
1258
+
1259
+ /**
1260
+ * formats byte integer to e.g. x.xx MB
1261
+ */
1262
+ function formatBytes( $size )
1263
+ {
1264
+ $units = array(' B', ' KB', ' MB', ' GB', ' TB');
1265
+ for ($i = 0; $size >= 1024 && $i < 4; $i++)
1266
+ $size /= 1024;
1267
+ return round($size, 2).$units[$i];
1268
+ }
1269
+
1270
+ /**
1271
+ * flush buffers, the hard way ;)
1272
+ */
1273
+ function flush_buffers()
1274
+ {
1275
+ if (ob_get_length())
1276
+ {
1277
+ @ob_end_flush();
1278
+ @ob_flush();
1279
+ @flush();
1280
+ }
1281
+ @ob_start();
1282
+ }
1283
+
1284
+ /**
1285
+ * formats e.g. 64MB to byte integer
1286
+ */
1287
+ function getBytes($val) {
1288
+ $val = trim($val);
1289
+ $last = strtolower($val{strlen($val)-1});
1290
+ switch($last) {
1291
+ case 'g':
1292
+ $val *= 1024;
1293
+ case 'm':
1294
+ $val *= 1024;
1295
+ case 'k':
1296
+ $val *= 1024;
1297
+ }
1298
+ return $val;
1299
+ }
1300
+
1301
+ } // class
counter-options.php CHANGED
@@ -4,17 +4,16 @@
4
* Count Per Day - Options and Administration
5
*/
6
7
- // Form auswerten
8
if(!empty($_POST['do']))
9
{
10
- //global $wpdb;
11
-
12
switch($_POST['do'])
13
{
14
// update options
15
case 'cpd_update' :
16
$count_per_day->options['onlinetime'] = $_POST['cpd_onlinetime'];
17
$count_per_day->options['user'] = empty( $_POST['cpd_user'] ) ? 0 : 1 ;
18
$count_per_day->options['autocount'] = empty( $_POST['cpd_autocount'] ) ? 0 : 1 ;
19
$count_per_day->options['bots'] = $_POST['cpd_bots'];
20
$count_per_day->options['dashboard_posts'] = $_POST['cpd_dashboard_posts'];
@@ -23,52 +22,298 @@ if(!empty($_POST['do']))
23
$count_per_day->options['show_in_lists'] = empty( $_POST['cpd_show_in_lists'] ) ? 0 : 1 ;
24
$count_per_day->options['chart_days'] = $_POST['cpd_chart_days'];
25
$count_per_day->options['chart_height'] = $_POST['cpd_chart_height'];
26
27
- update_option('count_per_day', $count_per_day->options);
28
29
- echo '<div id="message" class="updated fade"><p>'.__('Options updated', 'cpd').'</p></div>';
30
- break;
31
32
- // clean database
33
- case 'cpd_clean' :
34
- $rows = $count_per_day->cleanDB();
35
- echo '<div id="message" class="updated fade"><p>'.sprintf(__('Database cleaned. %s rows deleted.', 'cpd'), $rows).'</p></div>';
36
- break;
37
38
- // reset counter
39
- case 'cpd_reset' :
40
- $wpdb->query('TRUNCATE TABLE '.CPD_C_TABLE);
41
- echo '<div id="message" class="updated fade"><p>'.sprintf(__('Counter reseted.', 'cpd'), $rows).'</p></div>';
42
break;
43
-
44
- // uninstall plugin
45
- case __('UNINSTALL Count per Day', 'cpd') :
46
- if(trim($_POST['uninstall_cpd_yes']) == 'yes')
47
{
48
- $wpdb->query("DROP TABLE IF EXISTS ".CPD_C_TABLE.";");
49
- $wpdb->query("DROP TABLE IF EXISTS ".CPD_CO_TABLE.";");
50
- delete_option('count_per_day');
51
- echo '<div id="message" class="updated fade"><p>';
52
- printf(__('Table %s deleted', 'cpd'), CPD_C_TABLE);
53
- echo '<br/>';
54
- printf(__('Table %s deleted', 'cpd'), CPD_CO_TABLE);
55
- echo '<br/>';
56
- echo __('Options deleted', 'cpd').'</p></div>';
57
- $mode = 'end-UNINSTALL';
58
}
59
- break;
60
61
- default:
62
- break;
63
}
64
}
65
66
switch($mode) {
67
- // deaktivation
68
case 'end-UNINSTALL':
69
- $deactivate_url = 'plugins.php?action=deactivate&amp;plugin='.dirname(plugin_basename(__FILE__)).'/counter.php';
70
if ( function_exists('wp_nonce_url') )
71
- $deactivate_url = wp_nonce_url($deactivate_url, 'deactivate-plugin_'.dirname(plugin_basename(__FILE__)).'/counter.php');
72
echo '<div class="wrap">';
73
echo '<h2>'.__('Uninstall', 'cpd').' "Count per Day"</h2>';
74
echo '<p><strong><a href="'.$deactivate_url.'">'.__('Click here', 'cpd').'</a> '.__('to finish the uninstall and to deactivate "Count per Day".', 'cpd').'</strong></p>';
@@ -76,133 +321,528 @@ switch($mode) {
76
break;
77
78
default:
79
- // show options page
80
81
$o = $count_per_day->options;
82
?>
83
- <div id="poststuff" class="wrap">
84
85
- <h2><img src="<?php echo $count_per_day->getResource('cpd_menu.gif') ?>" alt="" style="width:24px;height:24px" /> Count per Day</h2>
86
87
<div class="postbox">
88
- <h3><?php _e('Options', 'cpd') ?></h3>
89
<div class="inside">
90
<form method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
91
- <table class="form-table">
92
<tr>
93
- <th nowrap="nowrap" scope="row" style="vertical-align:middle;"><?php _e('Online time', 'cpd') ?>:</th>
94
- <td><input class="code" type="text" name="cpd_onlinetime" size="3" value="<?php echo $o['onlinetime']; ?>" /> <?php _e('Seconds for online counter. Used for "Visitors online" on dashboard page.', 'cpd') ?></td>
95
- </tr>
96
- <tr>
97
- <th nowrap="nowrap" scope="row" style="vertical-align:middle;"><?php _e('Loged on Users', 'cpd') ?>:</th>
98
- <td><label for="cpd_user"><input type="checkbox" name="cpd_user" id="cpd_user" <?php if($o['user']==1) echo 'checked="checked"'; ?> /> <?php _e('count too', 'cpd') ?></label></td>
99
- </tr>
100
- <tr>
101
- <th nowrap="nowrap" scope="row" style="vertical-align:middle;"><?php _e('Auto counter', 'cpd') ?>:</th>
102
- <td><label for="cpd_autocount"><input type="checkbox" name="cpd_autocount" id="cpd_autocount" <?php if($o['autocount']==1) echo 'checked="checked"'; ?> /> <?php _e('Counts automatically single-posts and pages, no changes on template needed.', 'cpd') ?></label></td>
103
- </tr>
104
- <tr>
105
- <th nowrap="nowrap" scope="row" style="vertical-align:middle;"><?php _e('Bots to ignore', 'cpd') ?>:</th>
106
- <td><textarea name="cpd_bots" cols="50" rows="10"><?php echo $o['bots']; ?></textarea></td>
107
- </tr>
108
- <tr>
109
- <th colspan="2"><h3><?php _e('Dashboard') ?></h3></th>
110
- </tr>
111
- <tr>
112
- <th nowrap="nowrap" scope="row" style="vertical-align:middle;"><?php _e('Reads per post', 'cpd') ?>:</th>
113
- <td><input class="code" type="text" name="cpd_dashboard_posts" size="3" value="<?php echo $o['dashboard_posts']; ?>" /> <?php _e('How many posts do you want to see on dashboard page?', 'cpd') ?></td>
114
- </tr>
115
- <tr>
116
- <th nowrap="nowrap" scope="row" style="vertical-align:middle;"><?php _e('Last Reads - Posts', 'cpd') ?>:</th>
117
- <td><input class="code" type="text" name="cpd_dashboard_last_posts" size="3" value="<?php echo $o['dashboard_last_posts']; ?>" /> <?php _e('How many posts do you want to see on dashboard page?', 'cpd') ?></td>
118
- </tr>
119
- <tr>
120
- <th nowrap="nowrap" scope="row" style="vertical-align:middle;"><?php _e('Last Reads - Days', 'cpd') ?>:</th>
121
- <td><input class="code" type="text" name="cpd_dashboard_last_days" size="3" value="<?php echo $o['dashboard_last_days']; ?>" /> <?php _e('How many days do you want look back?', 'cpd') ?></td>
122
- </tr>
123
- <tr>
124
- <th nowrap="nowrap" scope="row" style="vertical-align:middle;"><?php _e('Chart - Days', 'cpd') ?>:</th>
125
- <td><input class="code" type="text" name="cpd_chart_days" size="3" value="<?php echo $o['chart_days']; ?>" /> <?php _e('How many days do you want look back?', 'cpd') ?></td>
126
- </tr>
127
- <tr>
128
- <th nowrap="nowrap" scope="row" style="vertical-align:middle;"><?php _e('Chart - Height', 'cpd') ?>:</th>
129
- <td><input class="code" type="text" name="cpd_chart_height" size="3" value="<?php echo $o['chart_height']; ?>" /> px - <?php _e('Height of the biggest bar', 'cpd') ?></td>
130
- </tr>
131
- <tr>
132
- <th colspan="2"><h3><?php _e('Edit Posts') ?> / <?php _e('Edit Pages') ?></h3></th>
133
- </tr>
134
- <tr>
135
- <th nowrap="nowrap" scope="row" style="vertical-align:middle;"><?php _e('Show in lists', 'cpd') ?>:</th>
136
- <td><label for="cpd_show_in_lists"><input type="checkbox" name="cpd_show_in_lists" id="cpd_show_in_lists" <?php if($o['show_in_lists']==1) echo 'checked="checked"'; ?> /> <?php _e('Show "Reads per Post" in a new column in post management views.', 'cpd') ?></label></td>
137
</tr>
138
</table>
139
- <p class="submit">
140
- <input type="hidden" name="do" value="cpd_update" />
141
- <input type="submit" name="update" value="<?php _e('Update options', 'cpd') ?>" class="button-primary" />
142
</p>
143
</form>
144
</div>
145
</div>
146
-
147
<!-- Cleaner -->
148
<div class="postbox">
149
- <h3><?php _e('Clean the database', 'cpd') ?></h3>
150
<div class="inside">
151
<p>
152
- <?php _e('You can clean the counter table by delete the "spam data".<br />If you add new bots above the old "spam data" keeps in the database.<br />Here you can run the bot filter again and delete the visits of the bots.', 'cpd') ?>
153
</p>
154
155
<form method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
156
- <p class="submit">
157
- <input type="hidden" name="do" value="cpd_clean" />
158
- <input type="submit" name="clean" value="<?php _e('Clean the database', 'cpd') ?>" class="button" />
159
</p>
160
</form>
161
</div>
162
</div>
163
-
164
<!-- Reset DBs -->
165
<div class="postbox">
166
- <h3><?php _e('Reset the counter', 'cpd') ?></h3>
167
<div class="inside">
168
<p style="color: red">
169
<?php _e('You can reset the counter by empty the table. ALL TO 0!<br />Make a backup if you need the current data!', 'cpd') ?>
170
</p>
171
172
<form method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
173
- <p class="submit">
174
<input type="hidden" name="do" value="cpd_reset" />
175
- <input type="submit" name="clean" value="<?php _e('Reset the counter', 'cpd') ?>" class="button" />
176
</p>
177
</form>
178
</div>
179
</div>
180
-
181
<!-- Uninstall -->
182
<form method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
183
<div class="postbox">
184
- <h3><?php _e('Uninstall', 'cpd') ?></h3>
185
<div class="inside">
186
<p>
187
- <b><?php _e('Since WP 2.7 you can delete the plugin directly after deactivation on the plugins page.', 'cpd') ?></b><br />
188
<?php _e('If "Count per Day" only disabled the tables in the database will be preserved.', 'cpd') ?><br/>
189
<?php _e('Here you can delete the tables and disable "Count per Day".', 'cpd') ?>
190
</p>
191
- <p style="text-align: left; color: red">
192
<strong><?php _e('WARNING', 'cpd') ?>:</strong><br />
193
<?php _e('These tables (with ALL counter data) will be deleted.', 'cpd') ?><br />
194
- <b><?php echo CPD_C_TABLE.', '.CPD_CO_TABLE; ?></b><br />
195
<?php _e('If "Count per Day" re-installed, the counter starts at 0.', 'cpd') ?>
196
</p>
197
- <p>&nbsp;</p>
198
- <p class="submit">
199
- <input type="checkbox" name="uninstall_cpd_yes" value="yes" />&nbsp;<?php _e('Yes', 'cpd'); ?><br /><br />
200
- <input type="submit" name="do" value="<?php _e('UNINSTALL Count per Day', 'cpd') ?>" class="button" onclick="return confirm('<?php _e('You are sure to disable Count per Day and delete all data?', 'cpd') ?>')" />
201
</p>
202
</div>
203
</div>
204
</form>
205
206
</div><!-- wrap -->
207
208
- <?php } // End switch($mode) ?>
4
* Count Per Day - Options and Administration
5
*/
6
7
+ // check form
8
if(!empty($_POST['do']))
9
{
10
switch($_POST['do'])
11
{
12
// update options
13
case 'cpd_update' :
14
$count_per_day->options['onlinetime'] = $_POST['cpd_onlinetime'];
15
$count_per_day->options['user'] = empty( $_POST['cpd_user'] ) ? 0 : 1 ;
16
+ $count_per_day->options['user_level'] = $_POST['cpd_user_level'];
17
$count_per_day->options['autocount'] = empty( $_POST['cpd_autocount'] ) ? 0 : 1 ;
18
$count_per_day->options['bots'] = $_POST['cpd_bots'];
19
$count_per_day->options['dashboard_posts'] = $_POST['cpd_dashboard_posts'];
22
$count_per_day->options['show_in_lists'] = empty( $_POST['cpd_show_in_lists'] ) ? 0 : 1 ;
23
$count_per_day->options['chart_days'] = $_POST['cpd_chart_days'];
24
$count_per_day->options['chart_height'] = $_POST['cpd_chart_height'];
25
+ $count_per_day->options['startdate'] = $_POST['cpd_startdate'];
26
+ $count_per_day->options['startcount'] = $_POST['cpd_startcount'];
27
+ $count_per_day->options['startreads'] = $_POST['cpd_startreads'];
28
+ $count_per_day->options['anoip'] = empty( $_POST['cpd_anoip'] ) ? 0 : 1 ;
29
+ $count_per_day->options['clients'] = $_POST['cpd_clients'];
30
+ $count_per_day->options['ajax'] = empty( $_POST['cpd_ajax'] ) ? 0 : 1 ;
31
+ $count_per_day->options['debug'] = empty( $_POST['cpd_debug'] ) ? 0 : 1 ;
32
+ $count_per_day->options['localref'] = empty( $_POST['cpd_localref'] ) ? 0 : 1 ;
33
+ $count_per_day->options['referers'] = empty( $_POST['cpd_referers'] ) ? 0 : 1 ;
34
+ $count_per_day->options['referers_cut'] = empty( $_POST['cpd_referers_cut'] ) ? 0 : 1 ;
35
+ $count_per_day->options['dashboard_referers'] = $_POST['cpd_dashboard_referers'];
36
+ $count_per_day->options['referers_last_days'] = $_POST['cpd_referers_last_days'];
37
+ $count_per_day->options['chart_old'] = empty( $_POST['cpd_chart_old'] ) ? 0 : 1 ;
38
+ $count_per_day->options['no_front_css'] = empty( $_POST['cpd_no_front_css'] ) ? 0 : 1 ;
39
+ $count_per_day->options['whocansee'] = ($_POST['cpd_whocansee'] == 'custom') ? $_POST['cpd_whocansee_custom'] : $_POST['cpd_whocansee'];
40
+ $count_per_day->options['backup_part'] = $_POST['cpd_backup_part'];
41
42
+ if (empty($count_per_day->options['clients']))
43
+ $count_per_day->options['clients'] = 'Firefox, MSIE, Chrome, Safari, Opera';
44
45
+ if ( isset($_POST['cpd_countries']) )
46
+ $count_per_day->options['countries'] = $_POST['cpd_countries'];
47
48
+ update_option('count_per_day', $count_per_day->options);
49
50
+ echo '<div class="updated"><p>'.__('Options updated', 'cpd').'</p></div>';
51
break;
52
+
53
+ // update countries
54
+ case 'cpd_countries' :
55
+ if ( class_exists('CpdGeoIp') )
56
+ {
57
+ $count_per_day->queries[] = 'cpd_countries - class "CpdGeoIp" exists';
58
+ $rest = CpdGeoIp::updateDB();
59
+ echo '<div class="updated">
60
+ <form name="cpdcountries" method="post" action="'.$_SERVER['REQUEST_URI'].'">
61
+ <p>'.sprintf(__('Countries updated. <b>%s</b> entries in %s without country left', 'cpd'), $rest, $wpdb->cpd_counter);
62
+ if ( $rest > 0 )
63
+ echo '<input type="hidden" name="do" value="cpd_countries" />
64
+ <input type="submit" name="updcon" value="'.__('update next', 'cpd').'" class="button" />';
65
+ if ( $rest > 20 )
66
{
67
+ // reload page per javascript until less than 100 entries without country
68
+ if ( !$count_per_day->options['debug'] )
69
+ echo '<script type="text/javascript">document.cpdcountries.submit();</script>';
70
}
71
+ echo '</p>
72
+ </form>
73
+ </div>';
74
+ if ( $rest > 20 )
75
+ $count_per_day->flush_buffers();
76
+ }
77
+ else
78
+ $count_per_day->queries[] = '<span style="color:red">cpd_countries - class "CpdGeoIp" NOT exists</span>';
79
+ break;
80
+
81
+ // download new GeoIP database
82
+ case 'cpd_countrydb' :
83
+ if ( class_exists('CpdGeoIp') )
84
+ {
85
+ $result = CpdGeoIp::updateGeoIpFile();
86
+ echo '<div class="updated"><p>'.$result.'</p></div>';
87
+ if ( file_exists($cpd_path.'geoip/GeoIP.dat') )
88
+ $cpd_geoip = 1;
89
+ }
90
+ break;
91
+
92
+ // delete massbots
93
+ case 'cpd_delete_massbots' :
94
+ if ( isset($_POST['limit']) )
95
+ {
96
+ $bots = $count_per_day->getMassBots($_POST['limit']);
97
+ $sum = 0;
98
+ foreach ($bots as $r)
99
+ {
100
+ $count_per_day->mysqlQuery('', "DELETE FROM $wpdb->cpd_counter WHERE ip = INET_ATON('$r->ip') AND date = '$r->date'", 'deleteMassbots '.__LINE__);
101
+ $sum += $r->posts;
102
+ }
103
+ if ( $sum )
104
+ echo '<div class="updated"><p>'.sprintf(__('Mass Bots cleaned. %s counts deleted.', 'cpd'), $sum).'</p></div>';
105
+ }
106
+ break;
107
+
108
+ // clean database
109
+ case 'cpd_clean' :
110
+ $rows = $count_per_day->cleanDB();
111
+ delete_option('count_per_day_summary');
112
+ delete_option('count_per_day_collected');
113
+ delete_option('count_per_day_posts');
114
+ echo '<div class="updated"><p>'.sprintf(__('Database cleaned. %s rows deleted.', 'cpd'), $rows).'</p></div>';
115
+ break;
116
+
117
+ // reset counter
118
+ case 'cpd_reset' :
119
+ if(trim($_POST['reset_cpd_yes']) == 'yes')
120
+ {
121
+ $wpdb->query('TRUNCATE TABLE '.$wpdb->cpd_counter);
122
+ $wpdb->query('TRUNCATE TABLE '.$wpdb->cpd_counter_useronline);
123
+ $wpdb->query('TRUNCATE TABLE '.$wpdb->cpd_notes);
124
+ echo '<div class="updated"><p>'.sprintf(__('Counter reseted.', 'cpd'), $rows).'</p></div>';
125
+ }
126
+ break;
127
+
128
+ // uninstall plugin
129
+ case __('UNINSTALL Count per Day', 'cpd') :
130
+ if(trim($_POST['uninstall_cpd_yes']) == 'yes')
131
+ {
132
+ count_per_day_uninstall();
133
+ echo '<div class="updated"><p>';
134
+ echo sprintf(__('Table %s deleted', 'cpd'), $wpdb->cpd_counter).'<br/>';
135
+ echo sprintf(__('Table %s deleted', 'cpd'), $wpdb->cpd_counter_useronline).'<br/>';
136
+ echo sprintf(__('Table %s deleted', 'cpd'), $wpdb->cpd_notes).'<br/>';
137
+ echo __('Options deleted', 'cpd').'</p></div>';
138
+ $mode = 'end-UNINSTALL';
139
+ }
140
+ break;
141
+
142
+ // backup counter
143
+ case 'cpd_backup' :
144
+ $count_per_day->backup();
145
+ break;
146
+
147
+ // collect entries
148
+ case 'cpd_collect' :
149
+ // backup first ;)
150
+ $count_per_day->backup();
151
+
152
+ set_time_limit(300);
153
+
154
+ $allnew = (isset($_POST['cpd_new_collection'])) ? 1 : 0;
155
+ if ($allnew)
156
+ {
157
+ delete_option('count_per_day_summary');
158
+ delete_option('count_per_day_collected');
159
+ delete_option('count_per_day_posts');
160
+ }
161
+
162
+ $keep = (isset($_POST['cpd_keep_month'])) ? $_POST['cpd_keep_month'] : 6;
163
+
164
+ $d = array(); // month data
165
+ $t = array(); // temp country data
166
+ $s = array( // summary
167
+ 'reads' => $count_per_day->getCollectedReads(),
168
+ 'users' => $count_per_day->getCollectedUsers() );
169
+ $mold = 0; // current month
170
+ $countryold = '#'; // current country
171
+
172
+ echo '<div id="cpd_progress_collection" class="updated"><p>'.__('Collection in progress...', 'cpd').' ';
173
+ $count_per_day->flush_buffers();
174
+
175
+ $sql = "
176
+ SELECT LEFT(date,7) month, COUNT(*) c, country
177
+ FROM $wpdb->cpd_counter
178
+ WHERE date < DATE_SUB( DATE_FORMAT(CURDATE(), '%%Y-%%m-01'), INTERVAL $keep MONTH )
179
+ GROUP BY date, country, ip
180
+ ORDER BY LEFT(date,7), country";
181
+ $res = $count_per_day->mysqlQuery('rows', $sql, 'getReadsPerMonthsCompress '.__LINE__);
182
+
183
+ foreach ($res as $r)
184
+ {
185
+ $reads = (int) $r->c;
186
+ $s['reads'] += $reads;
187
+ $s['users'] += 1;
188
+ $country = ($r->country) ? $r->country : '-';
189
190
+ if ( $r->month != $mold )
191
+ {
192
+ // new month row
193
+ $month = str_replace('-','',$r->month);
194
+ $d[$month]['reads'] = $reads;
195
+ $d[$month]['users'] = 1;
196
+ $t[$month][$country]['reads'] = $reads;
197
+ $t[$month][$country]['users'] = 1;
198
+ $mold = $r->month;
199
+ echo "| ";
200
+ $count_per_day->flush_buffers();
201
+ }
202
+ else if ( $country != $countryold )
203
+ {
204
+ // new country
205
+ $d[$month]['reads'] += $reads;
206
+ $d[$month]['users'] += 1;
207
+ $t[$month][$country]['reads'] = $reads;
208
+ $t[$month][$country]['users'] = 1;
209
+ $countryold = $country;
210
+ }
211
+ else
212
+ {
213
+ // new visitor/ip
214
+ $d[$month]['reads'] += $reads;
215
+ $d[$month]['users'] += 1;
216
+ $t[$month][$country]['reads'] += $reads;
217
+ $t[$month][$country]['users'] += 1;
218
+ }
219
+ }
220
+
221
+ // format country data as "country:reads|visitors;"
222
+ foreach ($t as $month => $cdata)
223
+ {
224
+ $d[$month]['country'] = '';
225
+ foreach ($cdata as $country => $c)
226
+ $d[$month]['country'] .= $country.':'.$c['reads'].'|'.$c['users'].';';
227
+ $d[$month]['country'] = substr($d[$month]['country'], 0, -1);
228
+ }
229
+ unset($t);
230
+
231
+ // add new to collected data
232
+ $d = get_option('count_per_day_collected', array()) + $d;
233
+
234
+ // summaries
235
+ $last = max(array_keys($d));
236
+ $s['lastcollectedmonth'] = substr($last, 0, 4).'-'.substr($last, 4, 2);
237
+ $s['mostreads'] = $count_per_day->getDayWithMostReads(0, 1);
238
+ $s['mostusers'] = $count_per_day->getDayWithMostUsers(0, 1);
239
+ $s['firstcount'] = $count_per_day->updateFirstCount();
240
+
241
+ // visitors per post
242
+ echo "<br />".__('Get Visitors per Post...', 'cpd')."\n";
243
+ $count_per_day->flush_buffers();
244
+
245
+ $sql = "
246
+ SELECT COUNT(*) count, page
247
+ FROM $wpdb->cpd_counter
248
+ WHERE date < DATE_SUB( DATE_FORMAT(CURDATE(), '%%Y-%%m-01'), INTERVAL $keep MONTH )
249
+ AND page
250
+ GROUP BY page";
251
+ $res = $count_per_day->mysqlQuery('rows', $sql, 'getUsersPerPost