0

On the category page the products are normally loaded. Where out of stock products are hidden.
After that I need to load those same category products but also the ones that are out of stock. These are loaded after the page render (but before the response is send) because of an external system.

It is done in an observer

    // only affect the catalog_category_view
    if ( !in_array('catalog_category_view', Mage::app()->getLayout()->getUpdate()->getHandles() ) ) {
        return;
    }

    // where we need to add the other product ID's
    $cacheData = $observer->getCacheData();

    /** @var Mage_Catalog_Model_Resource_Product_Collection $productCollection */
    $productCollection = Mage::getSingleton('catalog/layer')->getProductCollection();

    // few things I tried
    //$select = $productCollection->getSelect();
    //$select->reset(Zend_Db_Select::WHERE);
    //$productCollection->resetData();
    $productIds = $productCollection->getAllIds();
    var_dump($productIds); // only the in stock items :(

I know it should be something with addAttributeToFilter/ removeAttributeToFilter or maybe in the getSelect But I just can't figure it out. Can anybody help me on my way?

2

It's actually not that simple, Mage_CatalogInventory is a separate module from Mage_Catalog and Mage_Catalog doesn't have any knowledge of stock information.

So when you get the product collection from the layer, it doesn't have any stock filter applied to it directly (although the CatalogInventory observer does add stock data after the collection gets loaded).

Rather, "information" about whether the product is saleable or not is added to a price index. This information is derived, among others, from the stock status from the CatalogInventory module. That is why if you change "Display Out of Stock Products" a bunch of indexers get invalidated.

I'm not too familiar with the internals regarding this topic, but basically if the product is out of stock, it will not have an entry in the catalog_product_index_price and therefor it will not pass the Mage_Catalog_Model_Resource_Product_Collection::addPriceData filter which is called through the calls to addMinimalPrice and addFinalPrice in the prepareProductCollection method of the layer (Mage_Catalog_Model_Layer).

Even though @Steve Robbins's answer is wrong (those filters have nothing to do with stock status - in fact, one of them is deprecated. If anything, Mage_CatalogInventory_Model_Stock::addInStockFilterToCollection would be responsible for filtering stock, but the only place where that's used are the upsells). His conclusion is right - you're better off creating a new collection, or somehow avoiding the price index or undoing the price index join that's happening in Mage_Catalog_Model_Resource_Product_Collection::_applyProductLimitations.

  • Thanks for the background details. I'll look into it Tuesday. – janw Oct 16 '15 at 7:04
1

When loading a collection through catalog/layer these filters are applied to it:

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

You could try to remove the parts from the Zend_Db_Select statement, but you may be better off creating a new collection with:

Mage::getModel('catalog/category')->load(Mage::getSingleton('catalog/layer')->getCurrentCategory()->getId())->getProductCollection();
  • Hi Steve, I've tried this but I just cannot seem to get it to really the actually layer filter. Any clue how to get that? – janw Oct 19 '15 at 14:14

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.