cancel
Showing results for 
Search instead for 
Did you mean: 

Sync products between 2 stores with REST API Magento 2

Sync products between 2 stores with REST API Magento 2

I am a trying to integrate products with REST API.

We have 1 master Magento store where we have all the products, and have plan for other Magento stores which will integrate with Master store and create, update data automatically. I run cron job on daily basis to run the script. I have master store in Magento 2.3 and working on a new site and using Magento 2.4.6.

The below code is working fine to create and update product but not assigning product to the category. 

 

<?php

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
ini_set('memory_limit', '5G');
ini_set('max_execution_time', '0');



error_reporting(E_ALL);

use Magento\Framework\App\Bootstrap;
require 'app/bootstrap.php';


$bootstrap = Bootstrap::create(BP, $_SERVER);

$objectManager = $bootstrap->getObjectManager();

$state = $objectManager->get('Magento\Framework\App\State');
$state->setAreaCode('frontend');

$userData = array("username" => "", "password" => ""); // Master Magento
$url = "";


$ch = curl_init("$url/index.php/rest/V1/integration/admin/token");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($userData));
curl_setopt($ch, CURLOPT_TIMEOUT, 600);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json", "Content-Length: " . strlen(json_encode($userData))));
 
$token = curl_exec($ch);

$localCategories = getLocalCategories();


$date = date("Y-m-d", strtotime('-24 hours', time()));


$ch = curl_init("$url/index.php/rest/V1/products/?searchCriteria[filter_groups][0][filters][0][field]=updated_at&searchCriteria[filter_groups][0][filters][0][value]=$date&searchCriteria[filter_groups][0][filters][0][condition_type]=gteq&searchCriteria[filter_groups][1][filters][0][field]=n_web&searchCriteria[filter_groups][1][filters][0][value]=Y&searchCriteria[filter_groups][1][filters][0][condition_type]=eq&searchCriteria[filter_groups][1][filters][1][field]=n_web&searchCriteria[filter_groups][1][filters][1][value]=S&searchCriteria[filter_groups][1][filters][1][condition_type]=eq&searchCriteria[filter_groups][2][filters][0][field]=n_stkcode&searchCriteria[filter_groups][2][filters][0][value]=&searchCriteria[filter_groups][2][filters][0][condition_type]=neq");


curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_TIMEOUT, 600);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json", "Authorization: Bearer " . json_decode($token)));

$result = curl_exec($ch);

$json = json_decode($result, true);

echo "\n\ndate: ".$date."\n\n";

