3

I currently have 4 widgets on my front page that display 4 products each.

At the moment it uses either featured products, special producs or hot products to decide which products to populate the widget with.

I select the product types using the categories.

I'm looking for a way to randomize the products from the specific category.

2

The are two obvious approaches to achieve this. You can do it either within your theme or create a module that will utilise this functionality.

Within the theme you can just create a template (let's say in catalog/product/randomize.phtml) and put the following code in there:

$_category = Mage::getModel('catalog/category')->load($this->getCategoryId());
$productVisibility = Mage::getSingleton('catalog/product_visibility');
$_productCollection = Mage::getResourceModel('reports/product_collection')
                   ->addAttributeToSelect('*')
                   ->addStoreFilter()
                   ->addCategoryFilter($_category)
                   ->setVisibility($productVisibility->getVisibleInCatalogIds());
$_productCollection->getSelect()->order(new Zend_Db_Expr('RAND()'));                  
$_productCollection->setPage(1, 4);

and then in your CMS page you put something like this:

{{block type="core/template" name="whatever" template="catalog/product/randomize.phtml" category_id="YOUR_CATEGORY_ID"}}

The second approach is to create your module with just one block, extend Mage_Catalog_Block_Product_List and then implement _getProductCollection method in almost the same manner as in first approach:

protected function _getProductCollection()
{
    if (is_null($this->_productCollection)) {
        $_category = Mage::getModel('catalog/category')->load($this->getCategoryId());
        $productVisibility = Mage::getSingleton('catalog/product_visibility');
        $this->_productCollection = Mage::getResourceModel('reports/product_collection');
        $this->_productCollection->addAttributeToSelect('*')
            ->addStoreFilter()
            ->addCategoryFilter($_category)
            ->setVisibility($productVisibility->getVisibleInCatalogIds());
        $this->_productCollection->getSelect()->order(new Zend_Db_Expr('RAND()'));                  
        $this->_productCollection->setPage(1, 4);
    }

    return parent::_getProductCollection();
}

Then in your CMS page you can call your block like this:

{{block type="module_name/block_name" name="whatever" template="catalog/product/list.phtml" category_id="YOUR_CATEGORY_ID"}}
3
  • Thanks very much for this solution. I am currently using a custom template. Which option would you use?
    – Wessel
    Aug 4 '13 at 14:01
  • If you don't have much experience with Magento I suggest 1st approach.
    – user487772
    Aug 4 '13 at 14:17
  • He-he, with the code I provided you are only getting a collection object. Then you have to loop through it and output products in the desired markup. Take a look at catalog/product/list.phtml template for example of looping through products collection.
    – user487772
    Aug 4 '13 at 17:44
0

ORDER BY RAND() is unperformant because it results in a resource intensive temp table copy. It has to load all results into a temporary table, assign a random number to each row and then sort without any index. Instead we retrieve all ids (this is faster and the amount of data is managable even for large catalogs), pick some randomly and retrieve these rows directly.

Here is how you create the product collection that way:

$_category = Mage::getModel('catalog/category')->load($this->getCategoryId());
$_productCollection = Mage::getResourceModel('reports/product_collection')
                   ->addStoreFilter()
                   ->addCategoryFilter($_category)
                   ->setVisibility(Mage::getSingleton('catalog/product_visibility')->getVisibleInCatalogIds());

// You can add additional filters here, if you want

$numberOfItems = 4;
$candidateIds = $productCollection->getAllIds();
$choosenIds = [];
$maxKey = count($candidateIds)-1;
while (count($choosenIds) < $numberOfItems)) {
  $randomKey = mt_rand(0, $maxKey);
  $choosenIds[$randomKey] = $candidateIds[$randomKey];
}
$productCollection->addIdFilter($choosenIds);

// Now we specify, which data to load. The following is the standard for product lists:
$productCollection
    ->addMinimalPrice()
    ->addFinalPrice()
    ->addTaxPercents()
    ->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
    ->addUrlRewrite();

You can read about random product performance in detail in my blog: http://www.schmengler-se.de/en/2015/09/show-random-products-in-magento-you-are-doing-it-wrong/

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.