W jednym z wdrożeń Magento 2 mieliśmy przypadek gdy w nowym sklepie wymagana była aktualizacja statusów produktów z pliku CSV. Sklep posiadał jedną wersję językową, która dane dziedziczyła po głównym widoku "All Store View".

Gdy początkowo zaktualizowałem atrybuty produktów, fragment skryptu odpowiedzialny za zapis danych wyglądał tak: 
 

            if ($product = $productRepository->get($sku)) {
                $product->setStatus($status);
                $product->save();
            }

W efekcie status został zaktualizowany, ale niestety czy tego chciałem czy nie skrypt zaktualizował również wszystkie atrybuty w Wszystkich widokach nie tylko w tym głównym. Jeśli mamy tylko jedną wersję językową wówczas dość kłopotliwe jest przełączanie się do widoku PL i modyfikowanie danych. Klienci często o tym zapominają podczas edycji i pojawiają się zgłoszenia do serwisu, że sklep pomimo zmian w panelu nie aktualizuje danych na front-endzie.

Aby wymusić aktualizację atrybutów tylko w store_id = 0 przerobiłem skrypt tak aktualizował w określonym widoku oraz nie powielał danych.

magento-aktualizacja-atrybutu-produktu-z-pliku-csv

Poniższy skrypt pozwala zaktualizować wybrany atrybut np. status w konkretnym store_id.

 

use Magento\Framework\App\Bootstrap;
require '/var/www/virtual/klimamarket.pl/htdocs/app/bootstrap.php';

$csv = "statusy.csv";
$storeId = 0;
$params = $_SERVER;
$bootstrap = Bootstrap::create(BP, $params);

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

$productRepository = $obj->get('Magento\Catalog\Model\ProductRepository');
$product_ = $obj->get('Magento\Catalog\Model\ProductFactory');
$productResourceModel = $obj->get('Magento\Catalog\Model\ResourceModel\Product');

if (!empty($argv) && sizeof($argv) > 1) {
    $csv = $argv[1];
}
if (($handle = fopen($csv, "r")) !== FALSE) {
    $i = 1;
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {

        if ($i == 1) {
            $i++;
            continue;
        }
        $sku = trim($data[0]);
        $status = $data[1];

        /**
         * Aktualizacja atrybutu produktu w wybranym store_id
         */

        try {
            if ($product = $productRepository->get($sku)) {

                $productFactory = $product_->create();
                $productResourceModel->load($productFactory, $product->getEntityId());
                $productFactory->setStoreId($storeId);

                $productFactory->setStatus($status);
                $productResourceModel->saveAttribute($productFactory, 'status');
            }

        } catch (\Exception $e) {
            echo "Error:  Invalid SKU, " . $sku . "\n";
            continue;
        }


    }
    fclose($handle);
}

 

 

Skrypt PHP wraz oraz plik CSV należy dodać do folderu pub znajdującego się w głównym folderze sklepu Magento