ChikunCount – WordPress Plugin
Well, I haven’t blogged anything on here for a while, mainly because I’ve been working on ChikunCount, the first WordPress plugin (WordPress anything really) I’ve worked on. I was actually pleasantly surprised at how easy it is to do development work for WP. So, in the spirit of keeping this a technical blog, I’ll go through some of the key points of ChikunCount, and how it does what it does.
Logging a pageview
Now, the hit counter that I’ve created in all honesty isn’t the most advanced hit counter ever. All it does is log when a page gets viewed. I could expand upon it by checking the times of last hit or session management, and separate page views from visits, but I’m kind of lazy, and I’ve never needed to do that in the past, so it is what it is : ).
So, in WordPress development, you register functions with the WP engine so it will run your functions at the specified time. I use the “get_header” action that the template calls, because if we’re requesting the header, we’re actually viewing the page. Figured it would be a good place to log the hit. In ChikunCount this is accomplished with:
-
add_action('get_header', '_chikuncount_updatehits');
This code is placed in the main body of the php file, and is thus executed when the WP engine includes my plugin file. The first argument ‘get_header’ is the action that we’re hooking, while the second argument is the function within my plugin file that will be ran.
-
function _chikuncount_updatehits() {
-
global $wpdb;
-
-
$table = $wpdb->prefix . 'chikuncounter';
-
-
// We'll just update our hitcounter
-
$ip = $_SERVER['REMOTE_ADDR'];
-
$host = strtolower($_SERVER['HTTP_HOST']);
-
$browser = $_SERVER['HTTP_USER_AGENT'];
-
$page = $_SERVER['REQUEST_URI'];
-
-
// Avoid apache dummy connections
-
if($host == '' || $ip == '::1')
-
return;
-
-
// Ignore favicon and robots.txt
-
if($page == '/favicon.ico' || $page == '/robots.txt')
-
return;
-
-
$sql = "INSERT INTO $table (ip, browser, page, host, time) VALUES ('$ip', '$browser', '$page', '$host', NOW());";
-
-
$wpdb->query($sql);
-
}
And there it is. You may notice the similarities between this function and the functions in my Creating a Hitcounter post, and thats because I pretty much copied that
. The only differences are there for compatibility to WP. Oh, and I also filtered out Apache dummy connections, favicon, and robots…Because ‘cmon, who really wants to count those as hits.
Outputting CSV Files
One of the major points of ChikunCount is that it can export CSV files with quite a few of your hit stats. I haven’t gone through and added all of what I want yet, but more reports are coming for those of you who are using the plugin.
I had some problems deciding exactly how I wanted to action the CSV reports. With WP development, you can’t (not that I’ve found yet, and TBH, I’m rather noobish with WP development) add an action to the admin page without having a menu link for it. Edit: Actually I don’t know why this hadn’t occurred to me but you can use this exact type of function to make multiple “options” pages for your plugin. Normally these actions would be displaying an options page or something similar, but we want to download a CSV file. After trying a couple things out I finally settled on hooking the “admin_init” action, and sending WP through a passthrough function that examines the URL.
-
// Actions we have for reporting
-
// We want this priority 0 sense we're going to be playing with headers
-
add_action('admin_init', '_chikuncount_report', 0);
-
-
function _chikuncount_report() {
-
if(isset($_GET['chikuncount'])) {
-
// We want a report
-
$chikunaction = $_GET['chikuncount'];
-
-
switch($chikunaction) {
-
// Total hits section
-
case "totalhits-byday":
-
_chikuncount_report_totalhits('day');
-
break;
-
case "totalhits-byweek":
-
_chikuncount_report_totalhits('week');
-
break;
-
case "totalhits-bymonth":
-
_chikuncount_report_totalhits('month');
-
break;
-
case "totalhits-byyear":
-
_chikuncount_report_totalhits('year');
-
break;
-
-
// Hits by blog
-
case "hitsbyblog":
-
_chikuncount_report_byblog();
-
break;
-
-
// Unique visitors
-
case "unique-byday":
-
_chikuncount_report_unique('day');
-
break;
-
case "unique-byweek":
-
_chikuncount_report_unique('week');
-
break;
-
case "unique-bymonth":
-
_chikuncount_report_unique('month');
-
break;
-
case "unique-byyear":
-
_chikuncount_report_unique('year');
-
break;
-
-
// Flash section
-
case "sevendays-ofc":
-
_chikuncount_report_totalhits_ofc();
-
break;
-
case "browsers-ofc":
-
_chikuncount_report_browsers_ofc();
-
break;
-
}
-
}
-
}
What we’re doing here is hooking the admin_init function, and checking to see if the GET variable “chikunaction” is set. (In case you were wondering, the third argument for this add_action function is the priority that the function will be called, lower = sooner.) If chikunaction is set, then we take it’s value and send it to the appropriate function to generate the report. If chikunaction is NOT set, or set with something other than a valid function, we just pass through and let execution continue normally.
In the case that we have a valid report to run, here’s one of the functions that makes the magic happen:
-
function _chikuncount_report_totalhits($type) {
-
global $wpdb;
-
-
$table = $wpdb->prefix . 'chikuncounter';
-
-
// Build our sql based on what our type is
-
switch($type) {
-
case 'day':
-
$sql = "SELECT COUNT(ip), DATE(time) FROM $table GROUP BY DATE(time);";
-
$file = 'total-hits-by-day';
-
break;
-
case 'week':
-
$sql = "SELECT COUNT(ip), WEEK(time) FROM $table GROUP BY WEEK(time);";
-
$file = 'total-hits-by-week';
-
break;
-
case 'month':
-
$sql = "SELECT COUNT(ip), MONTH(time) FROM $table GROUP BY MONTH(time);";
-
$file = 'total-hits-by-month';
-
break;
-
case 'year':
-
$sql = "SELECT COUNT(ip), YEAR(time) FROM $table GROUP BY YEAR(time);";
-
$file = 'total-hits-by-year';
-
break;
-
}
-
-
$output = '';
-
-
$result = $wpdb->get_results($sql, ARRAY_N);
-
-
foreach($result as $row) {
-
$output .= $row[1] . ',' . $row[0] . "\r\n";
-
}
-
-
header("Pragma: public");
-
header("Expires: 0");
-
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
-
header("Cache-Control: private",false);
-
header("Content-Type: text/csv");
-
header("Content-Disposition: attachment; filename=\"$file.csv\";");
-
header("Content-Transfer-Encoding: binary");
-
header("Content-Length: ".strlen($output));
-
-
echo $output;
-
-
die();
-
}
Here we’re building our SQL statement based on the type of report we’re running (based on days, weeks, etc) so that we have the correct data. Then taking the SQL results and dumping them into a string that will become our CSV file (format: date,hits\r\ndate,hits). Next we dump some header information to the browser so it knows that we’re sending across a text/csv and not to cache anything. Then we simply echo the CSV string so that the browser picks it up, and stop WP execution by calling die().
Obviously theres a lot more that goes into the plugin than that, and I may elaborate on the rest in some later blog. However, for now it appears we’re out of time. If you want to get into some of the more inner workings of ChikunCount, feel free to download it and rip apart the source code all you want
.
Till next time.
Looks like 1.3 does not work in WP 2.9. I get
- All page hit counts show up as zero.
- This shows up in dashboard for flash graph.
Open Flash Chart
JSON Parse Error [Syntax Error]
Error at character 0, line 1:
0:
- and this shows up when I look at some page hits.
—–
Warning: Invalid argument supplied for foreach() in /home/windy10/public_html/wp/wp-content/plugins/chikuncount/chikuncount.php on line 475
Warning: Cannot modify header information – headers already sent by (output started at /home/windy10/public_html/wp/wp-content/plugins/chikuncount/chikuncount.php:475) in /home/windy10/public_html/wp/wp-content/plugins/chikuncount/chikuncount.php on line 479
Warning: Cannot modify header information – headers already sent by (output started at /home/windy10/public_html/wp/wp-content/plugins/chikuncount/chikuncount.php:475) in /home/windy10/public_html/wp/wp-content/plugins/chikuncount/chikuncount.php on line 480
[...]
—–
be excited to try it again when you’ve fixed it
Thanks,
dj
Hmm… Make sure your actually running 1.3. Not sure what may have happened but those line numbers aren’t matching up to 1.3’s.
I think the real problem might be a conflicting plugin though. I’m using 2.9.1 on this blog atm and it’s acting fine.
I found the reporting page on the dashboard, but it is blank. Just installed from the WP site.
After looking at the code above and after finding the dashboard panel I expected that after a day perhaps the reports might show up on the panel, but they dont.
My Chikuncount dashboard panel is still blank a day and a half after installing it. Have I mis installed it or something? Am I even looking in the right place?
I’m running WP 2.5 not 2.9.1. Is that an issue?
Ok I upgraded to WP 2.9.1 and chikuncount now displays correctly.
@Jay Doggett
Hey, sorry that I couldn’t get to you before now, but good to hear that you’ve got it working! I think I had to change some stuff for 2.9, specifically how it hooks into the wordpress events, but I think an older version on the WP plugin site will work for 2.5.
Hey there,
I have WP version 2.9.2; do you think the plugin would work for me?
Thanks,
The Rat
@The Rat
I just upgraded my blog to 2.9.2 to check for you. Everything seems to be working fine!
Thanks
How to embed the flash chart to a page in WP? i get an error message as it try to create the chart:
Open Flash Chart
IO ERROR
Loading test data
Error #2032
This is the URL that I tried to open:../../data-files/y-axis-auto-steps.txt
Any idea and tutorial for solving the issue?
Best regards Mats in Sweden