Exporting Magento 1 Product Reviews and Importing them to Magento 2

created January 11, 2020, last updated January 12, 2020.

.
closeThis post was last updated 4 years 2 months 11 days ago, some of the information contained here may no longer be actual and any referenced software versions may have been updated!

I am Migrating Magento 1.9 to 2.3 – yikes!

I wasn’t able to use the Magento 2 migration tool for products so one of the tasks on my TO DO list was product review migration. Looking around for (free) solutions the only stuff I came across was no longer free or didn’t work. $100 to import 500 reviews – I don’t think so.

If you are looking to do something similar here is a quick copy and paste of the php code I used for the Magento 1 export, and the Magento 2 import.

I am assuming you can plug this into your existing Magento php cli tools which already bootstrap the corresponding Magento1 or 2 core classes. For Magento 1 I first took a full product collection and parsed each product for review data. All the data is saved to a tab seperated CSV file which is then used for the Magento 2 product review import.

Magento Migration Product Review Migration
Magento Migration Product Review Migration

Magento 1.9 product review export to csv

echo $c("MAGE1 Migration - Export MAGE1 Product Reviews to CSV")->header. "\n\n";

// LOAD ALL PRODUCTS
//
$_storeID=0; // admin

$_reviewVisibleInStoreViews=array(1,2);

$_storeLocale[0]='admin';
$_storeLocale[1]='de';
$_storeLocale[2]='en';
$this->getProductCollectionAllSKUs($_storeID);

$_products=$this->get('collection');
$_reviewData=array();
$_count=0;

foreach($_products as $_id=>$_product)
{
    $_sku = $_product->getSku();
    $_productId = $_product->getId();
    $_reviewcCollection = \Mage::getModel('review/review')->getCollection()
        ->addStoreFilter($_storeID)
        ->addEntityFilter('product', $_productId)
        ->addStatusFilter(\Mage_Review_Model_Review::STATUS_APPROVED)
        ->setDateOrder()
        ->addRateVotes();

        if (count($_reviewcCollection))
        {

            $_productReview=array();

            foreach($_reviewcCollection as $_review) {

                $_ratings=array();
                $votes = $_review->getRatingVotes();
                $total = 0;

                foreach($votes as $vote)
                {
                    $total += $vote->getPercent();
                    $_ratings[]=$vote->getValue();
                }

                $avgRating = $total / count($votes);

                $_reviewDetail=trim(preg_replace('/\s\s+/', '<br>', $_review['detail']));
                $_reviewTitle=trim(preg_replace('/\s\s+/', '<br>', $_review['title']));

                //var_dump($total, count($votes), $avg);
                $_productReview[]=array(
                    'createdat' => $_review->getCreatedAt(),
                    'review' => $_reviewDetail,
                    'summary' => $_reviewTitle,
                    'nickname' => $_review['nickname'],
                    'customer_id' => ($_review['customer_id'] ? $_review['customer_id'] : null),
                    'ratings' => implode('|', $_ratings),
                    'visibilty' => implode('|', $_reviewVisibleInStoreViews),
                );

                $_count++;
                echo '.';

            }

            $_reviewData[$_sku]=$_productReview;

        }

}

//print_r($_reviewData);
echo "\n".$c($_count. ' product reviews exported for store view '. $_storeID)->info."\n";

// EXPORT CSV
//
//
$_now = new \DateTime(null, new \DateTimeZone('Europe/Berlin'));
$_reviewExportFilename='/home/data/Mage1MigrateReviewsProducts_'.$_now->format('Y-m-d').'_'.$_storeLocale[$_storeID].'.csv';

$_reviewExportHeader='sku,createdat,review,summary,nickname,customer_id,ratings,visibility';
$_reviewExportHeader=explode(',',$_reviewExportHeader);

if (file_exists($_reviewExportFilename)) {unlink($_reviewExportFilename);}

// -- csv seperator
$_seperator="\t"; // TAB
//$_seperator=','; // COMMA

ini_set('default_charset','UTF-8');

$_fileHandle = fopen($_reviewExportFilename, 'w');

    // write UTF8-BOM
    //fwrite($_fileHandle, pack("CCC",0xef,0xbb,0xbf));

    // write header
    if ($_reviewExportHeader) {fwrite($_fileHandle, implode($_seperator, $_reviewExportHeader)."\r\n");}

    echo $c('Creating CSV export file '. $_reviewExportFilename)->info."\n";

    // write data
    foreach ($_reviewData as $_sku => $_reviews)
    {
        foreach ($_reviews as $_review)
        {
            fwrite($_fileHandle, $_sku.$_seperator.implode($_seperator, $_review)."\r\n");
        }
    }

fclose($_fileHandle);

echo $c('Product review export complete!')->success. "\n";

Magento 2 csv product import

