Customer behavior studies shows that customers check products on first page, if searched product is not there they will only small number will go to second page or third page. Most likely they will try to use search or redefine there search parameters to get better results. That is why is important to display on first page products that are ‘in stock’ and can be purchased right away.
Magento offer several options how to sort products on catalog page, with this little snippet we will extend that feature by keeping same order but ‘out of stock’ products will be displayed as last on catalog page.
There are many ways to do that however we will go for simplest one, by copying Magento files into our ‘local’ folder, or course same code can be wrapped up in form of module for more effective use. For example we want to use this feature only on ‘Sale’ category to effectively keep available products on top of list.
First step would be to copy file ‘Toolbar.php’ from Magento core folder to our local folder:
/app/code/local/Mage/Catalog/Block/Product/List/Toolbar.php
than open file in editor and find function ‘setCollection’ and copy complete code. We will rename new function from ‘setCollection’ to ‘setCatalogCollection’ and add code that will sort products by stock status. New function should look like this:
public function setCatalogCollection($collection)
{
$this->_collection = $collection;
$this->_collection->setCurPage($this->getCurrentPage());
// we need to set pagination only if passed value integer and more that 0
$limit = (int)$this->getLimit();
if ($limit) {
$this->_collection->setPageSize($limit);
}
if ($this->getCurrentOrder()) {
$this->_collection->joinField('inventory_in_stock', 'cataloginventory_stock_item', 'is_in_stock', 'product_id=entity_id','is_in_stock>=0', 'left')->setOrder('inventory_in_stock', 'desc');
$this->_collection->setOrder($this->getCurrentOrder(), $this->getCurrentDirection());
}
return $this;
}
We will need to copy one more from Magento core folder to our local folder:
/app/code/local/Mage/Catalog/Block/Product/List.php
In ‘List.php’ file find line:
$toolbar->setCollection($collection);
and replace it with our new function:
$toolbar->setCatalogCollection($collection);
Save all changes, refresh cache and check front end to see how code works. If everything is done properly your catalog page ordering will be adjusted and ‘out of stock’ products will be listed as last in collection.
It is important not to overwrite Magento default function ‘setCollection’ since it might happen that some 3rd party modules will use it and can cause site to crash (issue confirmed with free blog extensions).
I hope that this little trick with help you, if I have some free time in next few weeks I will try to create module to save you time and spare you from editing files.

Works on CE 1.9.2.3 – thanks!
Is there a way to make it work with configurable products? So that when all options are out of stock, then the parent configurable will go down in the list.
Hello,
thanks for comment, will it should work with configurable products as well. As far as I know when all options are ‘out of stock’ main product should be set out of stock too automatically, I can test this particular case to be sure that it works.
Cheers !
It works fine,
Thank you.
Hello Bernardo,
thank you very much for comment 🙂
Cheers
I am having real trouble with this, and any answer involving adding files to my local directory. I am on 1.9.2.1 and cannot get this solution to work. If you have any suggestions, tips, or tricks that may apply to my version please let me know. Thank you.
Hi,
This worked for me fine on category pages, but it broke search result pages.
http://pastebin.com/nubpD3UT
Any ideas?
Hello Daniel,
sorry to hear that, I tested on my local machine code and it works fine on catalog and search page.
Can you contact me via email and maybe we can find out what happen ?
Hello Daniel,
please shear your solution when you have chance – Thanks!
Hello,
I would like to point that Daniel had issue with 3rd party search module that caused mini conflict. Issue is resolved by turning OFF setting in module that also push ‘out of stock’ products to end of collection.
Cheers!
Hello,
Hope you’re doing great. I want to order my recently added products first but also place the out of stock products in last, Is it possible?
The main reason is out of stock products render the page uneven.
Current Code using..
if(($this->getCurrentOrder())==’position’){
$this->_collection->setOrder(‘entity_id’,’desc’);
Hello,
we are fine, thanks 🙂
You can try to use something like this:
$this->_collection->setOrder(array(‘attribute1’, ‘attribute2’), asc);
Hi,
Unfortunately it will not work for me on CE 1.9.2.2
Ik don’t get warnings or something, it just doesn’t work. Do you know what the problem is?
Kind regards,
Toshi
Hello,
did you checked message in warning, maybe you have custom theme or some 3rd party module that is causing conflict with code ?
This is not working for me for configurable products, Magento 1.9
can you give any solution for that ?
Even I found the same problem. Please reply if anyone has fond the solution.
Hello,
I can check, please send me version of Magento that you use.
Thanks!
Thank you. It worked perfectly and helped me a lot lot.
I’m ok with its working but my only concern is I’m not able to revert back by undoing this blogq. why isn’t it working? how to revert back this code after applying? any help regarding this?
Hello,
just remove files from ‘local’ pool, refresh Magento cache and that is all.
I hope that you followed guide and didn’t made changes to Magento core files, in that case you will need to copy files from Magento installation package.
Cheers!
Sir I’m facing a small problem after placing this code so willl you guide me in detail regarding this through mails. talagapu.sivamanohar@gmail.com is my mail. so will you please respond me and guide me.
talagapu.sivamanohar@gmail.com
Works Great! 1.9.3.6
Hello Justin,
than you own me a beer 🙂
Will this also work when products are searched? So if someone searches for Jack it will show the OOS products last.? We use Sphinx search extension
Hello,
I had chance to work with Sphinx engine (by using Mirasvit search modules) but didn’t tested code for OOS with it, at least you can try and share results for us 🙂
Hi , i am getting an error like this after following your steps
‘Joined field with this alias is already declared’.Please help.
Hello,
please check code that create product collection and look for ‘joinField’ function, because alias must be unique.
You can also try to dump MySql query and there you should be able to see all joined fields and possible duplicate entry.
Thanks !
SELECT `e`.*, `price_index`.`price`, `price_index`.`tax_class_id`, `price_index`.`final_price`, IF(price_index.tier_price IS NOT NULL, LEAST(price_index.min_price, price_index.tier_price), price_index.min_price) AS `minimal_price`, `price_index`.`min_price`, `price_index`.`max_price`, `price_index`.`tier_price`, `at_inventory_in_stock`.`is_in_stock` AS `inventory_in_stock` FROM `catalog_product_entity` AS `e` INNER JOIN `catalog_category_product_index` AS `cat_index` ON cat_index.product_id=e.entity_id AND cat_index.store_id=1 AND cat_index.visibility IN(2, 4) AND cat_index.category_id IN(’37’) INNER JOIN `catalog_product_index_price` AS `price_index` ON price_index.entity_id = e.entity_id AND price_index.website_id = ‘1’ AND price_index.customer_group_id = 0 LEFT JOIN `cataloginventory_stock_item` AS `at_inventory_in_stock` ON (at_inventory_in_stock.`product_id`=e.entity_id) AND (is_in_stock>=0)
The is the mysql query output.Can u please find the problem
its not worked in 1933 version can you please another way for sort out that?