$products = array();
//print_r($json);
if(is_array($json) && (count($json) > 0)){
    echo count($json['items'])." records to add/update\n\n";
    foreach($json['items'] as $item):

        $product = array();

        $product['name'] = $item['name'];
        $product['status'] = $item['status'];

        if(isset($item['price'])){
            $product['price'] = $item['price']; 
        } else {
            $product['price'] = 0;
        }
        
        $custom_att = $item['custom_attributes'];
        $product['type_id'] = $item['type_id'];

        $sku = $item['sku'];
        $product['sku'] = $sku;

        foreach($custom_att as $att){

    
            

            if($att['attribute_code'] == 'n_stkcode'){
                $msku = $sku;
                $sku = $att['value'];
                $product['sku'] = $sku;
            }

                    if($att['attribute_code'] == 'short_description'){
                $short_description = $att['value'];
                $product['short_description'] = $short_description;
            }

            if($att['attribute_code'] == 'description'){
                $description = $att['value'];
                $product['description'] = $description;
            }

        
            if($att['attribute_code'] == 'product_specifications'){
                $specs = $att['value'];
                $product['specs'] = $specs;
            }

        }


        if(!isset($product['short_description'])){
            $product['short_description'] = "";
        }

        if(!isset($product['description'])){
            $product['description'] = "";
        }

        if(!isset($product['product_specifications'])){
            $product['product_specifications'] = "";
        }


    
            /// GET IMAGE URL 
            $gallery = array();
            $ch = curl_init("$url/index.php/rest/V1/getproductimage/$msku");
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
            curl_setopt($ch, CURLOPT_TIMEOUT, 600);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json", "Authorization: Bearer " . json_decode($token)));

            $img_result = curl_exec($ch);
            // print_r($img_result);

            $img_json = json_decode($img_result, true);
            if(isset($img_json[0]['product_image_url'])){
                $baseimg = $img_json[0]['product_image_url'];
            } else { 
                $baseimg = "";
            }

            $last = strrpos($baseimg, "/");
            $next_to_last = strrpos($baseimg, "/", $last - strlen($baseimg) - 1) - 2;
            $baseurl = substr($baseimg, 0, $next_to_last);

            $gallery = $item['media_gallery_entries'];
            $gallery_items = array();

            foreach ($gallery as $key => $entry) {
                $galurl = $baseurl . $entry['file'];
                $gallery[$key]['file'] = $galurl;
            }

            $product['gallery'] = $gallery;

            /// GET STOCK QUANTITY

            $ch = curl_init("$url/index.php/rest/V1/stockItems/$msku");
             curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
             curl_setopt($ch, CURLOPT_TIMEOUT, 600);
             curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
             curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json", "Authorization: Bearer " . json_decode($token)));
         
             $inv_result = curl_exec($ch);
             $sku_json = json_decode($inv_result, true);

             if(isset($sku_json['qty'])){
                $qty = $sku_json['qty'];    
             } else {
                $qty = 0;
             }

             $product['qty'] = $qty;
            
            /// GET RELATED ARRAY & ASSOCIATED(GROUPED SKUS) ARRAY 
            $related = $item['product_links'];
            $relArray = array();
            $assArray = array();
            foreach($related as $relsku){
                if($relsku['link_type'] == 'associated'){
                    array_push($assArray, $relsku['linked_product_sku']);   
                }
                if($relsku['link_type'] == 'related'){
                    array_push($relArray, $relsku['linked_product_sku']);
                }
            }

            $product['associated'] = $assArray;
            $product['related'] = $relArray;

            /// GET CATEGORIES IN ARRAY
            $categories = $item['extension_attributes']['category_links'];
            $catArray = array();

            foreach($categories as $category){
                $category_id = $category['category_id'];

                foreach($localCategories as $lcat){
                    if($category_id == $lcat['baseId']){
                        array_push($catArray, $lcat['id']);
                    }
                }
            }

            $product['categories'] = $catArray;

            if(sizeof($catArray)>0){
                array_push($products, $product);
            }
        

    endforeach;
} else {
    echo "No recently updated products";
}

foreach($products as $product){ 
     print_r($product);
    $__product = $objectManager->get('Magento\Catalog\Model\Product');

    if($__product->getIdBySku($product['sku'])) {
        $pid = $__product->getIdBySku($product['sku']);
        echo '\nproduct '. $product['sku'] .' exists';
        
        $productFactory = $objectManager->get('\Magento\Catalog\Model\ResourceModel\Product\Action');
        $productFactory->updateAttributes([$pid], ['name' => $product['name']], 1);
        $productFactory->updateAttributes([$pid], ['description' => $product['description']], 1);
        $productFactory->updateAttributes([$pid], ['short_description' => $product['short_description']], 1); 

        
        $productFactory->updateAttributes([$pid], ['price' => $product['price']], 1); 
        
        
        
        $categoryLinkRepository = $objectManager->get('\Magento\Catalog\Api\CategoryLinkManagementInterface');
        $categoryLinkRepository->assignProductToCategories($product['sku'], $product['categories']);

        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $pr = $objectManager->create('Magento\Catalog\Model\Product')->load($__product->getIdBySku($product['sku']));

        $productRepository = $objectManager->create('Magento\Catalog\Api\ProductRepositoryInterface');
        $productGallery = $objectManager->create('\Magento\Catalog\Model\ResourceModel\Product\Gallery');

        


        $gallery = $pr->getMediaGalleryImages();
        if (count($gallery) > 0) {
            foreach($gallery as $image){
                $productGallery->deleteGallery($image->getValueId());
            }
            $pr->setMediaGalleryEntries([]);

            echo "added new image";
        }
        $productRepository->save($pr);


        $fileSystem = $objectManager->get('\Magento\Framework\Filesystem');

        $tmpDir = $fileSystem->getDirectoryRead(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA)->getAbsolutePath() . 'tmp' . DIRECTORY_SEPARATOR;
    

        $file = $objectManager->create('\Magento\Framework\Filesystem\Io\File');
        $file->checkAndCreateFolder($tmpDir);

        $primgs = $product['gallery'];
        


        foreach($primgs as $primg){
            $imageUrl = $primg['file'];
            $newFileName = $tmpDir . baseName($imageUrl);
            $imageType = $primg['types'];

            $result = $file->read($imageUrl, $newFileName);
            if ($result) {
                $pr->addImageToMediaGallery($newFileName, array('image','small_image','thumbnail'), false, false);
            }
            
        

        }

        $pr->save();
        echo '\nproduct udpated\n';

    } else {

        $fileSystem = $objectManager->create('\Magento\Framework\Filesystem');

        $tmpDir = $fileSystem->getDirectoryRead(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA)->getAbsolutePath() . 'tmp' . DIRECTORY_SEPARATOR;
        
        

        $file = $objectManager->create('\Magento\Framework\Filesystem\Io\File');
        $file->checkAndCreateFolder($tmpDir);

        $primgs = $product['gallery'];

        $urlkey = "sku-".rand(1,100)."-".strtolower($product['sku']);
        $_product = $objectManager->create('Magento\Catalog\Model\Product');

        $_product->setName($product['name']);
        $_product->setDescription($product['description']);
        $_product->setShortDescription($product['short_description']);
        $_product->setTypeId($product['type_id']);
        $_product->setSku($product['sku']);
        $_product->setPrice($product['price']);
        $_product->setUrlKey($urlkey);
        $_product->setWebsiteIds(array(1));
        $_product->setVisibility(4);
        $_product->setStatus($product['status']);
        $_product->setAttributeSetId(4);
        $category_id= array(5);
        $_product->setCategoryIds($product['categories']);

    

        foreach($primgs as $primg){
            $imageUrl = $primg['file'];
            $newFileName = $tmpDir . baseName($imageUrl);
            $imageType = $primg['types'];

            $result = $file->read($imageUrl, $newFileName);
            if ($result) {
                echo $imageUrl;
                $_product->addImageToMediaGallery($newFileName, $imageType, true, false);
            }
        }

        echo "\n" . $product['sku'] . " created";
        echo "\n";
        $_product->save();
    }
}

