I do not want the customers/guest to let post reviews who did not make a purchase of that product.
- for guest users I disable - "Allow guest to write reviews"
- for customers/logged in users - how to add condition?
Anyone having an extension that providing such features.
Solved! Go to Solution.
Hello @Sandip Magento
You have to add the condition here.
If the current customer has purchased the current product, then load the review form otherwise show the custom message or don't load any template.
Follow the steps given below
1. 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>
2. 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; } } }
3. Add your custom message when review form is not available to the customer if he/she has not purchased the product yet.
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.
Hello @Sandip Magento
You have to add the condition here.
If the current customer has purchased the current product, then load the review form otherwise show the custom message or don't load any template.
Follow the steps given below
1. 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>
2. 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; } } }
3. Add your custom message when review form is not available to the customer if he/she has not purchased the product yet.
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.
Thanks @Mayur Bhuva for your effort and answer. Let me give a try.
Bro @Mayur Bhuva
Not really an answer but gotta say this!
Almost 2 years later that's still helpful, I'm using 2.3.5-p1 and still no option to do that or extensions that I found, saying this, create it on git under your name so it's easier to install and some other people can improve like activating or deactivating the text and change the text in admin, I think that would help some people, great job!
Best regards
Hi,
I know this is an older post; I'm using Magento 2.4.3 and while the code works, 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 my Form.php is :
if (in_array($this->getCurrentProduct()->getId(), $product_ids)) {
I followed all the instructions from the solution except 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.
Any advise would be greatly appreciated.
im very new and im using 2.4.3p version, is there new path to apply this code, because i cant find the mentioned file in the path, im install via composer