I have always been a big fan of extended functionality, but never a big fan of means to extend by using plugins. Not that plugins are bad, but usually they have the tendency of slowing things down, and that is something not to commend. In the other hand, for the ‘unfortunate’ luck of WordPress being so popular, there are so many plugins in the repository, I suspect there is a developer in the world who hasn’t created his own. I’m thinking whether my grand-mother has developed one yet. Not everything that shines is gold.

After reading this write up by Gines, I suggested not to always rely on plugins, instead try to avoid them where possible. Although he makes a good point when says:

But for our friends who’s not in to coding, queries, development, plugins will have to do.

Anyway, as I challenged myself towards it, I jumped on and started to write my own Top Commentators function so I could list them on the sidebar. Surprisingly Matt listed as second top commenter, and it is a bit odd you know.

Now if you (as I) want to list your blogs Top Commentators lets go on and do some coding. Fire up your favorite code editor and open your themes function.php file in it.

Initially we need to create our function, I called it top_commentators() as its intention clearly indicates.

function top_commentators($show = 5){

Next step we globalize $wpdb class for our use, and execute our query to retrieve the required information from the database.

	//Globalize $wpdb class
	global $wpdb;
        //check for function results cache
        if (false === ( $comments = get_transient('comments') ) ) {
	//Execute Query and Store Results
	$comments = $wpdb->get_results('
		SELECT COUNT(comment_author_email) AS comments_count,
		comment_author_email, comment_author, comment_author_url
		FROM '.$wpdb->comments.'
		WHERE
			user_id != 1 AND comment_approved = 1
			AND comment_type = "" AND comment_author_email != ""
		GROUP BY comment_author_email
		ORDER BY comments_count DESC, comment_author ASC
		LIMIT '.$show );
    //Store cache in Database with 24 hours expiration time
    set_transient('comments', $comments, 60*60*24);
}

Some explanation might be necessary here. Note where the WHERE clause starts and the following code. I apply some restrictions here, first I use user_id != 1 to filter myself off the list, then I check comment_approved = 1 whether the comment is approved, then again I tell to look for comments comment_type = “” that are actual comments, not trackbacks or pingbacks and = “” looks for comments by default, no need to write the word within the quotes. And finally I ask comment_author_email != “” not to be blank. You can remove some or apply more if you wish.
The code from the above block, will execute the SQL statement and store it in the $comments variable as an array.

Finally, we need to organize our information structure, how we want to list them.
I chose div > p over ul > li combination just because I can.

	//Prepare HTML Output Structure
	$output = '<div id="topcommentators"><h3>Top Commentators</h3>';

	//Loop through found records
	foreach($comments as $comment){

	//Check if Commenter has provided a Website URL
	//if YES, link his/her info his/her site URL
    if($comment->comment_author_url){
		$output .= '<p><a href="'.$comment->comment_author_url.'" title="'.$comment->comment_author.'">'.get_avatar($comment->comment_author_email, $size='24', $default='', $comment->comment_author).' '.$comment->comment_author.' ('.$comment->comments_count.')</a></p>'.PHP_EOL;
    }
    else { //If Commenter hasn't provided an URL to his site then display the rest of the information
		$output .= '<p>'.get_avatar($comment->comment_author_email, $size='24', $default='', $comment->comment_author).' '.$comment->comment_author.' ('.$comment->comments_count.')</p>'.PHP_EOL;
      }
    }
	//End HTML Output
	$output .= '</div>';
	//Print results in the browser
	echo $output;
}

Basically, this is the easy part. After we retrieve the information we store the information into the $output variable and finally we echo everything to its own place. I was forced to do an if {} else check, because $comment->comment_author_url would return home blogs URL in case the comment author didn’t put his own. That was weird though. And we show the commentators’ Gravatar if there is one, or the default is returned.

Now, of course this doesn’t do anything on it’s own, so we need to call it anywhere we want to show our valued TOP Commentators who make our blogs look so neat and useful, and trustworthy, and worth spending our time, and much more.

Go ahead now, put this <?php top_commentators(); ?> wherever you want to list your TOP FIVE. I decided sidebar, yours can be footer or anywhere else on your blog. You can, however, alter the returned number of top comment authors to your satisfaction, say 10 for instance, simply by adding a desired value to the function:
<?php top_commentators(10); ?>

And last but doubtlessly not least, comes the CSS part where we “fancyfy” the output. Here’s what I used, change it to fit you best.

div#topcommentors p {
	margin: 0 0 5px;
	padding: 0;
	border-bottom: 1px dashed #ccc;
}
div#topcommentors p:hover { background: #f1f1f1; }

That was all it took to get what we wanted, in our own without activating YAMP (Yet Another More Plugin).
Let me know if it worked for you, if any troubles arise while trying to realize this on your own, just send me a nudge in the Comment form below. I’d try to assist you as best as I can.

And this would be the complete top_commentators() function code, just in case.

//Top Comment Authors
function top_commentators($show = 5){

	//Globalize $wpdb class
	global $wpdb;

        //check for function results cache
        if (false === ( $comments = get_transient('comments') ) ) {	

	//Execute Query and Store Results
	$comments = $wpdb-&gt;get_results('
		SELECT COUNT(comment_author_email) AS comments_count,
		comment_author_email, comment_author, comment_author_url
		FROM '.$wpdb-&gt;comments.'
		WHERE
			user_id != 1 AND comment_approved = 1
			AND comment_type = &quot;&quot; AND comment_author_email != &quot;&quot;
		GROUP BY comment_author_email
		ORDER BY comments_count DESC, comment_author ASC
		LIMIT '.$show );

    //Store cache in Database with 24 hours expiration time
    set_transient('comments', $comments, 60*60*24);
}
	//Prepare HTML Output Structure
	$output = '&lt;div id=&quot;topcommentors&quot;&gt;&lt;h3&gt;Top Commentors&lt;/h3&gt;';

	//Loop through found records
	foreach($comments as $comment){

	//Check if Commenter has provided a Website URL
	//if TRUE, show URL and the rest of the information
    if($comment-&gt;comment_author_url){
		$output .= '&lt;p&gt;&lt;a href=&quot;'.$comment-&gt;comment_author_url.'&quot; title=&quot;'.$comment-&gt;comment_author.'&quot;&gt;'.get_avatar($comment-&gt;comment_author_email, $size='24', $default='', $comment-&gt;comment_author).' '.$comment-&gt;comment_author.' ('.$comment-&gt;comments_count.')&lt;/a&gt;&lt;/p&gt;'.PHP_EOL;
    }
    else { //If Commenter hasn't provided an URL to his site then display the rest of the information
		$output .= '&lt;p&gt;'.get_avatar($comment-&gt;comment_author_email, $size='24', $default='', $comment-&gt;comment_author).' '.$comment-&gt;comment_author.' ('.$comment-&gt;comments_count.')&lt;/p&gt;'.PHP_EOL;
      }
    }
	//End HTML Output
	$output .= '&lt;/div&gt;';
	//Print results in the browser
	echo $output;
} //End Function

Download this function in a file: Function Top Commentators

Update: Thanks to our friend Pepe for asking in the comments, I’ve added two more lines in the second and final code blocks. Now it checks for cache if exists in Database, if not it’ll set a cache and an expiration time. This means the query will be executed once in 24 hours. You should see two new rows in wp_options table _transient_timeout_comments and _transient_comments.