There are several Previous/Next extensions out there for Magento by now. Honestly I do not know how any of them works as I never used any :). I decided to code my own since I wanted to tackle the challenge of coding the previous/next that works alongside the layered navigation filter and sort order in the product listing grid.
Here is an example code for the extension (partial but fully functional) I just posted few minutes ago on the Magento Connect (still waiting for approval, I’ll update the post with the link once it’s approved).
First we start of with the config.xml file of the Inchoo_Prevnext extension:
<config>
...
<frontend>
<events>
<controller_action_postdispatch>
<observers>
<inchoo_prevnext_set_filtered_category_product_collection>
<class>inchoo_prevnext/observer</class>
<method>setInchooFilteredCategoryProductCollection</method>
</inchoo_prevnext_set_filtered_category_product_collection>
</observers>
</controller_action_postdispatch>
</events>
</frontend>
...
</config>
Now we implement the actual observer method. Here I am grabbing the loaded product collection, the one last looked at the category product listing page. As you can see, I’m focusing down to the “category” controller, “view” action, extracting the product id’s from collection and setting them under the inchoo_filtered_category_product_collection session key. This way when I go on the product view page I can read the last viewed products grid and then decide what is previous and what next product. Next time I’m on category product listing grid this code will simply reset the id’s to those shown in the grid.
class Inchoo_Prevnext_Model_Observer
{
public function setInchooFilteredCategoryProductCollection()
{
/**
* There might be some illogical buggy behavior when coming directly
* from "Related products" / "Recently viewed" products block.
* Nothing that should break the page however.
*/
if (Mage::app()->getRequest()->getControllerName() == 'category' && Mage::app()->getRequest()->getActionName() == 'view') {
$products = Mage::app()->getLayout()
->getBlockSingleton('Mage_Catalog_Block_Product_List')
->getLoadedProductCollection()
->getColumnValues('entity_id');
Mage::getSingleton('core/session')
->setInchooFilteredCategoryProductCollection($products);
unset($products);
}
return $this;
}
}
And finally the helper class to host the getPreviousProduct and getNextProduct methods.
class Inchoo_Prevnext_Helper_Data extends Mage_Core_Helper_Abstract
{
/**
* @return Mage_Catalog_Model_Product or FALSE
*/
public function getPreviousProduct()
{
$prodId = Mage::registry('current_product')->getId();
$positions = Mage::getSingleton('core/session')->getInchooFilteredCategoryProductCollection();
if (!$positions) {
$positions = array_reverse(array_keys(Mage::registry('current_category')->getProductsPosition()));
}
$cpk = @array_search($prodId, $positions);
$slice = array_reverse(array_slice($positions, 0, $cpk));
foreach ($slice as $productId) {
$product = Mage::getModel('catalog/product')
->load($productId);
if ($product && $product->getId() && $product->isVisibleInCatalog() && $product->isVisibleInSiteVisibility()) {
return $product;
}
}
return false;
}
/**
* @return Mage_Catalog_Model_Product or FALSE
*/
public function getNextProduct()
{
$prodId = Mage::registry('current_product')->getId();
$positions = Mage::getSingleton('core/session')->getInchooFilteredCategoryProductCollection();
if (!$positions) {
$positions = array_reverse(array_keys(Mage::registry('current_category')->getProductsPosition()));
}
$cpk = @array_search($prodId, $positions);
$slice = array_slice($positions, $cpk + 1, count($positions));
foreach ($slice as $productId) {
$product = Mage::getModel('catalog/product')
->load($productId);
if ($product && $product->getId() && $product->isVisibleInCatalog() && $product->isVisibleInSiteVisibility()) {
return $product;
}
}
return false;
}
}
There is a known “issue” with this approach, that is it does not compensate for the rest of the possible pages in the category product grid. This is due to the fact that at the moment of fetching the id’s of category listed products we still do now know the ids of the products for possible other pages. This however would require more load on the server as it requires one or two extra database queries. Additionally, there might be some illogical prev/next from time to time (like if you are landing on a product directly without ever being on some category view page within the current session, etc) -Thus there is a room for improvement, but it’s important to know that nothing will get broken due to this.
Hope this code was helpful, and some of you find the room to improve it.
The post Listing out Previous/Next products in Magento (Inchoo_Prevnext extension) appeared first on Inchoo.