Popularity Values and View Reports. You can also use the included Template Tags to display post popularity and lists of popular posts on your blog.
Version: 1.3b2
Author: Alex King
Author URI: http://alexking.org/
*/
// Copyright (c) 2005-2007 Alex King. All rights reserved.
//
// Released under the GPL license
// http://www.opensource.org/licenses/gpl-license.php
//
// This is an add-on for WordPress
// http://wordpress.org/
//
// **********************************************************************
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// **********************************************************************
//
// Known Issues
// - When spam comments/pingbacks/trackbacks are deleted or marked as
// spam, their value is not always removed from the posts they were
// applied to. This is because the hooks in WP do not seem to fire
// consistently with sufficient data. Hopefully this will be fixed in
// a future release of WP.
// Special thanks to Martijn Stegink for help with WordPress 2.3 compatibility.
/* -- INSTALLATION --------------------- */
// Change this to "0" below if you don't want to show each post's popularity with the post content
@define('AKPC_SHOWPOP', 1);
// To hide the popularity score on a per post/page basis, add a custom field to the post/page as follows:
// name: hide_popularity
// value: 1
// Change this to "0" if you don't want to show the little [?] that links to the explanation of what the popularity means
@define('AKPC_SHOWHELP', 1);
// If you would like to show lists of popular posts in the sidebar,
// take a look at how it is implemented in the included sidebar.php.
/* ------------------------------------- */
if (!isset($wpdb)) {
require('../../wp-blog-header.php');
akpc_init();
}
load_plugin_textdomain('alexking.org');
if (!function_exists('is_admin_page')) {
function is_admin_page() {
if (function_exists('is_admin')) {
return is_admin();
}
if (function_exists('check_admin_referer')) {
return true;
}
else {
return false;
}
}
}
// -- MAIN FUNCTIONALITY
class ak_popularity_contest {
var $feed_value;
var $home_value;
var $archive_value;
var $category_value;
var $single_value;
var $comment_value;
var $pingback_value;
var $trackback_value;
var $logged;
var $options;
var $top_ranked;
var $current_posts;
function ak_popularity_contest() {
$this->options = array(
'feed_value'
,'home_value'
,'archive_value'
,'category_value'
,'single_value'
,'comment_value'
,'pingback_value'
,'trackback_value'
);
$this->feed_value = 1;
$this->home_value = 2;
$this->archive_value = 4;
$this->category_value = 6;
$this->single_value = 10;
$this->comment_value = 20;
$this->pingback_value = 50;
$this->trackback_value = 80;
$this->logged = 0;
$this->top_ranked = array();
$this->current_posts = array();
}
function get_settings() {
global $wpdb;
$result = mysql_query("
SELECT *
FROM $wpdb->ak_popularity_options
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if (!$result) {
return false;
}
while ($data = mysql_fetch_object($result)) {
if (in_array($data->option_name, $this->options)) {
$temp = $data->option_name;
$this->$temp = $data->option_value;
}
}
return true;
}
function install() {
global $wpdb;
$result = mysql_query("
CREATE TABLE `$wpdb->ak_popularity_options`
(
`option_name` VARCHAR( 50 ) NOT NULL
, `option_value` VARCHAR( 50 ) NOT NULL
)
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if (!$result) {
return false;
}
$this->default_values();
$result = mysql_query("
CREATE TABLE `$wpdb->ak_popularity`
(
`post_id` INT( 11 ) NOT NULL
, `total` INT( 11 ) NOT NULL
, `feed_views` INT( 11 ) NOT NULL
, `home_views` INT( 11 ) NOT NULL
, `archive_views` INT( 11 ) NOT NULL
, `category_views` INT( 11 ) NOT NULL
, `single_views` INT( 11 ) NOT NULL
, `comments` INT( 11 ) NOT NULL
, `pingbacks` INT( 11 ) NOT NULL
, `trackbacks` INT( 11 ) NOT NULL
, `last_modified` DATETIME NOT NULL
, KEY `post_id` ( `post_id` )
)
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if (!$result) {
return false;
}
$this->mine_data();
return true;
}
function default_values() {
global $wpdb;
foreach ($this->options as $option) {
$temp = $this->$option;
$result = mysql_query("
INSERT
INTO $wpdb->ak_popularity_options
VALUES
(
'$option'
, '$temp'
)
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if (!$result) {
return false;
}
}
return true;
}
function update_settings() {
global $wpdb;
foreach ($this->options as $option) {
if (isset($_POST[$option])) {
$this->$option = intval($_POST[$option]);
$temp = $this->$option;
$result = mysql_query("
UPDATE $wpdb->ak_popularity_options
SET option_value = '$temp'
WHERE option_name = '$option'
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if (!$result) {
return false;
}
}
}
$this->recalculate_popularity();
header('Location: '.get_bloginfo('wpurl').'/wp-admin/options-general.php?page=popularity-contest.php&updated=true');
die();
}
function recalculate_popularity() {
global $wpdb;
$result = mysql_query("
UPDATE $wpdb->ak_popularity
SET total = (home_views * $this->home_value)
+ (feed_views * $this->feed_value)
+ (archive_views * $this->archive_value)
+ (category_views * $this->category_value)
+ (single_views * $this->single_value)
+ (comments * $this->comment_value)
+ (pingbacks * $this->pingback_value)
+ (trackbacks * $this->trackback_value)
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
}
function reset_data() {
global $wpdb;
$result = mysql_query("
TRUNCATE $wpdb->ak_popularity
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if (!$result) {
return false;
}
$result = mysql_query("
TRUNCATE $wpdb->ak_popularity_options
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if (!$result) {
return false;
}
$this->default_values();
return true;
}
function create_post_record($post_ID = -1) {
global $wpdb;
if ($post_ID == -1) {
global $post_ID;
}
$result = mysql_query("
SELECT post_id
FROM $wpdb->ak_popularity
WHERE post_id = '$post_ID'
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if (mysql_num_rows($result) == 0) {
$result = mysql_query("
INSERT
INTO $wpdb->ak_popularity
VALUES
(
'$post_ID'
, '0'
, '0'
, '0'
, '0'
, '0'
, '0'
, '0'
, '0'
, '0'
, '".date('Y-m-d H:i:s')."'
)
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
}
}
function delete_post_record($post_ID = -1) {
global $wpdb;
if ($post_ID == -1) {
global $post_ID;
}
$result = mysql_query("
DELETE
FROM $wpdb->ak_popularity
WHERE post_id = '$post_ID'
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
}
function mine_data() {
global $wpdb;
$posts = mysql_query("
SELECT ID
FROM $wpdb->posts
WHERE post_status = 'publish'
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if ($posts && mysql_num_rows($posts) > 0) {
while ($post = mysql_fetch_object($posts)) {
$this->create_post_record($post->ID);
$this->populate_post_data($post->ID);
}
}
return true;
}
function mine_gap_data() {
global $wpdb;
$posts = mysql_query("
SELECT p.ID
FROM $wpdb->posts p
LEFT JOIN $wpdb->ak_popularity pop
ON p.ID = pop.post_id
WHERE pop.post_id IS NULL
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if ($posts && mysql_num_rows($posts) > 0) {
while ($post = mysql_fetch_object($posts)) {
$this->create_post_record($post->ID);
$this->populate_post_data($post->ID);
}
}
}
function populate_post_data($post_id) {
global $wpdb;
// grab existing comments
$result = mysql_query("
SELECT comment_ID
FROM $wpdb->comments
WHERE comment_post_ID = '$post_id'
AND comment_type = ''
AND comment_approved = '1'
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
$count = mysql_num_rows($result);
if ($result && $count > 0) {
// increase post popularity
$result = mysql_query("
UPDATE $wpdb->ak_popularity
SET comments = comments + $count
, total = total + ".($this->comment_value * $count)."
WHERE post_id = '$post_id'
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if (!$result) {
return false;
}
}
// grab existing trackbacks
$result = mysql_query("
SELECT comment_ID
FROM $wpdb->comments
WHERE comment_post_ID = '$post_id'
AND comment_type = 'trackback'
AND comment_approved = '1'
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
$count = mysql_num_rows($result);
if ($result && $count > 0) {
// increase post popularity
$result = mysql_query("
UPDATE $wpdb->ak_popularity
SET trackbacks = trackbacks + $count
, total = total + ".($this->trackback_value * $count)."
WHERE post_id = '$post_id'
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if (!$result) {
return false;
}
}
// grab existing pingbacks
$result = mysql_query("
SELECT comment_ID
FROM $wpdb->comments
WHERE comment_post_ID = '$post_id'
AND comment_type = 'pingback'
AND comment_approved = '1'
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
$count = mysql_num_rows($result);
if ($result && $count > 0) {
// increase post popularity
$result = mysql_query("
UPDATE $wpdb->ak_popularity
SET pingbacks = pingbacks + $count
, total = total + ".($this->pingback_value * $count)."
WHERE post_id = '$post_id'
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if (!$result) {
return false;
}
}
}
function record_view() {
if ($this->logged > 0) {
return true;
}
global $wpdb, $posts;
if (!isset($posts) || !is_array($posts) || count($posts) == 0 || is_admin_page()) {
return;
}
$ids = array();
$ak_posts = $posts;
foreach ($ak_posts as $post) {
$ids[] = $post->ID;
}
if (is_feed()) {
$result = mysql_query("
UPDATE $wpdb->ak_popularity
SET feed_views = feed_views + 1
, total = total + $this->feed_value
WHERE post_id IN (".implode(',', $ids).")
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if (!$result) {
return false;
}
}
else if (is_archive() && !is_category()) {
$result = mysql_query("
UPDATE $wpdb->ak_popularity
SET archive_views = archive_views + 1
, total = total + $this->archive_value
WHERE post_id IN (".implode(',', $ids).")
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if (!$result) {
return false;
}
}
else if (is_category()) {
$result = mysql_query("
UPDATE $wpdb->ak_popularity
SET category_views = category_views + 1
, total = total + $this->category_value
WHERE post_id IN (".implode(',', $ids).")
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if (!$result) {
return false;
}
}
else if (is_single()) {
$result = mysql_query("
UPDATE $wpdb->ak_popularity
SET single_views = single_views + 1
, total = total + $this->single_value
WHERE post_id = '".$ids[0]."'
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if (!$result) {
return false;
}
}
else {
$result = mysql_query("
UPDATE $wpdb->ak_popularity
SET home_views = home_views + 1
, total = total + $this->home_value
WHERE post_id IN (".implode(',', $ids).")
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if (!$result) {
return false;
}
}
$this->logged++;
return true;
}
function record_feedback($type, $action = '+') {
global $wpdb, $comment_post_ID;
switch ($type) {
case 'trackback':
$result = mysql_query("
UPDATE $wpdb->ak_popularity
SET trackbacks = trackbacks $action 1
, total = total $action $this->trackback_value
WHERE post_id = '$comment_post_ID'
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if (!$result) {
return false;
}
break;
case 'pingback':
$result = mysql_query("
UPDATE $wpdb->ak_popularity
SET pingback_views = pingback_views $action 1
, total = total $action $this->pingback_value
WHERE post_id = '$comment_post_ID'
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if (!$result) {
return false;
}
break;
default:
$result = mysql_query("
UPDATE $wpdb->ak_popularity
SET comments = comments $action 1
, total = total $action $this->comment_value
WHERE post_id = '$comment_post_ID'
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if (!$result) {
return false;
}
break;
}
return true;
}
function edit_feedback($comment_id, $action) {
global $wpdb, $comment_post_ID;
switch ($action) {
case 'delete':
if (!isset($comment_post_ID) || empty($comment_post_ID)) {
// Often, this data isn't set for us - without it there is no joy
return;
}
else {
// Unfortunately, this hook happens after the comment
// is already out of the DB, so we don't know what type it was.
// Assuming it was a comment (not a trackback or pingback) is
// the safest solution.
$this->record_feedback('', '-');
}
break;
case 'status':
$result = mysql_query("
SELECT comment_post_ID, comment_type, comment_approved
FROM $wpdb->comments
WHERE comment_ID = '$comment_id'
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if ($result) {
while ($data = mysql_fetch_object($result)) {
if ($data->comment_approved == 'spam') {
$comment_post_ID = $data->comment_post_ID;
$this->record_feedback($data->comment_type, '-');
return;
}
}
}
}
}
function recount_feedback() {
global $wpdb;
$posts = mysql_query("
SELECT ID
FROM $wpdb->posts
WHERE post_status = 'publish'
OR post_status = 'static'
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
if ($posts && mysql_num_rows($posts) > 0) {
$result = mysql_query("
UPDATE $wpdb->ak_popularity
SET comments = 0
, trackbacks = 0
, pingbacks = 0
", $wpdb->dbh) or die(mysql_error().' on line: '.__LINE__);
while ($post = mysql_fetch_object($posts)) {
$this->populate_post_data($post->ID);
}
}
$this->recalculate_popularity();
header('Location: '.get_bloginfo('wpurl').'/wp-admin/options-general.php?page=popularity-contest.php&updated=true');
die();
}
function options_form() {
$temp = new ak_popularity_contest;
print('
'.__('Put this tag within The Loop to show the popularity of the post being shown. The popularity is shown as a percentage of your most popular post. For example, if the popularity total for Post #1 is 500 and your popular post has a total of 1000, this tag will show a value of 50%.', 'alexking.org').'
'.__('Put this tag outside of The Loop (perhaps in your sidebar?) to show a list (like the archives/categories/links list) of your most popular posts. All arguments are optional, the defaults are included in the example above.', 'alexking.org').'
Examples:
<?php akpc_most_popular(); ?>
<li><h2>Most Popular Posts</h2>
<ul>
<?php akpc_most_popular(); ?>
</ul>
</li>
'.__('Put this tag outside of The Loop (perhaps in your sidebar?) to show a list of the most popular posts in a specific category. You may want to use this on category archive pages. All arguments are', 'alexking.org').'
Examples:
<?php akpc_most_popular_in_cat(1); ?>
<php if (is_category()) { akpc_most_popular_in_cat(); } ?>
<?php if (is_category()) { ?>
<li><h2>Most Popular in \'<?php single_cat_title(); ?>\'</h2>
<ul>
<?php akpc_most_popular_in_cat(); ?>
</ul>
</li>
<?php } ?>
'.__('Put this tag outside of The Loop (perhaps in your sidebar?) to show a list of the most popular posts in a specific month. You may want to use this on monthly archive pages.', 'alexking.org').'
Examples:
<?php akpc_most_popular_in_month(\'200504\'); ?>
<php if (is_archive() && is_month()) { akpc_most_popular_in_month(); } ?>
<?php if (is_archive() && is_month()) { ?>
<li><h2>Most Popular in <?php the_time(\'F, Y\'); ?></h2>
<ul>
<?php akpc_most_popular_in_month(); ?>
</ul>
</li>
<?php } ?>
');
}
function show_report($type = 'popular', $limit = 10, $custom = array()) {
global $wpdb;
if (count($custom) > 0 && 1 == 0) {
}
else {
$query = '';
$column = '';
$items = array();
switch ($type) {
case 'category':
$title = $custom['cat_name'];
$items = $wpdb->get_results("
SELECT p.ID AS ID, p.post_title AS post_title, pop.total AS total
FROM $wpdb->posts p
LEFT JOIN $wpdb->ak_popularity pop
ON p.ID = pop.post_id
LEFT JOIN $wpdb->term_relationships tr
ON p.ID = tr.object_id
LEFT JOIN $wpdb->term_taxonomy tt
ON tt.term_taxonomy_id = tr.term_taxonomy_id
WHERE tt.term_id = ".$custom['cat_ID']."
AND p.post_status = 'publish'
ORDER BY pop.total DESC
LIMIT $limit
");
$list = '';
if (count($items) > 0) {
foreach ($items as $item) {
$list .= '
'."\n";
}
}
break;
case 'pop_by_category':
$cats = array();
$cats = $wpdb->get_results("
SELECT name, t.term_id
FROM $wpdb->terms t
LEFT JOIN $wpdb->term_taxonomy tt
ON t.term_id = tt.term_id
WHERE tt.taxonomy = 'category'
ORDER BY name
");
$i = 1;
if (count($cats) > 0) {
foreach ($cats as $cat) {
$temp = array(
'cat_ID' => $cat->term_id
,'cat_name' => $cat->name
);
$this->show_report('category', 10, $temp);
if ($i == 3) {
print('
');
$i = 0;
}
$i++;
}
}
break;
case 'category_popularity':
$title = __('Average by Category', 'alexking.org');
$items = $wpdb->get_results("
SELECT DISTINCT name, AVG(pop.total) AS avg
FROM $wpdb->posts p
LEFT JOIN $wpdb->ak_popularity pop
ON p.ID = pop.post_id
LEFT JOIN $wpdb->term_relationships tr
ON p.ID = tr.object_id
LEFT JOIN $wpdb->term_taxonomy tt
ON tr.term_taxonomy_id = tt.term_taxonomy_id
LEFT JOIN $wpdb->terms t
ON tt.term_id = t.term_id
GROUP BY name
ORDER BY avg DESC
");
$list = '';
if (count($items) > 0) {
foreach ($items as $item) {
$list .= '
'.ceil($item->avg).'
'.$item->name.'
'."\n";
}
}
break;
case 'year':
global $month;
$title = $custom['y'].__(' Average by Month', 'alexking.org');
$items = $wpdb->get_results("
SELECT MONTH(p.post_date) AS month, AVG(pop.total) AS avg
FROM $wpdb->posts p
LEFT JOIN $wpdb->ak_popularity pop
ON p.ID = pop.post_id
WHERE YEAR(p.post_date) = '".$custom['y']."'
GROUP BY month
ORDER BY avg DESC
");
$list = '';
if (count($items) > 0) {
foreach ($items as $item) {
$list .= '
'."\n";
}
}
break;
case 'month_popularity':
$years = array();
$years = $wpdb->get_results("
SELECT DISTINCT YEAR(post_date) AS year
FROM $wpdb->posts
ORDER BY year DESC
");
$i = 2;
if (count($years) > 0) {
foreach ($years as $year) {
$temp = array(
'y' => $year->year
);
$this->show_report('year', 10, $temp);
if ($i == 3) {
print('
');
$i = 0;
}
$i++;
}
}
break;
case 'views_wo_feedback':
$title = __('Views w/o Feedback', 'alexking.org');
$items = $wpdb->get_results("
SELECT p.ID AS ID, p.post_title AS post_title, pop.total AS total
FROM $wpdb->posts p
LEFT JOIN $wpdb->ak_popularity pop
ON p.ID = pop.post_id
WHERE pop.comments = 0
AND pop.pingbacks = 0
AND pop.trackbacks = 0
AND p.post_status = 'publish'
ORDER BY pop.total DESC
LIMIT $limit
");
$list = '';
if (count($items) > 0) {
foreach ($items as $item) {
$list .= '
'."\n";
}
}
break;
case 'date':
$items = $wpdb->get_results("
SELECT p.ID AS ID, p.post_title AS post_title, pop.total AS total
FROM $wpdb->posts p
LEFT JOIN $wpdb->ak_popularity pop
ON p.ID = pop.post_id
WHERE DATE_ADD(p.post_date, INTERVAL $days DAY) $compare DATE_ADD(NOW(), INTERVAL $offset DAY)
AND p.post_status = 'publish'
ORDER BY pop.total DESC
LIMIT $limit
");
$list = '';
if (count($items) > 0) {
foreach ($items as $item) {
$list .= '
'."\n";
}
}
break;
case 'popular':
$items = $wpdb->get_results("
SELECT p.ID AS ID, p.post_title AS post_title, pop.$column AS $column
FROM $wpdb->posts p
LEFT JOIN $wpdb->ak_popularity pop
ON p.ID = pop.post_id
WHERE p.post_status = 'publish'
ORDER BY pop.$column DESC
LIMIT $limit
");
$list = '';
if (count($items) > 0) {
foreach ($items as $item) {
$list .= '
get_results("
SELECT p.*, pop.*
FROM $wpdb->posts p
LEFT JOIN $wpdb->ak_popularity pop
ON p.ID = pop.post_id
WHERE p.post_status = 'publish'
ORDER BY pop.total DESC
LIMIT ".intval($limit)
);
if ($posts) {
$bgcolor = '';
foreach ($posts as $post) {
start_wp();
$class = ('alternate' == $class) ? '' : 'alternate';
?>
$column_display_name) {
switch($column_name) {
case 'popularity':
?>