15

I have the following code:

$_productCollection = $this->getLoadedProductCollection();

foreach ($_productCollection as $_product)
{
  if ($_product->_data['type_id'] == 'configurable')
  {
    ...
  } 
}

While it does what it's supposed to do, it greatly slows down page load time. Is it possible to load only configurable products and remove the check for 'configurable'? The store has 12000 products, about 700 are configurable and the rest are child simple products.

I found the following code which returns all configurable products. I need only the products within the current category:

$collectionConfigurable = Mage::getResourceModel('catalog/product_collection')
                ->addAttributeToFilter('type_id', array('eq' => 'configurable'));
Vincent
  • 16,086
  • 18
  • 67
  • 73
  • Can you cache the output or collection obtained from this code? – alex Mar 12 '11 at 03:45
  • I'm not sure what you mean but I did `fwrite($f, print_r($_productCollection, true))` and the file size was 54MB. `$_productCollection->count()` returns 5420. Obviously I can't post it here. – Vincent Mar 12 '11 at 03:56

7 Answers7

29

The problem with getLoadedProductCollection() is it's already loaded - the products' data has already been retrieved from the database. Just using the current category's product collection isn't good enough either, that will ignore the "layers" (attribute filters). The trick is to remove the loaded products from the list first.

// First make a copy, otherwise the rest of the page might be affected!
$_productCollection = clone $this->getLoadedProductCollection();
// Unset the current products and filter before loading the next.
$_productCollection->clear()
                   ->addAttributeToFilter('type_id', 'configurable')
                   ->load();

print_r($_productCollection) has it's issues too, you're not just outputting the products but also all details of the resource that is the database connection, and cached values, and the products' individual resources, and so on...

In this case I think you would be happier with:

print_r($_productCollection->toArray())
clockworkgeek
  • 37,650
  • 9
  • 89
  • 127
  • Is there a way not to load simple products from DB at all? – Vincent Mar 12 '11 at 21:23
  • You could set their visibility to "Not visible individually", that would exclude them from product lists. If you mean specifically to this occasion then use the filter `addAttributeToFilter('type_id', array('neq' => 'simple'))`. `neq` obviously means "Not EQual". – clockworkgeek Mar 12 '11 at 21:34
  • +1 to this method. I like the clone and clear - very succinct. – philwinkle Mar 13 '11 at 06:24
  • 1
    @clockworkgeek discovered today that `clone` doesn't create a clean copy in Magento due to PHP's shallow cloning and because Varien didn't implement __clone() - ref : http://stackoverflow.com/questions/4959949/clone-is-not-working-for-me/4960001#4960001 - – Jonathan Day Oct 11 '11 at 09:40
  • i tried to use the technique with event `catalog_product_collection_load_before` , it gave correct output but still the toolbar is showing 6 items where there is only 1 loaded. my code: `$observer->getCollection() ->clear() ->addAttributeToSelect('*') ->addAttributeToFilter('entity_id', array('nin' => $excludeIds)) ->load();` – R T Apr 13 '15 at 19:25
  • should i write a new question? your help is best acknowledged and appreciated. thank you. – R T Apr 13 '15 at 19:26
  • @MadMax you should start a new question since this one is years old and doesn't explain the problem with toolbars/pagers. – clockworkgeek Apr 14 '15 at 12:24
7

All those solutions didn't work for me, try this:

$_productCollection1 = Mage::getResourceModel('catalog/product_collection')
            ->addAttributeToSelect('*')
            ->addAttributeToFilter('type_id','configurable'); 

foreach ($_productCollection1 as $product1) {
    echo $product1->getName();
    ...
}

It works but don't know if it's correct (I'm new to Magento). Let me know please.

Fred K
  • 13,249
  • 14
  • 78
  • 103
3

Try following

   $collection  =  Mage::getModel('catalog/product')->getCollection();
   $collection->addAttributeToFilter('type_id','configurable');

    foreach($collection as $product)
    {

    }

For loading configurable and simple as well try

$collection->addAttributeToFilter('type_id', array('in' => array('configurable','simple')));
Mukesh
  • 7,630
  • 21
  • 105
  • 159
3

The way you're doing this requires all products to be loaded before you parse through and filter them. This is probably closer to what you're looking for:

$_productCollection = $this ->getLoadedProductCollection()
                            ->addAttributeToFilter('type_id','configurable');
philwinkle
  • 7,036
  • 3
  • 27
  • 46
0

Here is the code for getting only configurable products:

 $Config_products  =  Mage::getModel('catalog/product')->getCollection()
            ->addAttributeToFilter('type_id','configurable');
0

Use \Magento\Catalog\Model\ResourceModel\Product\Collection $_productcollection,

public function getConfigProducts() {
     $configproducts = $this->_productcollection;
     $configproducts->addAttributeToSelect('*');
     $configproducts->addAttributeToFilter('status',\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);
     $configproducts->addAttributeToFilter('show_in_price_page', array('eq' => 1));
     $configproducts->addAttributeToFilter('type_id', array('eq' => "configurable"));
     return $configproducts;
}
Elikill58
  • 4,050
  • 24
  • 23
  • 45
-1

If you change Visibility of simple product to "Not Visible Individually", Magento will not load it to display in product list page.

ndlinh
  • 1,345
  • 9
  • 13