Magento Bestseller Module

Bestseller Module that was dynamic and harnessed the power of Magento’s built in features

Posted on March 21, 2016 in Magento

Source Code

This shows you the code and gives the explanation of what is happening. First, the bestseller module extends Mage_Core_Block_Product_Abstract, and put in the folder /app/code/local/Mage/Catalog/Block/Product/.


class Mage_Catalog_Block_Product_Bestseller extends Mage_Catalog_Block_Product_Abstract {
    public function _prepareLayout() 
    {
        $storeId = Mage::app()->getStore()->getId();

        $products = Mage::getResourceModel('reports/product_collection')
                    ->addOrderedQty()
                    ->addAttributeToSelect('*")
                    ->setStoreId($storeId)
                    ->addStoreFilter($storeId);
        
        Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($products);
        Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($products);
        $this->setToolbar($this->getLayout()->createBlock('catalog/product_list_toolbar', 'Toolbar'));

        $toolbar = $this->getToolbar();
        $toolbar->setAvailableOrders(array(
                       'ordered_qty'=>$this->__('Most Purchased'),
                       'name'=>$this->__('Name'),
                       'price'=>$this->__('Price')
                ))
                ->setDefaultOrder('ordered_qty')
                ->setDefaultDirection('desc')
                ->setCollection($products);
        return $this;
    }
    
    protected function _getProductCollection() {
         return $this->getToolbar()->getCollection();
    }

    public function getToolbarHtml() {
       return $this->getToolbar()->_toHtml();
    }

    public function getMode() {
        return $this->getToolbar()->getCurrentMode();
    }

    public function getLoadedProductCollection() {
          return $this->_getProductCollection();
    }
}

Usage of Best Seller Module

Copy and paste following line into any CMS page:


{{block type="catalog/product_bestseller" template="catalog/product/list.phtml"}}

Explanation of Module

This module was designed as simply as possible, harnessing “stock” features of Magento. As such, it uses the standard “list.phtml” template used in Magento (used anytime you do a stock install and look at category of products, or other product listings). This is found at: app/design/frontend/default/default/template/catalog/product/list.phtml.

The Toolbar template is found here: app/design/frontend/default/default/template/catalog/product/list/toolbar.phtml

I did not create my own module for this since the Bestseller module works perfectly fine on it’s own as an addition to the Mage core (although in the Local folder of course! It doesn’t belong in the core files!)

This code doesn’t use the __constructor method, but instead goes right to the _prepareLayout method, as here we can access the Layout object (Mage_Core_Model_Layout) and thus include our Toolbar block. The first order of business it to grab our product collection. We grab it from the “reports/product_collection” resource model. The “Reports” module is where to go to create reports on past activity within Magento. In this case, see: app/code/core/Mage/Reports/Model/Mysql4/Product/Collection.php for any code investigation. Our product collection does minium processing – We add the “OrderedQty” attribute, all other attributes (you can narrow these down if you need), set the store ID and add the store filter. We also add visibility filters so we don’t get products showing which should not be.

Next, we create a new Toolbar block (the createBlock method is a factory for blocks). The Toolbar block (Mage_Catalog_Block_Product_List_Toolbar) extends a pagination class (Mage_Page_Block_Html_Pager) and so is an ideal way to organize a product collection. This will handle limiting the number of products collected, the order they are in, grid vs list mode, and whether they are acsending or descending. We do bare minimum filtering to the product collection ourselves and let the pagination class do the rest for us! Note that we set the “available orders” in our code. Without setting this, the “stock” orders used to filter the results are “Position”, “Name” and “Price” (position will appear as “Best Value”). We don’t want Best Value, we obviously want Ordered Quantity (I used “Most Purchased”). We also set the default order, which is “Descending” (we want the most purchased first).

The rest of the functions here are utility functions to make the list.phtml work together with our Bestseller block.

getToolbarHtml is called within the list.phtml file. Here we grab the HTML of the Toolbar using the block’s standard (built-in) _toHtml method which is responsable for outputting final HTML of the block. getMode is called within list.phtml also. It is used to grab the current mode, either “list” or grid”. getLoadedProductCollection is the public method that allows the list.phtml file to use the product collection and output its details. It is a public interface to the protected _getProductCollection method. Using two methods isn’t necessary for this, but it is in keeping with OOP principals of hiding your processing code from the “public” (code using your objects). That’s basically it! We have a complete module that will successfully ouput best selling products and use the Toolbar.


comments powered by Disqus