0

I'm trying to save review programmatically. This seems to be working but not totally and as it's using object manager; I would like to find the good proper way to handle this in Magento 2.

So basically my question is: How to replace this piece of code to make it "clean"

$stores=array(
    $this->block->getStoreId($this->block::STORE_CODE_PARTICULIER),
    $this->block->getStoreId($this->block::STORE_CODE_PRO)
);
$objectManager = ObjectManager::getInstance();

$_review = $objectManager->get("Magento\Review\Model\Review")
                ->setEntityPkValue($productId)
                ->setStatusId($statusReview)
                ->setTitle($reviewTitle)
                ->setDetail($reviewDetail)
                ->setEntityId(1)
                ->setStoreId($store_id)
                ->setStores($stores)
                ->setCustomerId($customerId)
                ->setNickname($customerNickName)
                ->save();

I wanted to find a repository for this review but seems like it doesn't exist?

Currently, this code works, but the behavior is odd (it's an import script...if I try to import one by one, my reviews are well created...but if I try to create more than 1, it will still only create one of them. That's why I suspect an unexpected behavior due to object manager being used.

Is there a better way to handle this?

Maybe I have to load the product and in fact, save the product more than the review itself?

Please let me know how you would handle this!

2 Answers 2

1

You can try the below code and reference:

Here I have created this file in Magento root for sample add reviews.

<?php
use Magento\Framework\App\Bootstrap;
require __DIR__ . '/app/bootstrap.php';
$bootstrap = Bootstrap::create(BP, $_SERVER);
$obj = $bootstrap->getObjectManager();
$state = $obj->get('Magento\Framework\App\State');
$state->setAreaCode('frontend');

ini_set('display_errors', 1);
echo "HELLO STACK EXCHANGE";


$productId=5;
$customerId=13; //for Guest user $customerId=Null;
$customerNickName='STACK EXCHANGE';
$reviewTitle='STACK EXCHANGE';
$reviewDetail='STACK EXCHANGE';
$StoreId=1;
$title='STACK EXCHANGE';


$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$_review = $objectManager->get("Magento\Review\Model\Review")
->setEntityPkValue($productId)    //product Id
->setStatusId(\Magento\Review\Model\Review::STATUS_PENDING)// pending/approved
->setTitle($reviewTitle)
->setDetail($reviewDetail)
->setEntityId(1)
->setStoreId($StoreId)
->setStores(1)
->setCustomerId($customerId)//get dynamically here 
->setNickname($customerNickName)
->save();


echo "Review Has been saved ";

echo "/////FOR SAVING RATING /////////
     ///////////////////////////////";

/* 
 $_ratingOptions = array(
     1 => array(1 => 1,  2 => 2,  3 => 3,  4 => 4,  5 => 5),   //quality
     2 => array(1 => 6,  2 => 7,  3 => 8,  4 => 9,  5 => 10),  //value
     3 => array(1 => 11, 2 => 12, 3 => 13, 4 => 14, 5 => 15),  //price 
     4 => array(1 => 16, 2 => 17, 3 => 18, 4 => 19, 5 => 20)   //rating
);*/

//Lets Assume User Chooses Rating based on Rating Attributes called(quality,value,price,rating)
$ratingOptions = array(
            '1' => '1',
            '2' => '7',
            '3' => '13',
            '4' => '19'
);      
        
foreach ($ratingOptions as $ratingId => $optionIds) 
{     
       $objectManager->get("Magento\Review\Model\Rating")
                     ->setRatingId($ratingId)
                     ->setReviewId($_review->getId())
                     ->addOptionVote($optionIds, $productId);
            
}
echo  "Latest REVIEW ID ===".$_review->getId()."</br>";     
$_review->aggregate();
echo "Rating has been saved submitted  successfully";

?>

REF URL: https://webkul.com/blog/how-to-create-product-review-rating-programatically-in-magento2/

I hope this will help.

2
  • This is the code i'm already using if you look at the question^^...I want to avoid using object manager.
    – Claims
    Nov 2, 2021 at 13:31
  • Then I would suggest, please create a custom module and add the required class in the constructor. Please review the reference URL.
    – Nits
    Nov 2, 2021 at 13:37
0

Ok then turns out the real explanation behind all that is the following :

$review = $objectManager->get("Magento\Review\Model\Review")

This call a singleton; which means, each time this is called, the same object was called which explain why all the time only my last entry was recorded.

So obviously here using a repository wasn't possible, but using the factory instead of the model was enough to fix it.

So quick fix was as I though removing the object manager and directly create a review factory instance.

1
  • Use create instead of get. Example $review = $objectManager->create("Magento\Review\Model\Review")
    – Ahsan
    Oct 6, 2023 at 21:40

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.