I need to push out of stock products to the end of catalog list
Please guide me how to solve this problem, or that file to dig
so far I found Toolbar.php
, and working around it
Magento Stack Exchange is a question and answer site for users of the Magento e-Commerce platform. It only takes a minute to sign up.
Sign up to join this communityI need to push out of stock products to the end of catalog list
Please guide me how to solve this problem, or that file to dig
so far I found Toolbar.php
, and working around it
This moves out of stock products to the end of the list on page, not all over the pagination:
1.Add event observer:<frontend>
<events>
<catalog_block_product_list_collection>
<observers>
<ssd_test>
<type>model</type>
<class>ssd_test/observer</class>
<method>catalogBlockProductCollectionBeforeToHtml</method>
</ssd_test>
</observers>
</catalog_block_product_list_collection>
</events>
</frontend>
2.Observer logic:
public function catalogBlockProductCollectionBeforeToHtml($observer)
{
/**
* @var $products Varien_Data_Collection
*/
$products = $observer->getEvent()->getCollection();
$soldOuts = array();
if ($products instanceof Varien_Data_Collection) {
foreach ($products as $product) {
if (!$product->isSaleable()) {
$products->removeItemByKey($product->getId());
$soldOuts[] = $product;
}
}
foreach ($soldOuts as $product) {
$products->addItem($product);
}
}
return $this;
}
3.Set "Display Out of Stock Products
" to "Yes
" on System->Configuration->Inventory
.
This moves out of stock products to the end of the list within all over the pagination:
config.xml: <frontend>
<events>
<catalog_product_collection_load_before>
<observers>
<review>
<type>model</type>
<class>ssd_test/observer</class>
<method>catalogProductCollectionLoadBefore</method>
</review>
</observers>
</catalog_product_collection_load_before>
</events>
</frontend>
Observer.php:
public function catalogProductCollectionLoadBefore($observer)
{
$toolbar = Mage::getBlockSingleton('catalog/product_list_toolbar');
if ($toolbar) {
$products = $observer->getEvent()->getCollection();
$stockId = Mage_CatalogInventory_Model_Stock::DEFAULT_STOCK_ID;
$websiteId = Mage::app()->getStore($products->getStoreId())->getWebsiteId();
$products->getSelect()->joinLeft(
array('_inv' => $products->getResource()->getTable('cataloginventory/stock_status')),
"_inv.product_id = e.entity_id and _inv.website_id=$websiteId and _inv.stock_id=$stockId",
array('stock_status')
);
$products->addExpressionAttributeToSelect('in_stock', 'IFNULL(_inv.stock_status,0)', array());
$products->getSelect()->reset('order');
$products->getSelect()->order('in_stock DESC');
if ($toolbar->getCurrentOrder()) {
$products->addAttributeToSort($toolbar->getCurrentOrder(), $toolbar->getCurrentDirection());
}
}
return $this;
}
Set "Display Out of Stock Products
" to "Yes
" on System->Configuration->Inventory
.
Above logics do not affect to your catalog sort/pagination functionality, only moves not salable products to the end.
I've implemented this functionality on my website.
Copy Collection.php from /app/code/core/Mage/Catalog/Model/Resource/Product/Collection.php to /app/code/local/Mage/Catalog/Model/Resource/Product/
Edit Collection.php, around line 1570 find text $storeId = $this->getStoreId();
Add the following lines directly bellow:
$this->getSelect()->joinLeft(
array('_inventory_table'=>$this->getTable('cataloginventory/stock_item')),
"_inventory_table.product_id = e.entity_id",
array('is_in_stock', 'manage_stock')
);
$this->addExpressionAttributeToSelect('on_top',
'(CASE WHEN (((_inventory_table.use_config_manage_stock = 1) AND (_inventory_table.is_in_stock = 1)) OR ((_inventory_table.use_config_manage_stock = 0) AND (1 - _inventory_table.manage_stock + _inventory_table.is_in_stock >= 1))) THEN 1 ELSE 0 END)',
array());
$this->getSelect()->order('on_top DESC');
Flush your cache and your products will now automatically sort the in stock products first and the out of stock products last.