I have created a custom Magento module which extends the core sales order functionality with some custom user input. After an order has been placed I would like to display this data in a custom tab on the order detail page of the admin area. I have managed to get the new tab displaying in the tab list however when I click on the tab it gives me a 404.
Here's my code:
app/code/local/Zac/Attack/etc/config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<Zac_Attack>
<version>0.1.0</version>
</Zac_Attack>
</modules>
<admin>
<routers>
<adminhtml>
<args>
<modules>
<!-- Override Adminhtml module here. -->
<Zac_Attack_Adminhtml before="Mage_Adminhtml">Zac_Attack_Adminhtml</Zac_Attack_Adminhtml>
</modules>
</args>
</adminhtml>
</routers>
</admin>
<adminhtml>
<layout>
<updates>
<attack>
<file>attack.xml</file>
</attack>
</updates>
</layout>
</adminhtml>
<global>
<blocks>
<attack>
<class>Zac_Attack_Block</class>
</attack>
</blocks>
<!-- models, resources, etc -->
</global>
</config>
app/code/local/Zac/Attack/Block/Adminhtml/Sales/Order/View/Tab/Attack.php:
<?php
class Zac_Attack_Block_Adminhtml_Sales_Order_View_Tab_Design extends Mage_Adminhtml_Block_Template
implements Mage_Adminhtml_Block_Widget_Tab_Interface
{
protected function _construct()
{
parent::_construct();
$this->setTemplate( 'attack/sales/order/view/tab/attack.phtml' );
}
public function getTabLabel()
{
return $this->__( 'Attack' );
}
public function getTabTitle()
{
return $this->__( 'Attack' );
}
public function getTabClass()
{
return '';
}
public function getClass()
{
return $this->getTabClass();
}
public function getTabUrl()
{
// Here the url gets rewritten to my custom name, throws 404 when called...
// The url takes the form:
// http://mydomain.com/admin/sales_order/attack/order_id/1/key/65cbb0c2956dd9413570a2ec8761bef5/
return $this->getUrl('*/*/attack', array('_current' => true));
}
public function canShowTab()
{
return true;
}
public function isHidden()
{
return false;
}
public function getOrder()
{
return Mage::registry( 'current_order' );
}
}
app/code/local/Zac/Attack/controllers/Adminhtml/Sales/OrderController.php:
<?php
require_once "Mage/Adminhtml/controllers/Sales/OrderController.php";
class Zac_Attack_Adminhtml_Sales_OrderController extends Mage_Adminhtml_Sales_OrderController
{
public function viewAction()
{
// This doesn't get called when viewing the default order detail page.
// I should see the <h1> output as the only content on the page but I don't.
die( '<h1>viewAction()</h1>' );
}
public function attackAction()
{
// This should be called when the url has the pattern '*/*/attack' (as it does
// when displaying my custom tab) however clicking this tab gives a 404.
die('<h1>attackAction()</h1>');
}
}
app/design/adminhtml/default/default/layout/attack.xml
<?xml version="1.0" encoding="UTF-8"?>
<layout>
<adminhtml_sales_order_view>
<reference name="sales_order_tabs">
<action method="addTab">
<name>order_design_details</name>
<block>attack/adminhtml_sales_order_view_tab_design</block>
</action>
</reference>
</adminhtml_sales_order_view>
</layout>
What appears to be failing is the controller override. Neither the overriden method "viewAction()" nor the custom action "attackAction()" get called. I can tell that the config is being picked up because when I print "Mage::getConfig()->getNode('admin/routers/adminhtml')" I can see the following output:
Mage_Core_Model_Config_Element Object
(
[args] => Mage_Core_Model_Config_Element Object
(
[module] => Mage_Adminhtml
[modules] => Mage_Core_Model_Config_Element Object
(
[Mage_Index] => Mage_Index_Adminhtml
[Mage_Paygate] => Mage_Paygate_Adminhtml
[Mage_Paypal] => Mage_Paypal_Adminhtml
[widget] => Mage_Widget_Adminhtml
[Mage_GoogleOptimizer] => Mage_GoogleOptimizer_Adminhtml
[Mage_GoogleBase] => Mage_GoogleBase_Adminhtml
[Mage_Authorizenet] => Mage_Authorizenet_Adminhtml
[Mage_Bundle] => Mage_Bundle_Adminhtml
[Mage_Centinel] => Mage_Centinel_Adminhtml
[Mage_Compiler] => Mage_Compiler_Adminhtml
[connect] => Mage_Connect_Adminhtml
[Mage_Downloadable] => Mage_Downloadable_Adminhtml
[importexport] => Mage_ImportExport_Adminhtml
[Mage_PageCache] => Mage_PageCache_Adminhtml
[xmlconnect] => Mage_XmlConnect_Adminhtml
[EM_DeleteOrder_Adminhtml] => EM_DeleteOrder_Adminhtml
[find_feed] => Find_Feed_Adminhtml
[moneybookers] => Phoenix_Moneybookers
[Zac_Attack_Adminhtml] => Zac_Attack_Adminhtml
)
[frontName] => admin
)
[use] => admin
)
So, my first question is: Am I following the correct approach for adding a custom tab to the page?
If I am not following the correct approach can you please advise me what the correct approach is or provide a link which clearly outlines the whole approach (there are too many answer fragments when searching for Magento information, not enough whole answers).
If I am following the correct approach, why is my controller not overriding?
Well, I hope that I've provided enough detail to make the problem clear. If not, feel free to post follow up questions in the comments and I'll be happy to elaborate - if I know how.
Thanks in advance for any help offered.
Cheers, Zac
P.S. I noticed that there is another module in the community section overriding the same controller - however that override doesn't appear to be taking effect either. Regardless, I have completely removed the 3rd party module for the purposes of debugging to ensure that there is no interference.