How to get product collection of given main category id?
-
16-10-2019 - |
Question
In my website I have several stores available. One particular store contains both the simple and configurable products. This is a huge collection of products. What is the fastest way to get all enabled products (including child products of configurable products)
collection of this store by store id?
Note: I tried this lot of different ways. But it takes loo much time. Sometimes cause to crash the server even.
Note : I'm using Magento CE 1.3
Any suggestions will be appreciated.
Solution
$category = Mage::getModel('catalog/category')->load($categoryId);
$collection = Mage::getModel('catalog/product')->getCollection()
->addCategoryFilter($category);
//you can use the next lines to add some minimal information about the products to the collection
//thanks @DavidManners
$collection->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes()) //add list attributes
->addMinimalPrice() //add prices
->addFinalPrice()
->addTaxPercents()
//or
//$collection->addAttributeToSelect('*');//if you want all the attributes
Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection);//only enabled products
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);//only visible products
Now the problem. Usually the simple products associated to the configurable ones are not associated to a category or they are set not to be visible. If this is not the case for you then the code above should be enough. If they are associated to a category but they are not visible then just comment the last line.
Otherwise you have to loop through the products and when you find a configurable one get it's associated products:
//this is needed if you want to get the out of stock simple products also
Mage::helper('catalog/product')->setSkipSaleableCheck(true);
$allProducts = array();
foreach ($collection as $product){
$allProducts[] = $product;
if ($product->getTypeId() == 'configurable'){
$simpleProducts = $product->getTypeInstance(true)
->getUsedProducts(null, $product);
foreach ($simpleProducts as $simple){
$allProducts[] = $simple;
}
}
}
Now you should have all the products you need in $allProducts
array.
This may not be fast due to getting the simple associated products but should get you what you need. I hope it doesn't crash the server.
OTHER TIPS
To add on @Marius his answer, to limit the used resources you can use the resource_iterator class.
Mage::getSingleton('core/resource_iterator')->walk($collection->getSelect(), array('productCallback'), array());
function productCallback($args)
{
var_dump($args['row']);
[...]
}
Instead of executing the the query and retrieving all the results at once Magento will now handle one result at the time, then moving on to the next.