Magento 2 – How to Create Product Programmatically with Different Store View Values

create-productmagento2programmaticallystore-view

I have created this custom import module that will create products and set different values for each store view. The problem is, when I save a single attribute for the product on a store view, all the other attributes are saved to it as well for that store view. I want the store view version to inherit (use default) all values except the one I'm changing (description).

This is stripped/simplified version of the script:

// Create a product model using \Magento\Catalog\Model\ProductFactory
$productModel = $this->productFactory->create();

// Set the default values
$productModel
  ->setStoreId(0)
  ->setName($name)
  ->setAttributeSetId($productModel->getDefaultAttributeSetId())
  ->setWebsiteIds([1,2])
  ->setVisibility(4)
  ->setUrlKey($urlKey)
  ->setStatus(2)
  ->setTypeId('simple')
  ->setPrice(10)
  ->save();

// Reload product
$productStoreView = $this->productFactory->create()
  ->load($productModel->getId())
  ->setStoreId(1)
  ->setDescription('Desc for store view 1')
  ->save();

$productStoreView = $this->productFactory->create()
  ->load($productModel->getId())
  ->setStoreId(2)
  ->setDescription('Desc for store view 2')
  ->save();

The result now when I, using Magento 2 admin, looking at the product, each store view has it's own values for status, name etc set for each store view when it should only be "description" that isn't using default value.

Any tips on what I'm doing wrong?

Updated 2017-01-30:

I've started up a brand new environment with a fresh Magento 2.1.3 install. Then I created a new website, store and store view with the same root catalog.

After that, I saved this script in pub/test.php and executed it via CLI (I know it's not best practice, it's just to test/prove my case).

I visit admin and click on the newly created product. The default view looks as it's supposed to. I then switch stores and status is not using default value among other attributes.

<?php

use Magento\Framework\App\Bootstrap;

require __DIR__ . '/../app/bootstrap.php';

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

$obj = $bootstrap->getObjectManager();

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

$product = $obj->get('Magento\Catalog\Model\Product');

$product
    ->setName('Random name ' . time())
    ->setSku(time())
    ->setPrice(0)
    ->setStatus(2)// Disabled
    ->setWebsiteIds([1, 2])
    ->setVisibility(4)
    ->setAttributeSetId($product->getDefaultAttributeSetId())
    ->setTypeId('simple')
    ->save();

echo "Saved product ID " . $product->getId() . "\n";

$obj->create('Magento\Catalog\Model\Product')
    ->load($product->getId())
    ->setStoreId(1)
    ->setDescription('Description store view 1')
    ->save();

$obj->create('Magento\Catalog\Model\Product')
    ->load($product->getId())
    ->setStoreId(2)
    ->setDescription('Description store view 2')
    ->save();

All store views: https://i.stack.imgur.com/YkGjV.jpg

Store view 1: https://i.stack.imgur.com/C8Tuh.jpg

Store view 2: https://i.stack.imgur.com/uAS2h.jpg

Best Answer

I think the best answer to this question currently looks like this (using price as example attribute):

/** @var  \Magento\Catalog\Model\ProductFactory */
protected $productFactory;

/** @var  \Magento\Catalog\Model\ResourceModel\Product */
protected $productResourceModel;

public function __construct(
    \Magento\Catalog\Model\ProductFactory $productFactory,
    \Magento\Catalog\Model\ResourceModel\Product $productResourceModel
)
{
    $this->productFactory = $productFactory;
    $this->productResourceModel = $productResourceModel;
}


private function setStoreViewPrice($productId, $storeId, $price)
{
    $product = $this->productFactory->create();
    $this->productResourceModel->load($product, $productId);
    $product->setStoreId($storeId);
    $product->setPrice($price);
    $this->productResourceModel->saveAttribute($product, 'price');
}

See also https://magento.stackexchange.com/a/114958/35180

Related Topic