0

I'm using Magento 2.4.3 and I'm loading a custom module using someone else's code from the link

https://community.magento.com/t5/Magento-2-x-Programming/Magento-2-Product-Reviews-only-by-customer-who-purchased-the/m-p/109338/highlight/false#M6143

Override the Review form block with your custom block.

app/code/Vendor/Module/etc/di.xml

    <?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Review\Block\Form" type="Vendor\Module\Block\Review\Form" />
</config>

Add condition for the customer in your custom block

app/code/Vendor/Module/Block/Review/Form.php

<?php
namespace Vendor\Module\Block\Review;
class Form extends \Magento\Review\Block\Form
{
/**
 * Customer Session Factory
 *
 * @var \Magento\Customer\Model\SessionFactory
 */
protected $_customerSession;
/**
 * Order Collection Factory
 *
 * @var \Magento\Sales\Model\ResourceModel\Order\CollectionFactory
 */
protected $_orderCollectionFactory;
/**
 * Registry
 *
 * @var \Magento\Framework\Registry
 */
protected $_registry;
/**
 * Review data
 *
 * @var \Magento\Review\Helper\Data
 */
protected $_reviewData = null;

/**
 * Catalog product model
 *
 * @var \Magento\Catalog\Api\ProductRepositoryInterface
 */
protected $productRepository;

/**
 * Rating model
 *
 * @var \Magento\Review\Model\RatingFactory
 */
protected $_ratingFactory;

/**
 * @var \Magento\Framework\Url\EncoderInterface
 */
protected $urlEncoder;

/**
 * Message manager interface
 *
 * @var \Magento\Framework\Message\ManagerInterface
 */
protected $messageManager;

/**
 * @var \Magento\Framework\App\Http\Context
 */
protected $httpContext;

/**
 * @var \Magento\Customer\Model\Url
 */
protected $customerUrl;

/**
 * @var array
 */
protected $jsLayout;

/**
 * @var \Magento\Framework\Serialize\Serializer\Json
 */
private $serializer;

/**
 * Form constructor.
 *
 * @param \Magento\Framework\View\Element\Template\Context $context
 * @param \Magento\Framework\Url\EncoderInterface $urlEncoder
 * @param \Magento\Review\Helper\Data $reviewData
 * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
 * @param \Magento\Review\Model\RatingFactory $ratingFactory
 * @param \Magento\Framework\Message\ManagerInterface $messageManager
 * @param \Magento\Framework\App\Http\Context $httpContext
 * @param Url $customerUrl
 * @param array $data
 * @param \Magento\Framework\Serialize\Serializer\Json|null $serializer
 * @throws \RuntimeException
 * @SuppressWarnings(PHPMD.ExcessiveParameterList)
 */
public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    \Magento\Framework\Url\EncoderInterface $urlEncoder,
    \Magento\Review\Helper\Data $reviewData,
    \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
    \Magento\Review\Model\RatingFactory $ratingFactory,
    \Magento\Framework\Message\ManagerInterface $messageManager,
    \Magento\Framework\App\Http\Context $httpContext,
    \Magento\Customer\Model\Url $customerUrl,
    array $data = [],
    \Magento\Framework\Serialize\Serializer\Json $serializer = null,
    \Magento\Customer\Model\SessionFactory $customerSession,
    \Magento\Sales\Model\ResourceModel\Order\CollectionFactory $orderCollectionFactory,
    \Magento\Framework\Registry $registry
) {
    $this->_customerSession = $customerSession;
    $this->_orderCollectionFactory = $orderCollectionFactory;
    $this->_registry = $registry;
    parent::__construct($context, $urlEncoder, $reviewData, $productRepository, $ratingFactory, $messageManager, $httpContext, $customerUrl, $data);
    $this->jsLayout = isset($data['jsLayout']) ? $data['jsLayout'] : [];
    $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()
        ->get(\Magento\Framework\Serialize\Serializer\Json::class);
}

protected function _construct()
{
    parent::_construct();

    if ($this->isCurrentCustomerPurchasedThisProduct()) {
        $this->setTemplate('Magento_Review::form.phtml');
    } else {
                    $this->setTemplate('Vendor_Module::no_review_form.phtml');
                    // You can set null here if you don't want to load any template
                    // $this->setTemplate(null);
    }
}

public function getCurrentCustomerId()
{
    return $this->_customerSession->create()->getCustomer()->getId();
}

public function getCustomerOrders()
{
    $orders = $this->_orderCollectionFactory->create()->addFieldToSelect(
        '*'
    )->addFieldToFilter(
        'customer_id',
        $this->getCurrentCustomerId()
    );

    return $orders;
}

