Magento 2 saving update product in "All Store Views"
I've noticed the same thing - Magento 2 ignores this:
$product->setStoreId(0);
So what we've done thats seems to allow us to achieve what you are trying to do is to use the \Magento\Store\Model\StoreManagerInterface instead.
In your constructor
public function __construct(
\Magento\Store\Model\StoreManagerInterface $storeManager
) {
$this->_storeManager = $storeManager;
}
Then in your code before you try to update the products you can do:
$this->_storeManager->setCurrentStore(0);
Tip: I've started doing this though, to make sue that the appropriate store gets put back when I'm done:
$originalStoreId = $this->_storeManager->getStore()->getId();
$this->_storeManager->setCurrentStore(0);
// Do other things...
$this->_storeManager->setCurrentStore($originalStoreId);
If you only need to change a single product attribute, the product model has an addAttributeUpdate() method that takes store_id as a parameter:
$store_id = 0; // or 1,2,3,... ?
$attribute_code = 'name';
$value = 'Storeview Specific Name';
$product->addAttributeUpdate($attribute_code, $value, $store_id);
Looking at the method in ./vendor/magento/module-catalog/Model/Product.php - it automatically does the "save the current store code and switch back after the update" thing that mcyrulik's answer does,
## ./vendor/magento/module-catalog/Model/Product.php
/**
* Save current attribute with code $code and assign new value
*
* @param string $code Attribute code
* @param mixed $value New attribute value
* @param int $store Store ID
* @return void
*/
public function addAttributeUpdate($code, $value, $store)
{
$oldValue = $this->getData($code);
$oldStore = $this->getStoreId();
$this->setData($code, $value);
$this->setStoreId($store);
$this->getResource()->saveAttribute($this, $code);
$this->setData($code, $oldValue);
$this->setStoreId($oldStore);
}
You can use \Magento\Catalog\Model\ResourceModel\Product\Action
like this:
public function __construct(
\Magento\Catalog\Model\ResourceModel\Product\Action $productAction
) {
$this->productAction = $productAction;
}
And then quickly update atributes:
$this->productAction->updateAttributes(
[$row->getProductId()], //array with product id's
[
$row->getAttributeCode() => $row->getAttributeValue(),
$row->getOtherAttributeCode() => $row->getOtherAttributeValue()
],
$storeId
);
This is especially good (fast) for changing attributes to many products at once.