Netismine

Tips & tricks

Simulate / fake a module

I found that I needed to trick Magento into thinking it’s using one of it’s own core modules instead of a custom one, when I needed to retain certain URL-s instead of using my own module’s controller. So, to hack Magento so that it returns it’s own core module with

$this->getUrl('*/*/*');
select all

you shoud utilize this code on the controller level ideally:

$this->getRequest()->setRouteName('catalog');
select all

Where “catalog” is the core module you want to fake.

Only 3 products on Wishlist page

I just finished debugging an issue where wishlist page in my account would only display 3 products.

Here’s how it goes.

Wishlist collection is being cached during runtime. When the parser reaches sidebar, Mage_Wishlist_Block_Customer_Sidebar class will limit this collection to only three results. Which is fine in default magento, since the wishlist sidebar is parsed only after the content part ends.

BUT, if you have something like this in your header:

<reference>
    <block type="wishlist/customer_sidebar" as="wishlist" before="cart_sidebar" template="wishlist/sidebar.phtml"/>
</reference>
select all

Translated, if you call the wishlist sidebar block in the header, header being parsed before the content area, collection will be limited to three products, hence causing the bug list in the content area to show only three products.

So, if something similar happens to you, you know where to look.

Remove head block from page

When developing a Magento custom module that should use an AJAX response of a page that’s bigger then a few blocks, you’d probably like to have all those script files removed from head. Now, you can either unset head block entirely, or just remove the script files. What you need to do is to create an observer on

controller_action_layout_render_before
select all

event, and create this observer function:

public function removeHead()
{
	if (Mage::app()->getRequest()->getModuleName() == "lazyload") { //put your module/controller/action name here so you don't remove head for every single page
		$layout = Mage::getSingleton('core/layout');
		$layout->unsetBlock('head');
 
		/* second level of destruction - because this block has two lives .. like a final queen in an arcade */
 
		$head = $layout->getBlock('root')->getChild('head');
		if (is_object($head)) {
			$head->setData('items',array());
			$layout->getBlock('root')->setChild('head',$head);
		}
 
		/* third level of destruction - if the bitch respawns */
		//$layout->getBlock('root')->setChild('head', new Mage_Core_Block_Template);
	}
}
select all

take a look at what it does, might give you some more ideas on how to battle the pest.

Layered navigation not showing up on search results

If you’re having this error in Magento, that’s probably because number of your search results exceeded 2000. Magento has a setting in admin that disables layered navigation if there are more than 2000 search results. You can remove this threshold here:
System -> Configuration -> Catalog -> Catalog Search -> Apply Layered Navigation if Search Results are Less Than

But beware that this might impact your search result page performance. I did some minor benchmarking and it turned out it took my server about 300-400ms more to display search page with 3500 results if this limit is removed and layered navigation displayed.

Get Bestsellers collection

It’s actually pretty easy to get up to date list of bestselling products from your database. It all fits into just one sql query:

SELECT `e`.*, `bs`.* FROM `catalog_product_entity` AS `e` INNER JOIN (SELECT `sales_flat_order_item`.`product_id`, SUM(`qty_ordered`) AS `count` FROM `sales_flat_order_item` GROUP BY `product_id`) AS `bs` ON bs.product_id = e.entity_id ORDER BY `bs`.`count` DESC
select all

In Magento’s language, that looks like this:

$select = Mage::getSingleton('core/resource')->getConnection('core_read')
        	->select()
	        ->from('sales_flat_order_item', array('product_id', 'count' => 'SUM(`qty_ordered`)'))
        	->group('product_id');
 
$collection = Mage::getModel('catalog/product')
	->getCollection();
 
$collection->getSelect()
	->join( array ('bs' => $select),
			'bs.product_id = e.entity_id')
	->order('bs.count DESC');
select all

So, it suddenly became suprisingly easy to make that bestsellers custom module? :) This is just for demonstration purposes, so make sure you replace the statics such as ‘sales_flat_order_item’ with appropriate Magento’s API calls.

Archive: Tips & Tricks