<?php

	echo $c("MAGE2 Import Product Reviews from MAGE1 Migration CSV")->header. "\n\n";

	$_reviewDataCSVFile='/home/data/Mage1MigrateReviewsProducts_2020-01-11_admin.csv';
	$_reviewDataCSV=file('/home/data/Mage1MigrateReviewsProducts_2020-01-11_admin.csv', FILE_IGNORE_NEW_LINES);

	echo $c("Importing from ". $_reviewDataCSVFile)->info. "\n";

	$_count=0;
	$_total=(count($_reviewDataCSV)-1);
	foreach ($_reviewDataCSV as $_key => $_data)
	{
		if ($_key===0){ // build header
			$_keys=explode("\t",trim($_data));
			continue;
		}

		$_dataArray=explode("\t",$_data);

		foreach ($_dataArray as $_key => $_data)
		{
			$_reviewData[$_keys[$_key]]=$_data;
		}

		//print_r($_reviewData);

		try
		{
			$_success=false;

            $_obj=new \PAJ\Library\Magento2\Reviews\AddReview(
                array(
					'reviewdata' => $_reviewData,
					'storeid' => '0'
                )
            );
				$_output=$_obj->get('output');
				$_success=$_obj->get('success');

			if($_success)
			{
				$_count++;
				echo $c("Review ". $_count."/".$_total. " imported.")->success. "\n";
				//print_r($_output);

			}

		}
		catch (\Exception $e)
		{
			// catch bad guys
			//throw new \Exception($e);
			echo $c("ERROR: ". $e->getMessage())->error. "\n";
			continue;
		}

		// 1 product test exit;
		//exit;
	}


if (!$_silent) {

	echo 'Import complete.'. "\n";
}


exit;


class MagentoAddReview extends AbstractApp
{

    /**
     * @var \Magento\Review\Model\RatingFactory;
     */
    private $_ratingFactory;
    /**
     * @var \Magento\Review\Model\ReviewFactory;
     */
    private $_reviewFactory;

    public function run()
    {
        // load a product
        //

        // init vars
        $_data=array();

        $_storeID=$this->_variables['storeid'];
        $_store = $this->_storeManagerInterface->getStore($_storeID);
        $this->_storeManagerInterface->setCurrentStore($_store);
        $_reviewData=$this->_variables['reviewdata'];

        $_sku=$_reviewData['sku'];
        $_customerId=$_reviewData['customer_id'];

        //for Guest user $_customerId=Null;
        //
        if (!$_customerId){$_customerId=Null;}

        // create review data
        //
        $_customerNickName=$_reviewData['nickname'];
        $_reviewTitle=$_reviewData['summary'];
        $_reviewDetail=preg_replace('#<br\s*/?>#i', "\n", $_reviewData['review']);
        $_title=preg_replace('#<br\s*/?>#i', "\n", $_reviewData['summary']);
        $_createdAt=$_reviewData['createdat'];

        // store visibility array, i.e. 1,2 for visibile in store view 1 and 2
        // 
        $_reviewVisibleInStoreViews=explode('|',$_reviewData['visibility']);
        $_ratings=explode('|',$_reviewData['ratings']);

        $_product = $this->_productRepository->get($_sku);
        $_productId=$_product->getId();

        $_reviewFactory = $this->getReviewFactory();
        $_ratingFactory = $this->getRatingFactory();

        foreach ($_ratings as $_key => $_rating)
        {
            $_reviewFinalData['ratings'][$_key+1] = $_rating;
        }

        $_reviewFinalData['nickname'] = $_customerNickName; //add user nickname
        $_reviewFinalData['title'] = $_title; //add title of the review
        $_reviewFinalData['detail'] = $_reviewDetail; //add details of the review
        $_reviewFinalData['customerid'] = $_customerId;

        $review = $_reviewFactory->create()->setData($_reviewFinalData);

        $review->unsetData('review_id');
        $review->setEntityId($review->getEntityIdByCode(\Magento\Review\Model\Review::ENTITY_PRODUCT_CODE))
            ->setEntityPkValue($_productId)
            ->setStatusId(\Magento\Review\Model\Review::STATUS_APPROVED) //By default set approved
            ->setStoreId($_storeID)
            ->setCreatedAt($_createdAt)
            ->setStores($_reviewVisibleInStoreViews)
            ->save();

        foreach ($_reviewFinalData['ratings'] as $ratingId => $rating) {
            $_ratingFactory->create()
                ->setRatingId($ratingId)
                ->setReviewId($review->getId())
                ->addOptionVote($rating, $_productId);
        }
        $review->aggregate();

        //$this->debug($_data);
        $_data['store']['storeid']=$_storeID;
        $_data['reviews']=array(
            'productid'=> $_productId
        );


        return ['magento' => $_data];
    }

    /**
     * Get Factories
     *
     */
    private function getRatingFactory()
    {
        if (!$this->_ratingFactory) {
            $this->_ratingFactory = \Magento\Framework\App\ObjectManager::getInstance()
                ->get(\Magento\Review\Model\RatingFactory::class);
        }
        return $this->_ratingFactory;
    }
    private function getReviewFactory()
    {
        if (!$this->_reviewFactory) {
            $this->_reviewFactory = \Magento\Framework\App\ObjectManager::getInstance()
                ->get(\Magento\Review\Model\ReviewFactory::class);
        }
        return $this->_reviewFactory;
    }
}

The echo’s use the cool colours from https://github.com/kevinlebrun/colors.php The will probably throw an error for you, sorry!

Comments

This site uses Akismet to reduce spam. Learn how your comment data is processed.