Okay, here's the situation: Because of how the product save works, $this->_productRepository->save($newProduct);
does not reflect changes back onto your $newProduct
. It's actually creating a new Product
instance and copying your data onto it inside there. Sound slow and inefficient? Yeah. This approach probably makes data integrity easier to maintain though.
To walk through that core method:
You pass a Product
into the method, used as $product
.
public function save(\Magento\Catalog\Api\Data\ProductInterface $product, $saveOptions = false)
They re-load the product by SKU, and copy link data from it onto yours.
$existingProduct = $this->get($product->getSku());
$product->setData(
$this->resourceModel->getLinkField(),
$existingProduct->getData($this->resourceModel->getLinkField())
);
They convert your product into a data array.
$productDataArray = $this->extensibleDataObjectConverter
->toNestedArray($product, [], \Magento\Catalog\Api\Data\ProductInterface::class);
$productDataArray = array_replace($productDataArray, $product->getData());
They create a new Product
object from that data.
$product = $this->initializeProductData($productDataArray, empty($existingProduct));
They save that new $product
.
unset($this->instances[$product->getSku()]);
unset($this->instancesById[$product->getId()]);
$this->resourceModel->save($product);
Finally, they load the product again, and return that.
return $this->get($product->getSku());
What this means in practice: $newProduct
(the Product
you passed in) will not give you any data about the save. It's exactly the same object after saving as you had before, because it's not touched directly (except for in #2). But $this->_productRepository->save()
actually returns the saved product model. Basically, they're shuffling objects around, and that complicates things.
With all that in mind, try this for your product save:
$newProduct = $this->_productFactory->create();
$newProduct->setName('Test Product')
->setTypeId(Type::TYPE_SIMPLE)
->setSku('test-product')
->setPrice($configurableProduct->getPrice())
->setWeight($configurableProduct->getWeight())
->setStatus(Status::STATUS_ENABLED)
->setVisibility(Visibility::VISIBILITY_NOT_VISIBLE)
->setAttributeSetId($configurableProduct->getAttributeSetId())
->setData('my_product_attribute', 'sample_value');
$newProduct = $this->_productRepository->save($newProduct);
$newId = $newProduct->getId();
Note that we're reassigning $newProduct
to the result of the repository save. That gives us the saved ID and anything else that resulted.