public function getCurrentProduct()
{
    return $this->_registry->registry('current_product');
}

public function isCurrentCustomerPurchasedThisProduct()
{
    $product_ids = [];

    foreach ($this->getCustomerOrders() as $order) {
        foreach ($order->getAllVisibleItems() as $item) {
            $product_ids[$item->getProductId()] = $item->getProductId();
        }
    }

    if (in_array($this->getCurrentProduct()->getId(), $product_ids)) {
        return true;
    } else {
        return false;
    }
}
}

My custom message in:

app/code/Vendor/Module/view/frontend/templates/no_review_form.phtml

You can not add the review on this product as you have not purchased this product yet.

I added this as a module and had to include a module.xml file in /app/code/Vendor/Module/etc and registration.php in /app/code/Vendor/Module which is pretty standard.

I get an error displayed at the top of the product page on the front end.

"An error has happened during application run. See exception log for details."

Nothing is in the exception.log but the below is in the system.log

main.CRITICAL: Error: Call to a member function getId() on null in /app/code/Vendor/Module/Block/Review/Form.php:163

Line "163" in Form.php from above is:

if (in_array($this->getCurrentProduct()->getId(), $product_ids)) {

Full Stack trace from system.log is below

#0 /bitnami/magento/app/code/Vendor/Module/Block/Review/Form.php(122):Vendor/Module\Block\Review\Form->isCurrentCustomerPurchasedThisProduct()
#1 /bitnami/magento/vendor/magento/framework/View/Element/AbstractBlock.php(225): Vendor/Module\Block\Review\Form->_construct()
#2 /bitnami/magento/vendor/magento/framework/View/Element/Template.php(155): Magento\Framework\View\Element\AbstractBlock->__construct()
#3 /bitnami/magento/vendor/magento/module-review/Block/Form.php(111): Magento\Framework\View\Element\Template->__construct()
#4 /bitnami/magento/app/code/Vendor/Module/Block/Review/Form.php(112): Magento\Review\Block\Form->__construct()
#5 /bitnami/magento/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php(121): Vendor/Module\Block\Review\Form->__construct()
#6 /bitnami/magento/vendor/magento/framework/ObjectManager/Factory/Compiled.php(108): Magento\Framework\ObjectManager\Factory\AbstractFactory->createObject()
#7 /bitnami/magento/vendor/magento/framework/ObjectManager/ObjectManager.php(56): Magento\Framework\ObjectManager\Factory\Compiled->create()
#8 /bitnami/magento/vendor/magento/framework/View/Element/BlockFactory.php(46): Magento\Framework\ObjectManager\ObjectManager->create()
#9 /bitnami/magento/vendor/magento/framework/View/Layout/Generator/Block.php(272): Magento\Framework\View\Element\BlockFactory->createBlock()
#10 /bitnami/magento/vendor/magento/framework/View/Layout/Generator/Block.php(252): Magento\Framework\View\Layout\Generator\Block->getBlockInstance()
#11 /bitnami/magento/vendor/magento/framework/View/Layout/Generator/Block.php(229): Magento\Framework\View\Layout\Generator\Block->createBlock()
#12 /bitnami/magento/vendor/magento/framework/View/Layout/Generator/Block.php(134): Magento\Framework\View\Layout\Generator\Block->generateBlock()
#13 /bitnami/magento/vendor/magento/framework/View/Layout/GeneratorPool.php(93): Magento\Framework\View\Layout\Generator\Block->process()
#14 /bitnami/magento/vendor/magento/framework/View/Layout.php(365): Magento\Framework\View\Layout\GeneratorPool->process()
#15 /bitnami/magento/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Framework\View\Layout->generateElements()
#16 /bitnami/magento/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Framework\View\Layout\Interceptor->___callParent()
#17 /bitnami/magento/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Framework\View\Layout\Interceptor->Magento\Framework\Interception\{closure}()
#18 /bitnami/magento/generated/code/Magento/Framework/View/Layout/Interceptor.php(68): Magento\Framework\View\Layout\Interceptor->___callPlugins()
#19 /bitnami/magento/vendor/magento/framework/View/Layout/Builder.php(129): Magento\Framework\View\Layout\Interceptor->generateElements()
#20 /bitnami/magento/vendor/magento/framework/View/Page/Builder.php(65): Magento\Framework\View\Layout\Builder->generateLayoutBlocks()
#21 /bitnami/magento/vendor/magento/framework/View/Layout/Builder.php(65): Magento\Framework\View\Page\Builder->generateLayoutBlocks()
#22 /bitnami/magento/vendor/magento/framework/View/Page/Config.php(224): Magento\Framework\View\Layout\Builder->build()
#23 /bitnami/magento/vendor/magento/framework/View/Page/Config.php(237): Magento\Framework\View\Page\Config->build()
#24 /bitnami/magento/vendor/magento/framework/App/View.php(170): Magento\Framework\View\Page\Config->publicBuild()
#25 /bitnami/magento/vendor/magento/framework/App/View.php(114): Magento\Framework\App\View->loadLayoutUpdates()
#26 /bitnami/magento/vendor/magento/module-page-cache/Controller/Block.php(86): Magento\Framework\App\View->loadLayout()
#27 /bitnami/magento/vendor/magento/module-page-cache/Controller/Block/Esi.php(19): Magento\PageCache\Controller\Block->_getBlocks()
#28 /bitnami/magento/vendor/magento/framework/Interception/Interceptor.php(58): Magento\PageCache\Controller\Block\Esi->execute()
#29 /bitnami/magento/vendor/magento/framework/Interception/Interceptor.php(138): Magento\PageCache\Controller\Block\Esi\Interceptor->___callParent()
#30 /bitnami/magento/vendor/magento/framework/Interception/Interceptor.php(153): Magento\PageCache\Controller\Block\Esi\Interceptor->Magento\Framework\Interception\{closure}()
#31 /bitnami/magento/generated/code/Magento/PageCache/Controller/Block/Esi/Interceptor.php(23): Magento\PageCache\Controller\Block\Esi\Interceptor->___callPlugins()
#32 /bitnami/magento/vendor/magento/framework/App/Action/Action.php(111): Magento\PageCache\Controller\Block\Esi\Interceptor->execute()
#33 /bitnami/magento/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Framework\App\Action\Action->dispatch()
#34 /bitnami/magento/vendor/magento/framework/Interception/Interceptor.php(138): Magento\PageCache\Controller\Block\Esi\Interceptor->___callParent()
#35 /bitnami/magento/vendor/magento/framework/Interception/Interceptor.php(153): Magento\PageCache\Controller\Block\Esi\Interceptor->Magento\Framework\Interception\{closure}()
#36 bitnami/magento/generated/code/Magento/PageCache/Controller/Block/Esi/Interceptor.php(32): Magento\PageCache\Controller\Block\Esi\Interceptor->___callPlugins()
#37 /bitnami/magento/vendor/magento/framework/App/FrontController.php(245): Magento\PageCache\Controller\Block\Esi\Interceptor->dispatch()
#38 /bitnami/magento/vendor/magento/framework/App/FrontController.php(212): Magento\Framework\App\FrontController->getActionResponse()
#39 /bitnami/magento/vendor/magento/framework/App/FrontController.php(147): Magento\Framework\App\FrontController->processRequest()
#40 /bitnami/magento/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Framework\App\FrontController->dispatch()
#41 /bitnami/magento/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Framework\App\FrontController\Interceptor->___callParent()
#42 /bitnami/magento/vendor/magento/module-store/App/FrontController/Plugin/RequestPreprocessor.php(99): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}()
#43 /bitnami/magento/vendor/magento/framework/Interception/Interceptor.php(135): Magento\Store\App\FrontController\Plugin\RequestPreprocessor->aroundDispatch()
#44 /bitnami/magento/vendor/magento/module-page-cache/Model/App/FrontController/BuiltinPlugin.php(71): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}()
#45 /bitnami/magento/vendor/magento/framework/Interception/Interceptor.php(135): Magento\PageCache\Model\App\FrontController\BuiltinPlugin->aroundDispatch()
#46 /bitnami/magento/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}()
#47 /bitnami/magento/generated/code/Magento/Framework/App/FrontController/Interceptor.php(23): Magento\Framework\App\FrontController\Interceptor->___callPlugins()
#48 /bitnami/magento/vendor/magento/framework/App/Http.php(116): Magento\Framework\App\FrontController\Interceptor->dispatch()
#49 /bitnami/magento/vendor/magento/framework/App/Bootstrap.php(264): Magento\Framework\App\Http->launch()
#50 /bitnami/magento/pub/index.php(29): Magento\Framework\App\Bootstrap->run()
#51 {main} [] []

Any advise would be greatly appreciated.

2
  • Are you able to find the solution ? Commented Jan 31, 2022 at 12:55
  • I ended up using "Advanced Review" from MAGETOP.COM.
    – Isaac
    Commented Mar 10, 2022 at 16:14

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.