0

I know this is a question that has been asked a few times before, however, I have spent most the day trying various solutions (not least from StackExchange) and examples which I've tried to reference below.

The issue I have is that I wish to add a custom button to the Order view within the adminhtml section of Magento (enterprise, 1.14.0.1), that's it! Just add the button! I've created the module triple checked the namespaces, spellings and paths, even used other modules that do achieve this as a base, all to no avail!

So I've rolled a simple example module that should JUST add a button that reloads the order view. It's super simple, 3 files! The problem is the constructor just never seems to be called (I've been adding Mage::log's in there to see).

Can anyone in the know please take a look and help point out if/where I've gone wrong, please?

For the benefit of the tape, the Company name for the module is "Cygnus" and the module name is "Test".

Let's start with the config.xml (/app/code/community/cygnus/test/etc/config.xml)

<?xml version="1.0"?>
<config>
    <modules>
        <Cygnus_Test>
            <version>0.0.1</version>
        </Cygnus_Test>
    </modules>
    <blocks>
        <cygnustest>
            <class>Cygnus_Test_Block</class>
        </cygnustest>
        <adminhtml>
            <rewrite>
                <sales_order_view>Cygnus_Test_Block_Adminhtml_Sales_Order_View</sales_order_view>
            </rewrite>
        </adminhtml>
    </blocks>
</config>

Now, here's the other XML config for completeness (/app/etc/modules/Cygnus_Test.xml)

<?xml version="1.0"?>
<config>
    <modules>
        <Cygnus_Test>
            <active>true</active>
            <codePool>community</codePool>
        </Cygnus_Test>
    </modules>
</config>

And finally the block extension (/app/code/community/cygnus/test/Block/Adminhtml/Sales/Order/View.php)

<?php
class Cygnus_Test_Block_Adminhtml_Sales_Order_View extends Mage_Adminhtml_Block_Sales_Order_View 
{

    public function  __construct() {

        Mage::log("I am the constructor, YAY!!!!",null,'cyg.log');

        //This was to test if the parent constructor makes a difference
        //parent::__construct();

        //create current URL
        $url = $this->getOrder()->getId();
        $url = $this->getUrl('*/sales_order/view', array('order_id'=>$current_order_id));

        //add a button
        $this->_addButton('reload_button', array(
            'label'     => Mage::helper('sales')->__('Reload'),
            'onclick'   => 'setLocation(\'' . $url . '\')',
            'class'     => 'go'
        ));

        //don't forget the parent!
        parent::__construct();

    }

}

So, nothing happens. No log from the constructor. I have tested the _addButton code in another module and this works, likewise, as you can see I've moved the parent constructor around but this makes no difference as the issue appears to be that Magento does not find or recognize my View.php file. It all points to a config.xml issue but I (and my senior developer) can not see the issue.

PS> I have, of course, been developing and testing locally with manual and admin based cache clearance (all caches are off anyway), and done many reloads/login & out of admin resets.

Anyone have anything to suggest? please feel free to copy/paste the code down to test. I stopped short of trying the observer method (in ref 4) instead of focusing on why my rewrite is not functioning.