$obj                      = \Magento\Framework\App\ObjectManager::getInstance();
$indexerCollectionFactory = $obj->get("\Magento\Indexer\Model\Indexer\CollectionFactory");
$indexerFactory           = $obj->get("\Magento\Indexer\Model\IndexerFactory");
$indexerCollection        = $indexerCollectionFactory->create();
$allIds                   = $indexerCollection->getAllIds();

foreach ($allIds as $id)
{
    $indexer = $indexerFactory->create()->load($id);
    if($indexer->getStatus() != 'valid'){
        $indexer->reindexRow($id);
    }
}


function getLocalCategories(){

    $localCategories = array();
    
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $categoryCollection = $objectManager->get('\Magento\Catalog\Model\ResourceModel\Category\CollectionFactory'); // 
    $categories = $categoryCollection->create();
    $categories->addAttributeToSelect('*');
     
    foreach ($categories as $category) {
        $localCat = array();

        $localCat['id'] = $category->getId();
        $localCat['baseId'] = $category->getBaseCatId();

        $cat_ids = $category->getPath();
        $lcatIds = explode('/', $cat_ids);
        array_shift($lcatIds);
            
        $lcatTree = "";

        foreach($lcatIds as $lcatId){
            if($lcatTree != ""){
                $lcatTree .= "/";
            }

            $_objectManager = \Magento\Framework\App\ObjectManager::getInstance();
            $category_data = $_objectManager->create('Magento\Catalog\Model\Category')
                    ->load($lcatId);
            $lcat_name = $category_data->getName();

            $lcatTree .= $lcat_name;
        }

        $localCat['name'] = $lcatTree;
        array_push($localCategories, $localCat);

    }
    return $localCategories;

}

function getCategoryName($catid, $token, $url){
    $ch = curl_init("$url/index.php/rest/V1/categories/$catid");
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
    curl_setopt($ch, CURLOPT_TIMEOUT, 600);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json", "Authorization: Bearer " . json_decode($token)));

    $result = curl_exec($ch);
    $json = json_decode($result, true);

    $cat_name = $json['name'];

    return $cat_name;
}

function getLocalCatId($catTree, $localCategories){
    foreach($localCategories as $cat){
        if($cat['name'] == $catTree){
            return $cat['id'];
        }
    }
}
1 REPLY 1

Re: Sync products between 2 stores with REST API Magento 2

Based on your use case, would it not make more sense to have other stores as websites of the main Magento 2 instance instead of having separate instances of Magento?

Founder at https://agency418.com