Magento product list collection modification

According to Marius, events are always the best approach to modify and apply filter on product listing page. This way, your changes are independent of the presentation layer (theme). If you have 2 websites with different themes you will have all modifications in one place. Changing the template file may result in pagination problems.

I had a requirement to customize product listing (category) page such that if a configurable product is present, and even a single associated product for that configurable product is out of stock, configurable product should not appear in product listing (category) page.

I’ve created my own module and observer and customized it. Here goes the code:

app/etc/modules/Retailon_Configurable.xml

<config>
<modules>
<Retailon_Configurable>
<active>true</active>
<codePool>local</codePool>
</Retailon_Configurable>
</modules>
</config>

app/code/local/Retailon/etc/config.xml

<?xml version="1.0"?>
<config>
<global>
<models>
<retailon_configurable>
<class>Retailon_Configurable_Model</class>
</retailon_configurable>
</models>
</global>
<frontend>
<events>
<catalog_block_product_list_collection>
<observers>
<retailon_configurable_list>
<type>singleton</type>
<class>retailon_configurable/observer</class>
<method>addInStockOnlyFilter</method>
-</retailon_configurable_list>
</observers>
</catalog_block_product_list_collection>
</events>
</frontend>
</config>

app/code/local/Retailon/Model/Observer.php

<?php

class Retailon_Configurable_Model_Observer {
/**
* Observes the catalog_block_product_list_collection event
*/
public function addInStockOnlyFilter($observer){
$productCollection = $observer->getEvent()->getCollection();

foreach ($productCollection as $product) {
if ($product->getTypeId() == "configurable"){
$product->getTypeInstance(true)->getUsedProducts ( null, $product);
foreach ($product->getTypeInstance(true)->getUsedProducts ( null, $product) as $simple) {
//all associated pro
if($simple->getStockItem()->getQty() < 1 ){
$proArray[] = $product->getId();
}
$stock = Mage::getModel('cataloginventory/stock_item')->loadByProduct($simple)->getQty();
echo $simple->getName()." with size ".$simple->getSize()." have a stock of ".$stock. " have sku "
.$simple->getSku()."Qty of ".$simple->getStockItem()->getQty();
echo '<br/>';
}
}
}

if(count($proArray)){
foreach ($proArray as $key) {
$productCollection->removeItemByKey($key);
}
}

$observer->getEvent()->setCollection($productCollection);
}

}
Advertisements

4 thoughts on “Magento product list collection modification

  1. Hi Amitshree,
    Thanks for sharing this. I’m trying to do the similar thing, I’m hooking to the same event with yours to remove those items that don’t belong to a certain product type. Your solution works for me, however, I noticed that the number of items shown at the toolbar on product listing page is still the same before I removed some products. Currently, there are 4 items shown in my product listing page, but the toolbar still says 5 items. Did you have the same problem?

    Like

    • Jimmy, I think it won’t change item counts shows in the toolbar based on applied observer filters. it will only hide/filter product visibility in product listing based on applied observer.

      Like

    • Hi Trinh,
      That’s not necessary but while I was working on it I was getting the filtered products in my observer but the products back on the category page were not appearing as per the filters, So I had to set the collection again and it worked fine.

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s