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()) { ?> 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 . '' . $stars . ' ' . $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("\"Star\"", $class, '1'); $html .= sprintf("\"Star\"", $class, '2'); $html .= sprintf("\"Star\"", $class, '3'); $html .= sprintf("\"Star\"", $class, '4'); $html .= sprintf("\"Star\"", $class, '5'); break; case .5: $html .= sprintf("\"Star\"", $class, '1'); $html .= sprintf("\"Star\"", $class, '2'); $html .= sprintf("\"Star\"", $class, '3'); $html .= sprintf("\"Star\"", $class, '4'); $html .= sprintf("\"Star\"", $class, '5'); break; case 1: $html .= sprintf("\"Star\"", $class, '1'); $html .= sprintf("\"Star\"", $class, '2'); $html .= sprintf("\"Star\"", $class, '3'); $html .= sprintf("\"Star\"", $class, '4'); $html .= sprintf("\"Star\"", $class, '5'); break; case 1.5: $html .= sprintf("\"Star\"", $class, '1'); $html .= sprintf("\"Star\"", $class, '2'); $html .= sprintf("\"Star\"", $class, '3'); $html .= sprintf("\"Star\"", $class, '4'); $html .= sprintf("\"Star\"", $class, '5'); break; case 2: $html .= sprintf("\"Star\"", $class, '1'); $html .= sprintf("\"Star\"", $class, '2'); $html .= sprintf("\"Star\"", $class, '3'); $html .= sprintf("\"Star\"", $class, '4'); $html .= sprintf("\"Star\"", $class, '5'); break; case 2.5: $html .= sprintf("\"Star\"", $class, '1'); $html .= sprintf("\"Star\"", $class, '2'); $html .= sprintf("\"Star\"", $class, '3'); $html .= sprintf("\"Star\"", $class, '4'); $html .= sprintf("\"Star\"", $class, '5'); break; case 3: $html .= sprintf("\"Star\"", $class, '1'); $html .= sprintf("\"Star\"", $class, '2'); $html .= sprintf("\"Star\"", $class, '3'); $html .= sprintf("\"Star\"", $class, '4'); $html .= sprintf("\"Star\"", $class, '5'); break; case 3.5: $html .= sprintf("\"Star\"", $class, '1'); $html .= sprintf("\"Star\"", $class, '2'); $html .= sprintf("\"Star\"", $class, '3'); $html .= sprintf("\"Star\"", $class, '4'); $html .= sprintf("\"Star\"", $class, '5'); break; case 4: $html .= sprintf("\"Star\"", $class, '1'); $html .= sprintf("\"Star\"", $class, '2'); $html .= sprintf("\"Star\"", $class, '3'); $html .= sprintf("\"Star\"", $class, '4'); $html .= sprintf("\"Star\"", $class, '5'); break; case 4.5: $html .= sprintf("\"Star\"", $class, '1'); $html .= sprintf("\"Star\"", $class, '2'); $html .= sprintf("\"Star\"", $class, '3'); $html .= sprintf("\"Star\"", $class, '4'); $html .= sprintf("\"Star\"", $class, '5'); break; case 5: $html .= sprintf("\"Star\"", $class, '1'); $html .= sprintf("\"Star\"", $class, '2'); $html .= sprintf("\"Star\"", $class, '3'); $html .= sprintf("\"Star\"", $class, '4'); $html .= sprintf("\"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; } ?>