Question

On the product view page the reviews get loaded via the following code:

$_items = $block->getReviewsCollection()->getItems();

This is what the getReviewsCollection function looks like:

public function getReviewsCollection()
{
    if (null === $this->_reviewsCollection) {
        $this->_reviewsCollection = $this->_reviewsColFactory->create()->addStoreFilter(
            $this->_storeManager->getStore()->getId()
        )->addStatusFilter(
            \Magento\Review\Model\Review::STATUS_APPROVED
        )->addEntityFilter(
            'product',
            $this->getProduct()->getId()
        )->setDateOrder();
    }
    return $this->_reviewsCollection;
}

This is later used in the following way:

foreach ($_items as $_review):
    ...
    ...
    foreach ($_review->getRatingVotes() as $_vote):
        ...
        ...

I'm trying to replicate this in order to display the recently reviewed products on the category pages. My code so far looks like this:

public function __construct(
    \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
    \Magento\Framework\Registry $registry,
    \Magento\Review\Model\ResourceModel\Review\CollectionFactory $reviewCollection,
    \Magento\Store\Model\StoreManagerInterface $storeManager, 
    \Magento\Framework\View\Element\Template\Context $context,
    array $data = []
) {
    $this->productRepository = $productRepository;
    $this->registry = $registry;
    $this->reviewCollection = $reviewCollection;
    $this->storeManager = $storeManager;
    parent::__construct($context, $data);
}

public function getCollection()
{
    $category = $this->registry->registry('current_category');
    $collection = $category->getProductCollection();

    foreach( $collection as $product ) {

        // this is the method from the magento
        // core function (getReviewsCollection()) mentioned above
        $reviewCollection = $this->reviewCollection->create()
            ->addStoreFilter(
                $this->storeManager->getStore()->getId()
            )->addStatusFilter(
                \Magento\Review\Model\Review::STATUS_APPROVED
            )->addEntityFilter(
                'product',
                $product->getId()
            )->setDateOrder();

        $reviews = $reviewCollection->getItems();

        if( !empty($reviews) ){
            foreach ($reviews as $review){
                // this is where the code breaks
                foreach( $review->getRatingVotes() as $vote ){
                    // do stuff here
                }
            }
        } 
    }
}

Inside the getCollection function I use the same method to retrieve the review collection as in the getReviewsCollection method from the magento core. I can successfully retrieve an array of \Magento\Review\Model\Review objects.

But my code breaks as soon as I try to iterate over the reviews and use the $review->getRatingVotes() method inside the inner most foreach loop. getRatingVotes() returns null and I get an Invalid argument supplied for foreach() exception.

I decided to investigate the getRatingVotes() method but I cannot find where it is defined. I did a search of the whole codebase inside VSCode as well as via grep. The only place where it occurs is inside the .phtml template file of the reviews list.

Était-ce utile?

La solution

Looks like I tried really hard to do it the hard way.
A simple:

$this->reviewFactory->create()->getEntitySummary($product, $this->storeManager->getStore()->getId());

$summary = $prod->getRatingSummary()->getRatingSummary();

Did the trick!!!

Licencié sous: CC-BY-SA avec attribution
Non affilié à magento.stackexchange
scroll top