Here's my version, based on both of the answers above. It runs on wp_set_comment_status
changed to approve
.
calc_avg_rating()
counts comments having a field of rating
(if a partuclar comment has no rating
, it simply moves on), and when a new comment is approved, it updates the post meta value of avg_rating
.
Then, for my template, I simply call get_product_rating
, which looks at the post meta field of avg_rating
, that way we're not calculating all of this every time the page is loaded.
add_action("wp_set_comment_status", "calc_average_rating");
function calc_average_rating($comment_ID, $approved) {
if ($approved = 'approve'){
$commentdata=get_comment($comment_ID, ARRAY_A);
$parent_post=get_post($commentdata['comment_post_ID']);
global $wpdb;
$post_id = $parent_post->ID;
$ratings = $wpdb->get_results("
SELECT $wpdb->commentmeta.meta_value
FROM $wpdb->commentmeta
INNER JOIN $wpdb->comments on $wpdb->comments.comment_id=$wpdb->commentmeta.comment_id
WHERE $wpdb->commentmeta.meta_key='rating'
AND $wpdb->comments.comment_post_id=$post_id
AND $wpdb->comments.comment_approved =1
");
$counter = 0;
$average_rating = 0;
if ($ratings) {
foreach ($ratings as $rating) {
$average_rating = $average_rating + $rating->meta_value;
$counter++;
}
//round the average to the nearast 1/2 point
$rating = (round(($average_rating/$counter)*2,0)/2);
} else {
//no ratings
$rating = '';
}
update_post_meta($post_id, 'avg_rating', $rating);
}
}
function get_product_rating() {
$post_id = get_the_ID();
$value = get_post_meta($post_id, 'avg_rating', true);
return $value;
}
Hope this helps someone!