Magento CE v2.1.1
at least 2 stores and websites
a product to test that is only in 1 of the websites
public function execute(\Magento\Framework\Event\Observer $observer)
{
$product = $observer->getProduct();
if ($product->getSku() != 'TEST-SKU') {
$product = $this->productRepository->get('TEST-SKU');
$product->setPrice(9.99); // or anything you want to change to test
$this->productRepository->save($product);
}
}
The products websites should remain unchanged.
This is the behavior when saving a product through the admin, but it is because the Save controller uses the old deprecated $product->save() method.
The product has been added to all websites.
This is due to the assignProductToWebsites method of ProductRepository:
if ($this->storeManager->getStore()->getCode() == \Magento\Store\Model\Store::ADMIN_CODE) {
$websiteIds = array_keys($this->storeManager->getWebsites());
If anyone is interested in the workaround, here is the code I use:
$websites = $product->getWebsiteIds();
$savedProduct = $this->productRepository->save($product);
$addedWebsites = array_diff($savedProduct->getWebsiteIds(), $websites);
$this->productWebsiteFactory->create()->removeProducts($addedWebsites, [$product->getId()]);
@dunarri Did other fields change as well? For instance, let's assume the product you were loading had "USE DEFAULT" checked for all values on all websites. When setting the price, does the other values go from "USE DEFAULT" to the same value but the "USE DEFAULT" button unchecked?
@robbanl I'm not sure what you mean, no field on my product edit screen has a use default option. The closest is "Use Config Settings" for "Allow Gift Message".
I've upgraded to the latest Magento 2.1.5 and tested the issue again and the problem still persists. Of course it does because the code in ProductRepository::assignProductToWebsites is still exactly the same.
I'm having the exact same issue as well.
@robbanl, product data (for example, "name") is not duplicated across scopes, it remains global (being greyed out on a store view scope and showing "use default"):

There is no way, using either ProductRepositoryInterface, or ProductWebsiteLinkRepositoryInterface to assign a product to any websites if your script is running in an admin website context. The reason we're doing that is so all data is updated on a global scope and not specific to the default website:

The above screenshot is from a console command that syncs products back in from a third party service.
@dunarri, thank you for your report.
This seems to be correct Magento behavior. Please refer to the Community Forums or the Magento Stack Exchange site for advice or general discussion about this.
Otherwise you may submit Pull Request with the suggested changes.
@magento-engcom-team I don't think it is a correct behavior because editing through the admin panel doesn't work like that. The product repository shouldn't override product websites (especially two or more websites) if it is set in the object.
This issue was fixed by the https://github.com/magento/magento2/commit/30c4881 ( PR https://github.com/magento/magento2/pull/11444 ).
So, I think, @magento-engcom-team, you can close it.
@RomaKis thank you for investigation. Closing