This translates into modifying the Mage_Adminhtml_Block_Sales_Order_Grid
class. So if we do a little bit of OOP-ing over here, this just means that we have to override this class and add our own.
Step-1: Creating a module
1. Creating your own folder directory under local. I used local/RLTSquare/MyModule
.
2. Registering your module with magento. This is a simple matter of creating an RLTSquare_MyModule.xml
file under etc/modules
, with the following text:
<config> <modules> <RLTSquare_MyModule> <active>true</active> <codePool>local</codePool> </RLTSquare_MyModule> </modules> </config>
3. Create a config.xml
file under local/RLTSquare/MyModule/etc
, with the following text in it:
<config> <modules> <RLTSquare_MyModule> <version>0.1.0</version> </RLTSquare_MyModule> </modules> </config>
Step-2: Overriding the class
1. Add a node in our config.xml
file (just under the root ‘config’ node) that we created above:
<global> <blocks> <adminhtml> <rewrite> <sales_order_grid>RLTSquare_MyModule_Block_Sales_Order_Grid</sales_order_grid> </rewrite> <adminhtml> <blocks> <global>
2. Create a file named Grid.php
under local/RLTSquare/MyModule/Block/Sales/Order
. I will skip the reasoning behind these particular names and directory structures, though magento veterans will recognize the order in this (apparent) chaos.
3.Finally, let’s bring our attention to the Grid.php
file. This will contain our overridden class.
class RLTSquare_MyModule_Block_Sales_Order_Grid extends Mage_Adminhtml_Block_Sales_Order_Grid { // In this function, we add the extra column that we want protected function _prepareColumns() { parent::_prepareColumns(); //The new column will be added in the second place $this->addColumnAfter('column_name', array( 'header'=> Mage::helper('sales')->__('Grid Header'), 'width' => '80px', 'type' => 'text', 'index' => 'columns_name', ), 'real_order_id'); $this->sortColumnsByOrder(); return this; } protected function _prepareCollection() { //Adding code to populate the column. Here, we are assuming that the new //column is in the 'order' table $collection = Mage::getResourceModel($this->_getCollectionClass()); $collection->join(array('rTable' => 'sales/order'), 'main_table.entity_id=rTable.entity_id', array(self::OLD_ORDER_ID=>self::OLD_ORDER_ID), null,'left'); $this->setCollection($collection); return parent::_prepareCollection(); } }
And this is where the trouble will begin.
The Problem with the Solution
You see, the problem is that in the last line of _prepareCollection
, when you call the parent class function to in the end to let it do what it wants with the $collection
variable, it completely overwrites it, thus rendering our extra lines of code irrelevant. A little bit of debugging will show that our code in this function, despite being run properly, is absolutely useless when the variable is reassigned in the parent class.
What to do now? A little bit of googling led me here, to this great blog piece by the people at Inchoo. The solution described here works perfectly, with one very nagging issue: Instead of overriding the class that actually needs to be overridden, they override its parent and then copy all the relevant code into their own custom class, before adding their own. This seems horribly un-OOP-ish and I can’t come to terms with this. Not to mention the fact that if the original code changes due to a magento upgrade, our overridden file would have to be coded again.
So, is there a better way? The way I chose to do it was that instead of calling the parent class function at the end, I called the grandparent class function by the following line of code:
call_user_func(array(get_parent_class(get_parent_class($this)), '_prepareCollection'));
This way, my new class gets to have only the minimum amount of code that it needs, and the problematic piece of code (which I do not need) is bypassed. I think this is much more elegant solution.
Anyone have any better ideas? Is calling a grandparent function like this not a good idea? Do comment!