Advertisement
Plugins

Creating a Plugin to Add Votes to Your WordPress Comments Using AJAX

by

WordPress has a good posting system which is extendable so that WordPress can be used to build a lot of different sites rather than just a blog. WordPress also has a very extendable commenting system. The commenting system of WordPress can also be extended in different ways to be used in your WordPress sites. The commenting system can be used as a review forum if the WordPress site is to be made into a product catalog system. The commenting system can be used as answers to questions if the WordPress site is to be used for a Question and Answer site. So the commenting system in WordPress can be moulded or extended to provide functionality th at can enhance the complete site built on WordPress. In this article we are going to write a plugin to add a voting system on the comments which could be useful if the commenting system is used in a different way like in the examples stated above and many others that you can think up.


Step 1 Creating the Plugin

Let's now start by creating the plugin. In our wp-content folder we will create a folder for our plugin called commentsvote. Inside the folder commentsvote create a file commentsvote.php which will be the main file of our plugin. Then we will add the plugin header as follows which will help WordPress to identify our plugin and show it in the plugin list in WordPress' admin. The header is as follows.

<?php
/*
Plugin Name: Vote on Comments
Plugin URI: 
Description: Allows to add votes on comment
Author: Abbas Suterwala
Version: 
Author URI: 
*/
?>

Once we add the header we will be able to see our plugin in the plugin list as follows. We can now activate the plugin.

Now let's setup some variables and scripts which we will use in our plugin. We create constants to define the plugin path and the plugin URL which can be used in different places in the plugin as follows.

<?php
define('VOTECOMMENTSURL', WP_PLUGIN_URL."/".dirname( plugin_basename( __FILE__ ) ) );
define('VOTECOMMENTPATH', WP_PLUGIN_DIR."/".dirname( plugin_basename( __FILE__ ) ) );
?>

Also as we are going to have the functionality to add votes via AJAX we will need a JavaScript file. To add the JavaScript file we create a js folder in our plugin folder and create a commentsvote.js file in it. Once we have created the necessary files our folder structure for the plugin will look as follows.

Then we enqueue the scripts so that the JS files are loaded by the WordPress engine as follows.