References (sorry but not enougth rep yet to post 2+ links :( ) :

  1. https://stackoverflow.com/questions/6642599/how-to-add-new-button-to-order-view-in-magento-admin-panel
  2. https://stackoverflow.com/questions/24835742/magento-admin-custom-button-on-view-order
  3. https://magento.stackexchange.com/questions/49709/button-click-not-working-on-sales-order-view-custom-tab-section
  4. Magento Admin Custom Button on View Order
  5. http://www.silvatechsolutions.com/tech-news/custom-magento-admin-order-buttons-fix-on-upgrade/
  6. http://ravichandranjothi.blogspot.co.uk/2013/06/magento-how-to-add-button-to-order-view.html
  7. https://magentomods.wordpress.com/2012/10/04/how-to-add-a-custom-button-to-an-admin-page-magento-ee-1-12-0-2/
  8. http://alanstorm.com/custom_magento_system_configuration

Thanks so much for advise and help in advance!

Danny 'Blatant' cygnus

0

I think you can make use of an observer method instead of using a rewrite. The following code should do the trick:

public function coreBlockAbstractPrepareLayoutBefore(Varien_Event_Observer $observer)
{
    $block = $observer->getBlock();
    if ($block instanceof Mage_Adminhtml_Block_Sales_Order_View) {
            $block->addButton('your_button', array(
                'label'     => 'your_label',
                'onclick'   => 'whatever_should_happen';
        }
    }
}

However if you want to use your module the config.xml is missing a global node. I think that's why your rewrite is not working.

Edit: Your Config.xml sould like:

<?xml version="1.0"?>
<config>
   <modules>
       <Cygnus_Test>
           <version>0.0.1</version>
       </Cygnus_Test>
   </modules>
   <global>
       <blocks>
        ...
  • Hi Michael, thanks I am aware of the observer method which I may have to fall back to. The module above is destined to be folded into a bigger module suite hence why I wanted to keep along the rewrite path (matched prevoius overloads). Can I just ask, you say "your module the config.xml is missing a or node", is this a type-o? what node am I missing here? – cygnus digital Mar 31 '15 at 9:17
  • Hi, I've editet my previous post, so the missing node <global> is inserted at the right place in the sample config.xml. – luemic Mar 31 '15 at 10:29
0

So I'm answering my own question as I eventually persevered with this. It's no surprise but the issue's that got me have been discussed before, but this is a bit of a remix of 2 issues.

Firstly I'd like to thank Michael Lühr for his answer, this is indeed the correct way to implement this using an observer and event, and may be the preferred method within Magento as this answer does not get effected by 'dependencies' as you will read below in the solution. The only reason it's not marked as the answer is becuase in my OP I did specifically say I was looking to solve the rewrite issue, not investigate the observer method ("I stopped short of trying the observer method (in ref 4) instead focusing on why my rewrite is not functioning.").

Now, here's what happened with my specific issue, I was hit by 2 issues :

  • Another (in use) module already rewriting the same sales_order_view
  • The Alphabetical nature of overloading Magento exhibits

In short I identified a module already using the rewrite (I actually referenced the 3rd party module when I wrote mine!), this module for sake of the answer was called "ExtraMod_Print". This module is in use by the client so we have to maintain this modules functionality as we go.

Now due to Magento's Alphabetical module loading nature (as described here : http://magebase.com/magento-tutorials/magento-extension-clashes-winners-and-loosers/) the ExtraMod_Print module was always loaded instead of mine. We can solve this by adding a dependency to my module's /app/etc/Cygnus_Test.xml as described here ( http://codeserious.com/magento-certification-basics-resolving-module-conflicts/ ) and shown in my code below

<?xml version="1.0"?>
<config>
    <modules>
        <Cygnus_Test>
            <active>true</active>
            <codePool>community</codePool>
            <depends>
                <ExtraMod_Print />
            </depends>
        </Cygnus_Test>
    </modules>
</config>

With this minor change, all of a sudden my module kicks in, happy days! But wait, there is a slight issue remaining, doing this knocks out the ExtraMod_Print functionality, effectively substituting mine. We can solve this however, all we need to do is inherit from the dependant class instead of the base Mage_Sales class. This solution is described more thoroughly here ( http: //codeserious.com/magento-certification-basics-resolving-module-conflicts/ ), in my code all I need to do is change the class declaration in /app/code/community/cygnus/test/Block/Adminhtml/Sales/Order/View.php as shown here ( I also tidied up the logging, put the parent constructor in the right place and such) :

<?php
class Cygnus_Test_Block_Sales_Order_View extends *ExtraMod_Print_Block_Adminhtml_Sales_Order_View*
{

    public function __construct() {

        //parent constructor
        parent::__construct();

        //create URL to our custom action
        $url = Mage::helper("adminhtml")->getUrl(
            "Cygnus_Test/order/doSomething",
            array('order_id'=>$this->getOrder()->getId())
        );

        //add the button
        $this->_addButton('cygtest_resubmit', array(
                'label'     => Mage::helper('sales')->__('Do Something'),
                'onclick'   => 'setLocation(\'' . $url . '\')',
                'class'     => 'go'
        ));

    }

}

So there you have it, both modules operating fine with each other, simple once you know how! There's a wealth of 'Magento basics' tutorials out there regarding module conflicts once you know what your looking for!

As I mentioned earlier though, I don't believe the rewrite style of solution is best especially if you plan to distribute your module. Adding dependencies is very much an implementation specific thing, adding a dependency on a module that isn't in the next Magento installation causes the "Dependency required" error message, thus using a rewrite makes your module 'non-portable'.

If you plan to share and distribute your module save yourself some time and refer to Michael Lühr's comments above, otherwise I hope the answer helps someone out there in the future!

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.