<?php/** * Plugin Name: Rate and Comment * Plugin URI: http://www.headzoo.com * Author: Sean Hickey * Author URI: http://www.headzoo.com * Version: 1.0 * Description: Rate a post only when a comment is left *//**do_action('rating_comment', $before, $after);do_action('commentor_vote', $before, $after);do_action('current_vote', $postID, $before, $after, $noVoteText);do_action('total_votes', $postID, $before, $after, $noVoteText);*/define('RAC_PATH', ABSPATH . '/wp-content/plugins/rate_comment');define('RAC_URL', get_bloginfo('url') . '/wp-content/plugins/rate_comment');/** * Rate and Comment class * * @author Sean Hickey * @version 1.0 * @todo */class RAC { /** * The $wpdb object. * @var obj */ var $wpdb; /** * The database table prefix. * @var string */ var $table_prefix; /** * The full path to the plugin directory. * @var string */ var $path; /** * The URL to the plugin directory. * @var string */ var $url; /** * Class constructor * * @param obj $wpdb The $wpdb object * @param string $table_prefix The database table prefix * @param string $path The full path to the plugin directory * @param string $url The URL to the plugin directory * @return void */ function RAC(&$wpdb, $table_prefix, $path, $url) { $this->wpdb = & $wpdb; $this->table_prefix = $table_prefix; $this->path = $path; $this->url = $url; $this->wpdb->comment_votes = $table_prefix . 'comment_votes'; add_action('wp_head', array(&$this, 'wpHead')); add_action('comment_form', array(&$this, 'ratingComment')); add_action('activate_rate_comment/rate_comment.php', array(&$this, 'install')); add_action('comment_post', array(&$this, 'castVote')); add_action('delete_comment', array(&$this, 'deleteComment')); } /** * Remove vote when a comment is deleted * * When a comment is deleted, this method checks to see if a vote was made with that * comment. If so, the vote is removed, and the average rating for that post is * changed, so that it was like the vote was never cast in the first place. Returns * the comment ID. * * @param int $commentID The ID for the comment being deleted * @return int */ function deleteComment($commentID) { $commentID = (int) $commentID; $comment = $this->wpdb->get_results("SELECT ID, post_ID FROM `{$this->wpdb->comment_votes}` WHERE `comment_ID` = $commentID", ARRAY_A); if (empty($comment)) { return $commentID; } $commentID = (int) $comment[0]['ID']; $commentPostID = (int) $comment[0]['post_ID']; $this->wpdb->query("DELETE FROM `{$this->wpdb->comment_votes}` WHERE ID = $commentID"); $allPostComments = $this->wpdb->get_results("SELECT vote FROM `{$this->wpdb->comment_votes}` WHERE `post_ID` = $commentPostID", ARRAY_A); $totalVotes = count($allPostComments); $voteCount = 0; for ($i = 0; $i < $totalVotes; $i++) { $voteCount += $allPostComments[$i]['vote']; } $newAverage = round(($voteCount / $totalVotes), 1); $this->wpdb->query("UPDATE `{$this->wpdb->posts}` SET `total_vote` = `total_vote` - 1, `post_current_vote` = $newAverage"); return $commentID; } /** * Add JS/CSS to document head * * Adds the required JavaScript and CSS stylesheet to the document's * head. * * @return void */ function wpHead() { if (is_single()) { ?> <script type="text/javascript"> var siteURL = '<?php echo $this->url; ?>'; </script> <script type="text/javascript" src="<?php echo $this->url; ?>/head.js"></script> <link rel="stylesheet" type="text/css" href="<?php echo $this->url; ?>/head.css" /> <?php } } /** * Remove the add to comment form action * * If the rating_comment() function is used, then don't autoinsert the rating stars in * the comment form. * * @return void */ function functionCalled() { remove_action('comment_form', array(&$this, 'ratingComment')); } /** * Writes a vote to the database * * After the comment form has been submitted, this method will check to see * if a vote has been cast, and then records that vote to the database. Always * returns TRUE. * * @return bool */ function castVote($commentID) { $commentID = (int) $commentID; if (empty($_POST['newvote'])) { return true; } if ($_POST['newvote'] == 0 || $_POST['newvote'] == '0') { return true; } $postID = (int) $_POST['newvotepostid']; $ipAddress = $this->wpdb->escape($_SERVER['REMOTE_ADDR']); if ($this->hasVotedAlready($postID)) { return true; } $totalVotes = $this->wpdb->get_var("SELECT total_vote FROM `{$this->wpdb->posts}` WHERE `ID` = {$postID}"); $currentVote = $this->wpdb->get_var("SELECT post_current_vote FROM `{$this->wpdb->posts}` WHERE `ID` = {$postID}"); if (empty($totalVotes)) { $totalVotes = 0; } if (empty($currentVote)) { $currentVote = 0; } $currentVote += (int) $_POST['newvote']; $totalVotes++; $currentVote = round($currentVote / $totalVotes, 1); $this->wpdb->query("INSERT INTO `{$this->wpdb->comment_votes}` VALUES (null, '$ipAddress', '{$_POST['newvote']}', {$postID}, {$commentID})"); $this->wpdb->query("UPDATE `{$this->wpdb->posts}` SET `total_vote` = $totalVotes, `post_current_vote` = $currentVote WHERE ID = {$postID}"); return true; } /** * Displays the vote left by a commentor * * Used inside the comments loop, this method will display the number of * stars left by the commentor. * * @param string $before String to display before the stars * @param string $after String to display after the stars * @return void */ function commentorVote($before = null, $after = null) { global $comment; $vote = $this->wpdb->get_var("SELECT `vote` FROM {$this->wpdb->comment_votes} WHERE `comment_id` = {$comment->comment_ID}"); if (empty($vote) || $vote == 0) { return; } $stars = $this->getStars($vote, true); echo $before . $stars . $after; } /** * Method that displays rating form * * This method displays the rating stars. * * @param int $postID The ID of the post * @param string $before String to display before the stars * @param string $after String to display after the stars * @return void */ function ratingComment($postID = null, $before = null, $after = null) { global $post; $currentVote = $this->getCurrentVote($post->ID); $stars = $this->getStars($currentVote, $this->hasVotedAlready($post->ID)); echo $before . '<span id="rating_star_group">' . $stars . '</span> <input type="hidden" id="rating_comment" name="newvote" value="0" /><input type="hidden" name="newvotepostid" value="' . $post->ID . '" />' . $after; } /** * Create star HTML * * Generates the rating star HTML. Adds the JavaScript and CSS to the stars if * the person hasn't voted already. * * @param int $vote The current vote for the post * @param int $hasVoted 0 if the person hasn't voted yet, anything else if they have * @return string */ function getStars($vote, $hasVoted) { $html = ''; $starOn = $this->url . '/star_on.png'; $starOff = $this->url . '/star_off.png'; $starHalf = $this->url . '/star_half.png'; if (!$hasVoted) { $js = ' onclick="ratingComment(%s);" '; $class = 'rating_star'; } else { $js = ''; $class = 'rated_star'; } switch ($vote) { case 0: $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '1'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '2'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '3'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '4'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '5'); break; case .5: $html .= sprintf("<img class=\"%s\" src=\"$starHalf\" $js alt=\"Star\" />", $class, '1'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '2'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '3'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '4'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '5'); break; case 1: $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '1'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '2'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '3'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '4'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '5'); break; case 1.5: $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '1'); $html .= sprintf("<img class=\"%s\" src=\"$starHalf\" $js alt=\"Star\" />", $class, '2'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '3'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '4'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '5'); break; case 2: $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '1'); $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '2'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '3'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '4'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '5'); break; case 2.5: $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '1'); $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '2'); $html .= sprintf("<img class=\"%s\" src=\"$starHalf\" $js alt=\"Star\" />", $class, '3'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '4'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '5'); break; case 3: $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '1'); $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '2'); $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '3'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '4'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '5'); break; case 3.5: $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '1'); $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '2'); $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '3'); $html .= sprintf("<img class=\"%s\" src=\"$starHalf\" $js alt=\"Star\" />", $class, '4'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '5'); break; case 4: $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '1'); $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '2'); $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '3'); $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '4'); $html .= sprintf("<img class=\"%s\" src=\"$starOff\" $js alt=\"Star\" />", $class, '5'); break; case 4.5: $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '1'); $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '2'); $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '3'); $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '4'); $html .= sprintf("<img class=\"%s\" src=\"$starHalf\" $js alt=\"Star\" />", $class, '5'); break; case 5: $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '1'); $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '2'); $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '3'); $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '4'); $html .= sprintf("<img class=\"%s\" src=\"$starOn\" $js alt=\"Star\" />", $class, '5'); break; } return $html; } /** * Get vote for post ID * * Returns the current vote for the given post ID. * * @param int $postID The ID for the post * @return float */ function getCurrentVote($postID) { $postID = (int) $postID; $currentVote = $this->wpdb->get_var("SELECT post_current_vote FROM `{$this->wpdb->posts}` WHERE `ID` = {$postID}"); if (empty($currentVote)) { $currentVote = 0; } return $currentVote; } /** * Returns the number of votes for a post * * Given the post ID, returns the number of times that post has received vots. * * @return int */ function getTotalVotes($postID) { $postID = (int) $postID; $totalVotes = $this->wpdb->get_var("SELECT total_vote FROM `{$this->wpdb->posts}` WHERE `ID` = $postID"); if (empty($totalVotes)) { $totalVotes = 0; } return $totalVotes; } /** * Checks if the person has voted already * * Returns 0 if the person hasn't voted already for this post ID, or anything else if * they have voted. * * @param int $postID The post ID * @return int */ function hasVotedAlready($postID) { $ipAddress = $this->wpdb->escape($_SERVER['REMOTE_ADDR']); return $this->wpdb->get_var("SELECT ID FROM `{$this->wpdb->comment_votes}` WHERE `ip` = '$ipAddress' AND `post_ID` = $postID"); } /** * Install plugin method * * Method that is run when the plugin is activated. If the tables for the * plugin hasn't already been created, they will be created. * * @return void */ function install() { if($this->wpdb->get_var("SHOW TABLES LIKE '{$this->wpdb->comment_votes}'") != $this->wpdb->comment_votes) { require_once(ABSPATH . 'wp-admin/upgrade-functions.php'); $sql = "CREATE TABLE `{$this->wpdb->comment_votes}` ( `ID` BIGINT NOT NULL AUTO_INCREMENT, `ip` VARCHAR( 15 ) NOT NULL , `vote` FLOAT NOT NULL , `post_ID` INT NOT NULL , `comment_ID` BIGINT NOT NULL, PRIMARY KEY ( `ID` ) ) TYPE = MYISAM ;"; dbDelta($sql); $sql = "ALTER TABLE `{$this->wpdb->posts}` ADD `total_vote` BIGINT NOT NULL , ADD `post_current_vote` FLOAT NOT NULL ;"; $this->wpdb->query($sql); $sql = "ALTER TABLE `{$this->wpdb->posts}` ADD INDEX ( `post_current_vote` ) ;"; $this->wpdb->query($sql); } }}$rac = new RAC($wpdb, $table_prefix, RAC_PATH, RAC_URL);/** * Wrapper class for $rac->ratingComment() * * @param string $before String to display before stars * @param string $after String to display after stars * @return void */add_action('rating_comment', 'rating_comment', 10, 2);function rating_comment($before = '', $after = '') { global $rac; $rac->functionCalled(); $rac->ratingComment(null, $before, $after);}/** * Display stars left by commentor * * Displays the number of stars left by the particular commentor. * * @param string $before String to display before the stars * @param string $after String to display after the stars * @return void */add_action('commentor_vote', 'commentor_vote', 10, 2);function commentor_vote($before = '', $after = '') { global $rac; $rac->commentorVote($before, $after);}/** * Returns the star HTML for a particular commentor * * Like the commentor_vote() function, but this one returns the HTML * for the stars, instead of displaying them. * * @return string */function get_commentor_vote() { ob_start(); commentor_vote(); $contents = ob_get_contents(); ob_end_clean(); return $contents;}/** * Returns the rating for a post * * Returns the HTML rating stars for a post. * * @return string */function get_rating_comment() { ob_start(); rating_comment(); $contents = ob_get_contents(); ob_end_clean(); return $contents;}/** * Returns current rating for a post * * Returns the current rating for the given post ID. * * @return float */function get_current_vote($postID) { global $rac; return $rac->getCurrentVote($postID);}/** * Displays the current rating for a post * * Returns the current rating for a given post ID. Text can be set to return if * the post has no votes. * * @param int $postID The ID for the post * @param string $before String to display before the current rating * @param string $after String to display after the current rating * @param string $notRated String to display if the post has no votes * @return string */add_action('current_vote', 'current_vote', 10, 4);function current_vote($postID, $before = '', $after = '', $notRated = 'Not rated yet') { $currVote = get_current_vote($postID); if ($currVote == 0) { $currVote = $notRated; } echo $before . $currVote . $after;}/** * Returns the number of votes for a post * * Returns the number of times votes have been cast for the given post * ID. * * @return int */function get_totalVotes($postID) { global $rac; return $rac->getTotalVotes($postID);}/** * Displays the total votes for a post * * Given a post ID, displays the number of times votes have been cast for that * post. Text can be set to return if there are no votes. * @param int $postID The ID for the post * @param string $before String to display before the total votes * @param string $after String to display after the total votes * @param string $notRated String to display if the post has no votes * @return string */add_action('total_votes', 'totalVotes', 10, 4);function totalVotes($postID, $before = '', $after = '', $noVotes = 'No votes') { $totalVotes = get_totalVotes($postID); if ($totalVotes == 0) { $totalVotes = $noVotes; } echo $before . $totalVotes . $after;}?>