<?php
function voteme_enqueuescripts() {
	wp_enqueue_script('votecomment', VOTECOMMENTSURL.'/js/commentsvote.js', array('jquery'));
	wp_localize_script( 'votecomment', 'votecommentajax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
}
add_action('wp_enqueue_scripts', voteme_enqueuescripts);
?>

Step 2 Understanding Some WordPress Function for Comments

WordPress provides support for comments meta in which we can store and retrieve some meta data related to the comment. We are going to store the votes on the comments as comment meta using these supporting functions. Hence here we are going to see what these functions are which WordPress provides.

The first function which we are going to see is get_comment_meta(). This function is similar to get_post_meta(). This function takes the first argument as the comment ID, the second argument as the name of the meta key, the third argument which if set to true returns the value as a string, if set to false or left blank will return an array of all the values for that key.

For more information you can visit the get_comment_meta() page in the WordPress Codex.

The other function which we are going to use is update_comment_meta. This function takes four arguments which are the comment ID, the meta key, the meta value and the previous value.

For more information you can visit the update_comment_meta() page in the WordPress Codex.


Step 3 Displaying the Current Votes Next to the Comment

Now let's add the number of votes and a vote link next to each comment so that the users can vote on the comments. For this first we write a function which will create the link and return it as a string.

<?php
function commentsvote_showlink() {
	$link = "";
	$nonce = wp_create_nonce("commentsvote_nonce");
	$current_CommentID =  get_comment_ID();
	$votes = get_comment_meta($current_CommentID, '_commentsvote', true) != '' ? get_comment_meta($current_CommentID, '_commentsvote', true) : '0';
	$arguments = $current_CommentID.",'".$nonce."'";
	$link = $votes.' <a onclick="commentsvote_add('.$arguments.');">'.'Votes'.'</a>';
	$completelink = '<div id="commentsvote-'.$current_CommentID.'">';
	$completelink .= '<span>'.$link.'</span>';
	$completelink .= '</div>';
	return $completelink;
}
?>

In this function we first get the current comment ID using the WordPress function get_comment_ID(). Then we get the number of votes on comment the using the function get_comment_meta().

Then we create a link in which we call the JavaScript function commentsvote_add() which we will implement in the below steps.

Then let's add this link to every comment using the filter comment_text. We hook into the filter comment_text and add the link as follows.

<?php
function commentsvote_comment_text($content) {
	return $content.commentsvote_showlink();
}
add_filter('comment_text', commentsvote_comment_text);
?>

Now if you visit the individual post page you will see the vote's link as follows.


Step 4 Creating the AJAX Handler for Adding Votes on Comments

Now once we have created the code to show the link let's create the AJAX handlers in WordPress to handle the request. The AJAX request handler is as follows.

<?php
function commentsvote_ajaxhandler() {
	if ( !wp_verify_nonce( $_POST['nonce'], "commentsvote_nonce")) {
		exit("Something Wrong");
	}

	$results = '';
	global $wpdb;

	$commentid = $_POST['commentid'];
	$votecount = get_comment_meta($commentid, '_commentsvote', true) != '' ? get_comment_meta($commentid, '_commentsvote', true) : '0';
	$votecountNew = $votecount + 1;
	update_comment_meta($commentid, '_commentsvote', $votecountNew);

	$results.='<div class="votescore" >'.$votecountNew.'</div>';

	//Return the String
	die($results);
}
// creating Ajax call for WordPress
add_action( 'wp_ajax_nopriv_commentsvote_ajaxhandler', 'commentsvote_ajaxhandler' );
add_action( 'wp_ajax_commentsvote_ajaxhandler', 'commentsvote_ajaxhandler' );
?>

In the AJAX handler we first verify the nonce. Then we get the comment ID and get the number of current votes on the comment using the function get_comment_meta(). Once that is done we increment the current count by one and then update the meta using the function update_comment_meta().

Then we return the updated value back from the AJAX handler.


Step 5 Voting on Comments via AJAX

Now once our link and the AJAX handlers are done we just need to write the JavaScript function to make the AJAX call. The function is as follows.

function commentsvote_add(comment_id,nonce) {

	jQuery.ajax({
		type: 'POST',
		url: votecommentajax.ajaxurl,
		data: {
			action: 'commentsvote_ajaxhandler',
			commentid: comment_id,
			nonce: nonce
		},
		success: function(data, textStatus, XMLHttpRequest) {
			var linkofcomment = '#commentsvote-' + comment_id;
			jQuery(linkofcomment).html('');
			jQuery(linkofcomment).append(data);
		},
		error: function(MLHttpRequest, textStatus, errorThrown) {
			alert(errorThrown);
		}
	});

}

The function basically gets the comment ID and the makes an AJAX call to the AJAX handler. Once the AJAX handler returns the value the JavaScript function retrieves the div of the comment and updates its content with the new number of votes. Now one can click on the vote to add one vote to the comment.


Step 6 Allowing Only Logged in Users to Vote

Now let's enhance the plugin to give an option to the admin to allow only logged in users to vote on comments. To do this we first create a settings page for our plugin. Following is the code to create a settings page.

<?php
// Settings
add_action('admin_menu', 'commentvote_create_menu');
function commentvote_create_menu() {
	add_submenu_page('options-general.php','Comments Vote','Comments Vote','manage_options', __FILE__.'comments_settings_page','comments_settings_page');
}
function comments_settings_page() {
?>
	<div class="wrap">
	<?php
	if( isset( $_POST['commentvotesubmit'] ) ) {
		update_option( 'commentvotelogin' , $_POST[ 'commentvotelogin' ] );
	}
	?>
		<div id="commentvotesetting">
			<form id='commentvotesettingform' method="post" action="">
				<h1><?php echo 'Settings'; ?></h1>
				<input type = 'Radio' Name ='commentvotelogin' value= 'yes' <?php if( get_option('commentvotelogin') == 'yes' ) echo 'checked';?> >Voting allowed to only logged in users
				<br/>
				<input type = 'Radio' Name ='commentvotelogin' value= 'no' <?php if( get_option('commentvotelogin') != 'yes' ) echo 'checked';?> >Voting allowed to non logged in users
				<br/><br/>
				<p class="submit">
				<input type="submit" id="commentvotesubmit" name="commentvotesubmit" class="button-primary" value="<?php echo 'Save'; ?>" />
				</p>
			</form>
		</div>
	</div>
<?php }
?>

Now depending on the setting we will check whether the user is logged in or not before showing the vote link or make the link point to the login page. So the adapted functions commentsvote_showlink() and commentsvote_ajaxhandler() will look as follows.

<?php
function commentsvote_showlink() {
	$link = "";
	$nonce = wp_create_nonce("commentsvote_nonce");
	$current_CommentID =  get_comment_ID();
	$votes = get_comment_meta($current_CommentID, '_commentsvote', true) != '' ? get_comment_meta($current_CommentID, '_commentsvote', true) : '0';
	if( get_option('commentvotelogin') != 'yes' || is_user_logged_in() ) {

		$arguments = $current_CommentID.",'".$nonce."'";
		$link = $votes.' <a onclick="commentsvote_add('.$arguments.');">'.'Votes'.'</a>';
		$completelink = '<div id="commentsvote-'.$current_CommentID.'">';
		$completelink .= '<span>'.$link.'</span>';
		$completelink .= '</div>';
	}
	else {
		$register_link = site_url('wp-login.php', 'login') ;
		$completelink = '<div class="commentlink" >'." <a href=".$register_link.">".$votes." Votes"."</a>".'</div>';
	}
	return $completelink;
}
function commentsvote_ajaxhandler() {
	if ( !wp_verify_nonce( $_POST['nonce'], "commentsvote_nonce")) {
		exit("Something Wrong");
	}

	$results = '';
	global $wpdb;
	if( get_option('commentvotelogin') != 'yes' || is_user_logged_in() ) {

		$commentid = $_POST['commentid'];
		$votecount = get_comment_meta($commentid, '_commentsvote', true) != '' ? get_comment_meta($commentid, '_commentsvote', true) : '0';
		$votecountNew = $votecount + 1;
		update_comment_meta($commentid, '_commentsvote', $votecountNew);

		$results.='<div class="votescore" >'.$votecountNew.'</div>';
	}

	//Return the String
	die($results);
}
?>

So now in case if the admin makes it compulsory that logged in users can only vote and if the logged in user is not logged in he will be pointed to the login page as follows.


Step 7 Showing Most Vote Comments on the Post

Now let's add the functionality to show below each post its top voted posts. To do this we will first have to fetch the comments for the post in descending order of its votes. There is no direct way to sort comments on the basis of their meta hence we will write a custom query for the same. We will write the following function to do it.

function commentsvote_get_top_voted_comments($post_id) {

	$commentids = array();
	global $wpdb;

	$request = "
		select * from $wpdb->comments , $wpdb->commentmeta where 
		$wpdb->comments.comment_post_ID = ".$post_id. 
		" AND $wpdb->comments.comment_ID = $wpdb->commentmeta.comment_ID 
		AND $wpdb->commentmeta.meta_key = '_commentsvote' 
		ORDER BY $wpdb->commentmeta.meta_value+0 DESC;
	";

	$comments = $wpdb->get_results($request);

	foreach ($comments as $comment) {
		array_push( $commentids , $comment->comment_ID );
	}

	return $commentids;
}

This function takes posts as input and then runs a custom query on the wp_comments and wp_commentmeta to fetch the list of top voted comments for the post.

Then we add a function to the filter the_content as follows to show the comment excerpt and the votes below the post.

function show_top_voted_comments($content) {

	$result = "";
	$post_ID = get_the_ID();

	$commentids = commentsvote_get_top_voted_comments($post_ID);

	if (count($commentids) > 0 )
		$result = "Top Comments for this post:<br/>";

	foreach ($commentids as $commentid) {
		$votecount = get_comment_meta($commentid, '_commentsvote', true) != '' ? get_comment_meta($commentid, '_commentsvote', true) : '0';
		$result .=get_comment_excerpt($commentid) .'('.$votecount.')'.'<br/>';
	}

	return $content.$result;

}
add_filter('the_content', show_top_voted_comments);

Now if we see the post it will look as follows.


Conclusion

In case WordPress is used for different kind of sites its basic system and functionalities might not be enough for the site. But as the WordPress system is very extendable we can write plugins like the above to provide extra functionality to suit our needs. So have fun while extending your WordPress site!

Related Posts
  • Code
    WordPress
    Mastering WordPress Meta Data: Understanding and Using ArraysMetadata
    In the first part of this series, we covered what WordPress meta data is, how it can be retrieved, and the various data types (such as objects or arrays) in which it can be returned. Now it's time to learn about the different types of arrays. When you write an array manually you know what its structure is an what the name of each index is. But when you are building arrays by querying a database, you are going to need to do some detective work to determine the structure of the data returned and the names of the indexes.Read More…
  • Code
    PHP
    Creating a Photo Tag Wall With Twilio Picture Messaging & PHPProcedural to oop php retina preview
    Twilio's recently announced Picture Messaging has vastly opened up what we can do with text messaging, now we can attach photos to our text messages and have them get used in different ways. In our case, we are going to build a Photo Tag Wall, which will contain photos linked to tags that will be displayed on a website.Read More…
  • Code
    Theme Development
    Creating a WordPress Theme From Static HTML: Creating Template FilesCreating wordpress theme from html 400
    In the first part of this series, I showed you how to prepare your HTML and CSS files for WordPress, ensuring the structure would work, the code was valid and that the correct classes were being used. In this tutorial you'll learn how to take your index.html file and split it up into a set of template files for use by WordPress.Read More…
  • Code
    Plugins
    Using HighCharts in WP-AdminHighcharts 400
    Charts are a great way to present data. They make data more digestible by making it visually appealing. In WordPress, there is no built-in method for getting posts and pages data in a graphical form. Although, there are certain plugins available which integrate Google Analytics with WordPress, but they are overkill if you want to get only a portion of that data. Also, nothing should keep you from learning new techniques and to dive straight into the subject is the best way to learn.Read More…
  • Code
    PhoneGap
    PhoneGap: Build a Feed Reader - Project StructurePhonegap feed reader@2x
    Although not specifically created to work together, jQuery Mobile and Cordova (also known as PhoneGap) are a very powerful duo to create hybrid, mobile apps. This series will teach you how to develop a feed reader using web technologies and these two frameworks. Over the course of this series, you'll also become familiar with the Cordova Connection and Storage Core Plugins and the Google Feed API.Read More…
  • Code
    Plugins
    Integrating Multiple Choice Quizzes in WordPress – Creating the FrontendIntegrating multiple choice quizzes in wordpress
    This is the second part of the series on developing a multiple choice quiz plugin for WordPress. In the first part we created the backend of our plugin to capture the necessary data to store in the database. In this final part, we will be creating the frontend of the plugin where the users can take quizzes and evaluate their knowledge.Read More…