How to Import Related Products to Magento 2?
The following article is based on a
Even if a CSV file has a row with the related_skus attribute with the specified data for a product, the default import process may not be flawless. If in admin under Products->Catalog the imported product contains no related products in the Related Products sidebar tab but those products exist in the catalog with SKUs, you’ve come to the right place.
The command expects a 2-columns related.csv file in the var folder. The columns are parent SKU & children SKUs. A comma is a CSV separator, and a pipe is a children_skus separator.
Below, you can see the corresponding files. Replace Sinapsis with your vendor name, and Sync with the module name. After installing the module, run bin/magento setup:upgrade & you’ll see the new command under bin/magento list. Execute it by running
1 |
bin/magento sync:related |
Also, note that since the 2.2 version, there are 2 changes required: an extra line before saving $product. This, you will prevent
1 |
$product->unsetData('media_gallery'); |
Besides, it is necessary to change admin to adminhtml in
1 |
$this->_appState->setAreaCode('adminhtml'); |
Note that the first change is innocuous for older Magento 2 versions. The second one may be harmful. Therefore, the following code contains only the first change:
app / code / Sinapsis / Sync / etc / di.xml
1 2 3 4 5 6 7 8 9 |
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <type name="Magento\Framework\Console\CommandList"> <arguments> <argument name="commands" xsi:type="array"> <item name="sync_related" xsi:type="object">Sinapsis\Sync\Console\Command\RelatedCommand</item> </argument> </arguments> </type> |
app / code / Sinapsis / Sync / etc / module.xml
1 2 3 4 |
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="module.xsd"> <module name="Sinapsis_Sync" setup_version="1.0.0"> </module> |
app / code / Sinapsis / Sync / registration.php
1 2 3 4 5 6 |
<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'Sinapsis_Sync', __DIR__ ); |
app / code / Sinapsis / Sync / Console / Command / RelatedCommand.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
<?php namespace Sinapsis\Sync\Console\Command; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Magento\Framework\ObjectManagerInterface; use Magento\Framework\App\State as AppState; use Magento\Framework\App\Filesystem\DirectoryList; class RelatedCommand extends Command { const CSV_SEPARATOR = ','; const CHILDREN_SEPARATOR = '|'; protected $_appState; protected $_objectManager; protected $_directorylist; public function __construct( DirectoryList $_directorylist, AppState $appState, ObjectManagerInterface $objectManager ) { $this->_appState = $appState; $this->_objectManager = $objectManager; $this->_directorylist = $_directorylist; parent::__construct(); } protected function configure() { $this->setName('sync:related') ->setDescription('Synchronize catalog related products'); parent::configure(); } protected function execute(InputInterface $input, OutputInterface $output) { $output->writeln('<info>Starting process...<info>'); $output->writeln(''); $this->_appState->setAreaCode('admin'); $productRepository = $this->_objectManager->create('Magento\Catalog\Model\ProductRepository'); $output->writeln('<info>Loading csv content...<info>'); $output->writeln(''); $filePath = $this->_directorylist->getPath('var') . DIRECTORY_SEPARATOR . 'related.csv'; //@todo control Exception if file does not exist $parseData = array(); if (($handle = fopen($filePath, "r")) !== FALSE) { while (($data = fgetcsv($handle, 0, self::CSV_SEPARATOR)) !== FALSE) { $parseData[] = $data; } fclose($handle); } else { $output->writeln('<info>Could not read .csv file<info>'); return; } $headers = array_shift($parseData); // remove headers foreach ($parseData as $row){ $skuParent = trim($row[0]); $skuChildren = trim($row[1]); $output->writeln('<info>Loading parent product ' . $skuParent . ' ... <info>'); try { $product = $productRepository->get($skuParent); } catch (\Magento\Framework\Exception\NoSuchEntityException $e){ $output->writeln('<info>Could not load!<info>'); continue; } $links = $product->getProductLinks(); $children = explode(self::CHILDREN_SEPARATOR, $skuChildren); $i = 1; foreach ($children as $skuChild){ $output->writeln('<info>Loading related product ' . $skuChild . ' ... <info>'); try { $child = $productRepository->get($skuChild); } catch (\Magento\Framework\Exception\NoSuchEntityException $e){ $output->writeln('<info>Could not load!<info>'); continue; } $productLink = $this->_objectManager->create('Magento\Catalog\Api\Data\ProductLinkInterface') ->setSku($skuParent) ->setLinkedProductSku($skuChild) ->setPosition($i) ->setLinkType('related'); $links[] = $productLink; $i++; } $product->setProductLinks($links); $product->unsetData('media_gallery'); $productRepository->save($product); $output->writeln('<info>Relations saved for ' . $skuParent . '<info>'); } $output->writeln(''); $output->writeln('<info>Done<info>'); } } |
It is a quite complex solution, isn’t it? You can essentially simplify the way you import related products to Magento 2 with our Improved Import & Export Magento 2 extension. The module extends the default functionality of the platform and adds lots of new features to product import. Since related products are supported by default, our extension also allows moving them to Magento 2.
Besides, it enhances product import with the ability to create a schedule for fully automated updates; the mapping functionality to match all third-party attributes to default attributes of Magento 2; hardcoded values for selected attributes, etc. For further information, follow the link below:
Download/Buy Improved Import & Export Magento 2 Extension
We hope the article was useful. For other useful Magento 2 tips, check out our Cookbook.