Magento 2 change product status programmatically
This shows how to change product status programmatically in Magento 2. Sometimes you need to create scripts that mass activate or deactivate products by cron, so you need to know how to change a product status and also how to do it in an optimized way. You also need to consider different stores, because status is an attribute with website scope.
Magento 2 change product status programmatically
A product status has two different states:
- enabled
product is visible in frontend - disabled
product is not visible in frontend
You can set this states on default store or for each website individually. On a multi store environment you can so define products that are only visible in specific frontends.
Change status programmatically
To change status you can load a product model and set status to a new value. You need to save this product. That works, but is very slow- Depending on the number of product attributes, saving a product can lasts some seconds. If you need to mass change product status, this can take a long time. A simple performance optimization is to only update needed attributes as I showed in Magento 2 speed optimization article. But for programmatically changing product status, there is a better way:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | $productIdsActivate = []; $productIdsDeactivate = []; foreach($this->productCollection as $product) { ... if($product->getActivate()) { $productIdsActivate[] = $product->getId(); } else { $productIdsDeactivate[] = $product->getId(); } } $storeIds = array_keys($this->storeManager->getStores()); //activate products $updateAttributes['status'] = \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED; foreach ($storeIds as $storeId) { $this->productAction->updateAttributes($productIdsActivate, $updateAttributes, $storeId); } |
First we need to get productCollection with all products. Then you run a loop for every product and check a condition. This condition should decide if you need to activate or deactivate a product. This can be anything, I used a active product attribute. You can also need two date fields that define a time period when a product should be active (for example only new week).
Two arrays saves product ids of to activate and to deactivate product ids. The last thing you need to do is to run updateAttributes method from Magento\Catalog\Model\ResourceModel\Product\Action model. This method needs 3 arrays:
- products ids to update
- attributes with value to update
- store ids to update attributes
You simply need to call this once and all products are updated for every attribute and every store.
Conclusion
You can use Magento\Catalog\Model\ResourceModel\Product\Action model to change product status programmatically easy and fast. This method is much faster than every other and optimized for this case.
Awesome and Handy post. Thanks for sharing it.