Вопрос

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.

Это было полезно?

Решение

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!!!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с magento.stackexchange
scroll top