1

As the title states, in Magento 1.9.2.2 I need to show products out of stock if they have the value of a specific attribute (for example the custom attribute 'always_show') set to 1 in the layered navigation.

How do I accomplish that? Do I have to extend the Mage_Catalog_Block_Product_List class?

1
2

After several tries I come up with the solution to my problem. I report my solution in case anyone will need it.

The first thing to do is rewriting the Mage_Catalog_Model_Layer. I created a custom module Custom_Module and in its config.xml, under the tag <global> I put:

<models>
    ...
    <catalog>
        <rewrite>
            <layer>Custom_Module_Model_Layer</layer>
        </rewrite>
    </catalog>
    ...
</models>

Then I created the rewritten Layer Model, in app/code/local/Custom/Module/Model/Layer.php

class Custom_Module_Model_Layer extends Mage_Catalog_Model_Layer
{
    /**
     * Initialize product collection
     *
     * @param Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection $collection
     * @return Mage_Catalog_Model_Layer
     */
    public function prepareProductCollection($collection)
    {
        $collection
        ->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
        ->addMinimalPrice()
        ->addFinalPrice()
        ->addTaxPercents()
        ->addUrlRewrite($this->getCurrentCategory()->getId());

        Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection);
        Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);

        // this filters products which has are in stock or out of stock and custom_attribute enabled

        Mage::getSingleton('custom_module/custom')->addCustomFilter($collection);

    }
}

Then I created the required model to add the filter in app/code/local/Custom/Module/Model/Custom.php

class Custom_Module_Model_Custom extends Mage_Core_Model_Abstract
{
    public function addCustomFilter($collection){
        $this->_getResource()->addCustomFilter($collection);
        return $this;
    }
}

And eventually I created the resource model in app/local/Custom/Module/Model/Resource/Custom.php

class Custom_Module_Model_Resource_Custom extends Mage_Core_Model_Resource_Db_Abstract{
    public function addCustomFilter($collection)
    {
        $websiteId = Mage::app()->getStore($collection->getStoreId())->getWebsiteId();
        $joinCondition = $this->_getReadAdapter()
            ->quoteInto('e.entity_id = stock_status_index.product_id'
                . ' AND stock_status_index.website_id = ?', $websiteId
            );

        $joinCondition .= $this->_getReadAdapter()->quoteInto(
            ' AND stock_status_index.stock_id = ?',
            Mage_CatalogInventory_Model_Stock::DEFAULT_STOCK_ID
        );

        $collection->getSelect()
            ->join(
                array('stock_status_index' => 'cataloginventory_stock_status'),
                $joinCondition,
                array()
            );

        $attributeCode = 'custom_attribute';
        $attribute = Mage::getSingleton('eav/config')->getAttribute(Mage_Catalog_Model_Product::ENTITY, $attributeCode);
        // get custom attribute values
        $collection->getSelect()
            ->join(
                array("custom_attribute" => $attribute->getBackendTable()),
                "e.entity_id = custom_attribute.entity_id AND custom_attribute.attribute_id = " . $attribute->getId(),
                array()
            )
            // filter out in stock products and not in stock products with custom_attribute = 1
            ->where('stock_status_index.stock_status=' . Mage_CatalogInventory_Model_Stock_Status::STATUS_IN_STOCK . ' OR (stock_status_index.stock_status=' . Mage_CatalogInventory_Model_Stock_Status::STATUS_OUT_OF_STOCK . ' AND custom_attribute.value = 1)');

        return $this;
    }
}
1
  • good works.. it will help lot of people
    – Amit Bera
    May 3 '16 at 18:39
0

I have not tried the above, but I've made similar modifications in the past. This time I tried something simpler that works suprisingly well - instead of touching layered navigation at all, change the data that it refers to by tweaking the product attribute index so that the attribute (e.g. size) value (e.g. 37.5) is not stored against the configurable product if the simple product with that value is out of stock (e.g. size 37.5 is out of stock). By changing this index, the layered navigation will follow suit.

Full answer and code here: https://magento.stackexchange.com/a/154654/13636

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.