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!
Comments