Closed jchirschy closed 3 years ago
I am working on an example. May take a few days. :)
Hello JeanClaude,
This example is just a little something to get you started. Modify it in any way you need. This specific example shows a custom class that takes care of importing some products via a CSV file. The method processFile
is the main entry to import the file. If you have an array of data instead of a csv file, call importData
directly.
If the class is enough for you, you can strip out the rest of the code, but if what you need is a small self-sufficient command line script that loads Magento as well, then keep the bootstrap and application startup code. It loads a file called "abc.csv" that you would need to create. The file contains a name and a price. The class adds some necessary attributes to create a minimal product.
The example also makes the distinction between global attribute values and store view specific values; I hope this is clear. And as you can see, you can make config settings by modifying the $config object.
<?php
use BigBridge\ProductImport\Api\Data\Product;
use BigBridge\ProductImport\Api\Data\ProductStoreView;
use BigBridge\ProductImport\Api\Data\SimpleProduct;
use BigBridge\ProductImport\Api\ImportConfig;
use BigBridge\ProductImport\Api\ImporterFactory;
// =============================================================
// Example CSV file: abc.csv
//
// sku,name,price
// apple1,some apple,1.24
// banana4,this banana,0.75
// =============================================================
// =============================================================
// Bootstrap Magento
// =============================================================
$bootstrap = getcwd() . '/app/bootstrap.php';
if (!file_exists($bootstrap)) {
die("Execute this command from the root of a shop.\n");
}
require_once $bootstrap;
\Magento\Framework\App\Bootstrap::create(getcwd(), []);
// =============================================================
// Startup
// =============================================================
/** @var MyProductImport $import */
$import = \Magento\Framework\App\ObjectManager::getInstance()->get(MyProductImport::class);
$results = $import->processFile("abc.csv");
print_r($results);
// =============================================================
// A custom import class
// =============================================================
class MyProductImport
{
const HEADERS = ['sku', 'name', 'price'];
/** @var ImporterFactory */
protected $importerFactory;
public function __construct(
ImporterFactory $importerFactory
)
{
$this->importerFactory = $importerFactory;
}
public function processFile(string $filePath): array
{
$result = [];
list($productLabels, $messages) = $this->readFile($filePath);
if (!empty($messages)) {
return $result;
}
return $this->importData($productLabels);
}
protected function readFile(string $file): array
{
$messages = [];
$data = [];
$lines = file($file);
$header = array_shift($lines);
if (strpos($header, "\t") !== false) {
$sep = "\t";
} elseif (strpos($header, ",") !== false) {
$sep = ',';
} elseif (strpos($header, ";") !== false) {
$sep = ';';
} else {
$messages[] = "Could not detect column separator in first line";
goto end;
}
$headers = array_map('strtolower', array_map('trim', str_getcsv($header, $sep)));
if ($headers !== self::HEADERS) {
$messages[] = "The header of the CSV must be '" . implode(',', self::HEADERS) . "'";
goto end;
}
$i = 1;
foreach ($lines as $line) {
$i++;
$fields = array_map('trim', str_getcsv($line, $sep));
if ($fields === ['']) {
continue;
}
if (count($fields) !== count(self::HEADERS)) {
$messages[] = "Line $i does not have the right number of columns";
goto end;
}
$data[] = $fields;
}
end:
return [$data, $messages];
}
public function importData(array $data): array
{
$messages = [];
$result = [];
$productIds = [];
$config = new ImportConfig();
$config->emptyNonTextValueStrategy = ImportConfig::EMPTY_NONTEXTUAL_VALUE_STRATEGY_REMOVE;
$config->resultCallback = function(Product $product) use (&$messages, &$result, &$productIds) {
if (!$product->isOk()) {
$messages[] = sprintf("Line %s, sku = %s: %s",
$product->lineNumber, $product->getSku(), implode('; ', $product->getErrors()));
} else {
$result[] = $product->getSku();
$productIds[] = $product->id;
}
};
try {
$importer = $this->importerFactory->createImporter($config);
foreach ($data as $i => $datum) {
$sku = $datum[0];
$name = $datum[1];
$price = $datum[2];
$product = new SimpleProduct($sku);
$product->setAttributeSetByName("Default");
$product->addCategoriesByGlobalName(['Default Category/Desks', 'Default Category/Chairs', 'Default Category/Boards']);
$product->setWebsitesByCode(['base']);
// global scope data
$global = $product->global();
$global->setName($name);
$global->setPrice($price);
$global->setVisibility(ProductStoreView::VISIBILITY_BOTH);
$global->setStatus(ProductStoreView::STATUS_DISABLED);
$global->setTaxClassName("Taxable Goods");
$global->generateUrlKey();
// store view specific data (for example, store view code = nl)
$dutch = $product->storeView('nl');
$dutch->setName($name . ' met tulpen');
$dutch->setPrice($price + 1.25);
// stock data
$stockItem = $product->defaultStockItem();
$stockItem->setQty('100');
$stockItem->setIsInStock(true);
$product->lineNumber = $i + 2;
$importer->importSimpleProduct($product);
}
// process any remaining products in the pipeline
$importer->flush();
} catch (Throwable $throwable) {
// errors that were not foreseen by the importer (and should not occur)
$messages[] = $throwable->getMessage();
}
return ['messages' => $messages, 'skus' => $result, 'ids' => $productIds];
}
}
Hello @garfix,
That's great. It works perfectly.
Greetings
Hello,
I'm pretty new to Magento. Could you help me to use the programming library to import products ?
I've installed the module and run CLI successfully. Could you give us more details on how to get started with the programming library ? Could you give us a complete php file as an example ?
Thanks for you help. Greetings JeanClaude