Skip to content

Commit

Permalink
Fix average product rating when ratings are not required
Browse files Browse the repository at this point in the history
If ratings are not required, the total rating count was counting all
reviews which skewed the average rating. In other words, reviews with
no rating were counted as a “zero” rating in the average rating
calculation. This bug was introduced in
83a457b which provided a fix for woocommerce#6839.

This change introduces a new product method `get_review_count()` which
can be used to accurately calculate the total number of reviews for a
product. Some instances of `get_rating_count()` were replaced with
`get_review_count()` where appropriate. Additionally, the
`single-product/rating.php` template was adjusted to display the
correct number of customer reviews and ratings in rich snippets. I’ve
also included the `bestRating` rich snippet detailed
[here](http://schema.org/AggregateRating). The version number was
adjusted to 2.3.2 on that template as I think this is a larger change.
  • Loading branch information
tamarazuk committed Feb 11, 2015
1 parent dd0d8b7 commit 7eaae2d
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 29 deletions.
55 changes: 35 additions & 20 deletions includes/abstracts/abstract-wc-product.php
Original file line number Diff line number Diff line change
Expand Up @@ -1072,26 +1072,13 @@ public function get_rating_count( $value = null ) {

$where_meta_value = $value ? $wpdb->prepare( " AND meta_value = %d", $value ) : " AND meta_value > 0";

if ( get_option( 'woocommerce_enable_review_rating' ) == 'yes' && get_option( 'woocommerce_review_rating_required' ) == 'yes' ) {

$count = $wpdb->get_var( $wpdb->prepare("
SELECT COUNT(meta_value) FROM $wpdb->commentmeta
LEFT JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID
WHERE meta_key = 'rating'
AND comment_post_ID = %d
AND comment_approved = '1'
", $this->id ) . $where_meta_value );

} else {

$count = $wpdb->get_var( $wpdb->prepare("
SELECT COUNT(*) FROM $wpdb->comments
WHERE comment_parent = 0
AND comment_post_ID = %d
AND comment_approved = '1'
", $this->id ) );

}
$count = $wpdb->get_var( $wpdb->prepare("
SELECT COUNT(meta_value) FROM $wpdb->commentmeta
LEFT JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID
WHERE meta_key = 'rating'
AND comment_post_ID = %d
AND comment_approved = '1'
", $this->id ) . $where_meta_value );

set_transient( $transient_name, $count, YEAR_IN_SECONDS );
}
Expand Down Expand Up @@ -1126,6 +1113,34 @@ public function get_rating_html( $rating = null ) {
}


/**
* Get the total amount (COUNT) of reviews.
*
* @since 2.3.2
* @return int The total numver of product reviews
*/
public function get_review_count() {

$transient_name = 'wc_review_count_' . $this->id . WC_Cache_Helper::get_transient_version( 'product' );

if ( false === ( $count = get_transient( $transient_name ) ) ) {

global $wpdb;

$count = $wpdb->get_var( $wpdb->prepare("
SELECT COUNT(*) FROM $wpdb->comments
WHERE comment_parent = 0
AND comment_post_ID = %d
AND comment_approved = '1'
", $this->id ) );

set_transient( $transient_name, $count, YEAR_IN_SECONDS );
}

return apply_filters( 'woocommerce_product_review_count', $count, $this );
}


/**
* Returns the upsell product ids.
*
Expand Down
1 change: 1 addition & 0 deletions includes/class-wc-comments.php
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ public static function clear_transients( $post_id ) {
delete_transient( 'wc_rating_count_' . $post_id . '_3' . $transient_version );
delete_transient( 'wc_rating_count_' . $post_id . '_4' . $transient_version );
delete_transient( 'wc_rating_count_' . $post_id . '_5' . $transient_version );
delete_transient( 'wc_review_count_' . $post_id . $transient_version );
}

/**
Expand Down
2 changes: 1 addition & 1 deletion includes/wc-template-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -964,7 +964,7 @@ function woocommerce_default_product_tabs( $tabs = array() ) {
// Reviews tab - shows comments
if ( comments_open() ) {
$tabs['reviews'] = array(
'title' => sprintf( __( 'Reviews (%d)', 'woocommerce' ), $product->get_rating_count() ),
'title' => sprintf( __( 'Reviews (%d)', 'woocommerce' ), $product->get_review_count() ),
'priority' => 30,
'callback' => 'comments_template'
);
Expand Down
4 changes: 2 additions & 2 deletions templates/single-product-reviews.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*
* @author WooThemes
* @package WooCommerce/Templates
* @version 2.1.0
* @version 2.3.2
*/
global $product;

Expand All @@ -20,7 +20,7 @@
<div id="reviews">
<div id="comments">
<h2><?php
if ( get_option( 'woocommerce_enable_review_rating' ) === 'yes' && ( $count = $product->get_rating_count() ) )
if ( get_option( 'woocommerce_enable_review_rating' ) === 'yes' && ( $count = $product->get_review_count() ) )
printf( _n( '%s review for %s', '%s reviews for %s', $count, 'woocommerce' ), $count, get_the_title() );
else
_e( 'Reviews', 'woocommerce' );
Expand Down
14 changes: 8 additions & 6 deletions templates/single-product/rating.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*
* @author WooThemes
* @package WooCommerce/Templates
* @version 2.2.6
* @version 2.3.2
*/

if ( ! defined( 'ABSPATH' ) ) {
Expand All @@ -17,18 +17,20 @@
return;
}

$count = $product->get_rating_count();
$average = $product->get_average_rating();
$rating_count = $product->get_rating_count();
$review_count = $product->get_review_count();
$average = $product->get_average_rating();

if ( $count > 0 ) : ?>
if ( $rating_count > 0 ) : ?>

<div class="woocommerce-product-rating" itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">
<div class="star-rating" title="<?php printf( __( 'Rated %s out of 5', 'woocommerce' ), $average ); ?>">
<span style="width:<?php echo ( ( $average / 5 ) * 100 ); ?>%">
<strong itemprop="ratingValue" class="rating"><?php echo esc_html( $average ); ?></strong> <?php _e( 'out of 5', 'woocommerce' ); ?>
<strong itemprop="ratingValue" class="rating"><?php echo esc_html( $average ); ?></strong> <?php printf( __( 'out of %s5%s', 'woocommerce' ), '<span itemprop="bestRating">', '</span>' ); ?>
<?php printf( _n( 'based on %s customer rating', 'based on %s customer ratings', $rating_count, 'woocommerce' ), '<span itemprop="ratingCount" class="rating">' . $rating_count . '</span>' ); ?>
</span>
</div>
<?php if ( comments_open() ) : ?><a href="#reviews" class="woocommerce-review-link" rel="nofollow">(<?php printf( _n( '%s customer review', '%s customer reviews', $count, 'woocommerce' ), '<span itemprop="ratingCount" class="count">' . $count . '</span>' ); ?>)</a><?php endif ?>
<?php if ( comments_open() ) : ?><a href="#reviews" class="woocommerce-review-link" rel="nofollow">(<?php printf( _n( '%s customer review', '%s customer reviews', $review_count, 'woocommerce' ), '<span itemprop="reviewCount" class="count">' . $review_count . '</span>' ); ?>)</a><?php endif ?>
</div>

<?php endif; ?>

0 comments on commit 7eaae2d

Please sign in to comment.