Jas
Jas

Reputation: 31

Magento: Show Rating Summary Individually

This is the senario:

I have 5 ratings set up in the backend, and they are: Value, Looks, Usability, Quality and Portability

However, I need to get the summary votes (average) of each of the rating. An example will be: Value: 60% Looks: 50% Usability: 100% Quality: 90% Portability: 70%

The ratings and vote % are the summary/average of all the reviews for the product in the product page. Amazon.com is also using the same style for their ratings.

I can’t get it figured out because Magento seems to only offer the summary of all votes out of the box.

Can someone help? I’m kinda stuck at this. Thanks!

Upvotes: 2

Views: 6151

Answers (6)

Sarvesh Patel
Sarvesh Patel

Reputation: 133

By using database with review id

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$resource = $objectManager->get('Magento\Framework\App\ResourceConnection');
$connection = $resource->getConnection();
$rating_option_vote = $resource->getTableName('rating_option_vote'); //gives table name with prefix
$review_id = 1;
//Select Data from table
$sql_review = "Select * FROM " . $rating_option_vote ." where `review_id` =".$review_id;
$result_review = $connection->fetchAll($sql_review); // gives associated array, table fields as key in array.
$percentage = 0;
if(!empty($result_review)){
    $percentage = $result_review[0]['percent'];
}
echo $percentage;

Upvotes: 0

Nick
Nick

Reputation: 11

You can get Rating collection using this code:

 $collection = Mage::getModel('rating/rating')
        ->getResourceCollection()
        ->addEntityFilter('product')
        ->setPositionOrder()
        ->setStoreFilter(Mage::app()->getStore()->getId())
        ->addRatingPerStoreName(Mage::app()->getStore()->getId())
        ->load();

$collection->addEntitySummaryToItem($_product->getId(), Mage::app()->getStore()->getId());

You can find this code in /app/code/core/Mage/Rating/Block/Entity/Detailed.php

And then display each rating:

<?php if(!empty($collection) && $collection->getSize()): ?>
<table class="ratings-table">
    <col width="1" />
    <col />
    <tbody>
        <?php foreach ($collection as $_rating): ?>
            <?php if($_rating->getSummary()): ?>
                <tr>
                    <th><?php echo $this->__($this->escapeHtml($_rating->getRatingCode())) ?></th>
                    <td>
                        <div class="rating-box">
                            <div class="rating" style="width:<?php echo ceil($_rating->getSummary()) ?>%;"></div>
                        </div>
                    </td>
                </tr>
            <?php endif; ?>
        <?php endforeach; ?>
    </tbody>
</table>

Upvotes: 0

thdoan
thdoan

Reputation: 19097

Here's a plug-and-play solution for Value and Looks (just paste the code into review/product/view/list.phtml and work from there):

<?php
$_items = $this->getReviewsCollection()->getItems();
$valueRatings = array();
$looksRatings = array();
$valueAvg = '';
$looksAvg = '';

if (count($_items) > 0) {
  foreach ($_items as $review) {
    foreach($review->getRatingVotes() as $score) {
      switch ($score->getRatingCode()) {
        case 'Value':
          $valueRatings[] = $score->getPercent();
          break;
        case 'Looks':
          $looksRatings[] = $score->getPercent();
          break;
      }
    }
  }
  $valueAvg = array_sum($valueRatings) / count($valueRatings);
  $looksAvg = array_sum($looksRatings) / count($looksRatings);
}
?>
<p>VALUE Average: <?php echo $valueAvg ?></p>
<p>LOOKS Average: <?php echo $looksAvg ?></p>

Note that $score->getRatingCode() corresponds to the Rating Name in Magento Admin / Catalog / Reviews and Ratings / Manage Ratings.

Upvotes: 0

Ahsan
Ahsan

Reputation: 331

I was looking for same thing.Here is my code.
<?php
$_reviewsCollection = Mage::getModel('review/review')->getCollection()
                ->addStoreFilter(Mage::app()->getStore()->getId())
                ->addStatusFilter('approved')
                ->addEntityFilter('product', $this->getProduct()->getId())
                ->setDateOrder()
                ->addRateVotes()
                ->load();
$_votesArray=array();
$_totalReview=0;
foreach ($_reviewsCollection->getItems() as $_review){   $_totalReview++;
$_votes = $_review->getRatingVotes(); 
    if (count($_votes)){
        foreach ($_votes as $_vote){
                $_votesArray[$_vote->getRatingCode()]=$_votesArray[$_vote->getRatingCode()]+$_vote->getPercent();
        }
    }
}
//print_r($_votesArray);    
?>

<ul>

<?php foreach ($_votesArray as $_key=>$_data){ ?>
                        <li><span><?php echo $_key ?>:</span>
                        <div class="rating-box">
                            <div class="rating" style="width:<?php echo $_data/$_totalReview ?>%"></div>
                        </div>
                        </li>
<?php } ?>  
</ul

Upvotes: 0

Jas
Jas

Reputation: 31

So to answer my own question, this was what I did.

app\code\local\Mage\Catalog\Block\Product\View\RatingSummary.php

class Mage_Catalog_Block_Product_View_RatingSummary extends Mage_Core_Block_Template
{
    public function getRatingAverages() {
        $rating = array();

        $product_id = Mage::registry('product')->getId();

        $resource = Mage::getSingleton('core/resource');
        $cn= $resource->getConnection('core_read');

        $sql = "select rt.rating_code, 
                avg(vote.percent) as percent from ".$resource->getTableName('rating_option_vote')." as vote 
                inner join ".$resource->getTableName('rating')." as rt
                on(vote.rating_id=rt.rating_id)
                inner join ".$resource->getTableName('review')." as rr
                on(vote.entity_pk_value=rr.entity_pk_value)
                where rt.entity_id=1 and vote.entity_pk_value=$product_id and rr.status_id=1
                group by rt.rating_code";
        $rating = $cn->fetchAll($sql);

        return $rating;
    }
}

I cannot find a way to get the rating individually using existing Magento APIs. Perhaps there are other ways, but I don’t know how. So I had to manually run pure SQL queries to the database which isn’t the best way to do it. Basically the above code returns the following:

rating_code => percent

Appearance => 80.6373%
Comfort => 83.2634%
Functionality => 79.7353%

So in my template, I use something similiar to display the result.

$rating_averages = $this=>getRatingAverages();
foreach($rating_averages as $rating) {
   echo $rating['rating_code'] . " => " . $rating['percent'];
}

Which should output the following:

Appearance => 80.6373%
Comfort => 83.2634%
Functionality => 79.7353%

Hope it helps anyone stuck in the same problem!

Upvotes: 1

Joe Mastey
Joe Mastey

Reputation: 27109

You are correct, Magento uses a straight non-weighted average to calculate overall reviews. This is also easy to relate to as a customer (the overall looks like an average). If you'd like to use weighted averages, you will need to change the code that Magento uses to calculate the average rating amount.

Once you've given some effort to that, feel free to come back with any questions you have on that process.

Hope that helps!

Thanks, Joe

Upvotes: 0

Related Questions