A Simple View and Comment Counter

This is a simple plugin I wrote to count post views and comments. I plan to use it to write a Most Popular widget. Perhaps this can be of use to someone.

It requires the Post-Indexer plugin as it adds two columns to that table. Of course you could modify it to use a table of it's own, but me for it's convenient as I use the Post-Indexer plugin extensively.

<?php
/*
 * Plugin name: Post View And Comment Counter
 * Description: Counts post views
 * Version: 1.0
 * Requires at least: WordPress 3.0
 * Author: Elia Morling
 */

// INSTALLATION INSTRUCTIONS:
// 1. Requires the post-indexer plugin
// 2. Run this SQL to update the post-indexer database table
// ALTER TABLE <code>wp_site_posts</code> ADD COLUMN <code>view_count</code> INT NOT NULL
// ALTER TABLE <code>wp_site_posts</code> ADD COLUMN <code>comment_count</code> INT NOT NULL

add_action('wp_head', 'post_view_counter_add');
add_action('comment_post', 'post_comment_post',10,2);
add_action('wp_set_comment_status', 'post_comment_status',10,2);

function post_view_counter_add(){
	global $wpdb, $post, $blog_id;
	// only count posts
	if(!is_single()) {return;}
	// sanity check, must be a post id
	if(!isset($post) || !is_int($post->ID)) {return;}
	// don't count blog authors
	if ( current_user_can('manage_options') ){return;}
	// don't count bots
	$bots = 'Google|msnbot|Rambler|Yahoo|AbachoBOT|accoona|AcioRobot|ASPSeek|CocoCrawler|Dumbot|FAST-WebCrawler|GeonaBot|Gigabot|Lycos|MSRBOT|Scooter|AltaVista|IDBot|eStyle|Scrubby';
 	if ( strpos($bots , $_SERVER['HTTP_USER_AGENT']) === true ){return;}
	// update counter
	$sql = "UPDATE <code>&quot; . $wpdb->base_prefix . &quot;site_posts</code> SET view_count=view_count+1 WHERE post_id=".$post->ID." AND blog_ID=".$blog_id;
	$wpdb->query($sql);
}

function post_comment_post($comment_id, $comment_status){
	global $wpdb, $post, $blog_id;
	// sanity check, must be a post id
	if(!isset($post) || !is_int($post->ID)) {return;}
	// we must predict change to counter, because this hook is run before post count is udpated
	$comment_count = (int) $post->comment_count;
	$comment_count++;
	// don't count blog authors
	// if ( current_user_can('manage_options') ){return;}
	// update counter
	$sql = "UPDATE <code>&quot; . $wpdb->base_prefix . &quot;site_posts</code> SET comment_count=".$comment_count." WHERE post_id=".$post->ID." AND blog_ID=".$blog_id;
	$wpdb->query($sql);
}

function post_comment_status($comment_id, $comment_status){
	global $wpdb, $blog_id;
	$comment = get_comment( $comment_id );
	$post_id = $comment->comment_post_ID;
	$post = get_post($post_id);
	$comment_count = $post->comment_count;
	// we must predict change to counter, because this hook is run before post count is udpated
	if($comment_status==="approve"){$comment_count++;}else{$comment_count--;}
	// update counter
	$sql = "UPDATE <code>&quot; . $wpdb->base_prefix . &quot;site_posts</code> SET comment_count=".$comment_count." WHERE post_id=".$post->ID." AND blog_ID=".$blog_id;
	$wpdb->query($sql);
}
    emorling

    Thanks David. Here is a widget to go with it...

    It displays the recent week's 5 most popular blog posts. It uses this score method: a comment is worth 5 points and a view is worth 1 point. You can tweak this to suit your needs.

    It requires the Avatar and Site-indexer plugins. (And the previously posted plugin of course)

    <?php
    /*
     * Plugin name: Most Popular Blog Posts
     * Description: A list of the past week's most popular blog posts
     * Version: 1.0
     * Requires at least: WordPress 3.0
     * Author: Elia Morling
     */
    class Most_Popular_Blogs_Widget extends WP_Widget {
    	protected $default_title = "Most Popular Blog Posts";
    
        	/** constructor */
        	function Most_Popular_Blogs_Widget() {
            	$widget_ops = array('description' => "Lists the mosts popular blogs and their latest post." );
            	parent::WP_Widget(false, $name = $this->default_title, $widget_ops);
    	}
    
        	/** @see WP_Widget::widget */
    	function widget($args, $instance) {		
    
    		// title
        		extract( $args );
            	$title = apply_filters('widget_title',  $instance['title']);
        		if(!$title){$title=$this->default_title;}
    
        		// get most popular blogs
       	 	echo $before_widget;
         		echo $before_title . $title . $after_title;
         		echo $this->get_listing();
         		echo $after_widget;
    
        	}
    
    	function get_listing(){
    		global $wpdb, $blog_user,$current_user;
    		// each comment is worth 5 points, and each view worth 1 point
    		// you can tweak this in the SELECT below
    		$posts = $wpdb->get_results("SELECT blog_id,post_id,post_title,post_permalink, view_count+comment_count*5 AS points  FROM <code>" . $wpdb->base_prefix . "site_posts</code> WHERE <code>post_published_gmt</code>> DATE_SUB(NOW(), INTERVAL 7 DAY) ORDER BY points DESC LIMIT 5;");
    		$content = "<div class='list_box_container'>";
    		foreach ($posts as $post) {
    			$blog_detailsTmp = get_blog_details($post->blog_id, true);
    			$content.= "<p><div class='list_box'><div id='col1'>";
    			$content.= get_blog_avatar($post->blog_id, 32, 'mystery', '');
    			$content.= "</div><div id='col2'>";
    			$content.= "<a href='".$blog_detailsTmp->siteurl."' style='font-weight:700;'>".$blog_detailsTmp->blogname."</a><br>";
    			$content.= " <a href='".$post->post_permalink."'>".$post->post_title."</a>";
    			$content.= "</div></div></p>";
    		}
    		$content.= "</div>";
    		return $content;
    	}
    
    } // end class
    
    // register widget
    add_action('widgets_init', create_function('', 'return register_widget("Most_Popular_Blogs_Widget");'));