Question

I am trying to add a print order button on the main order detail page on the magento admin. The client's old magento had a print button for the order itself (paid or unpaid, not invoice). See what it used to look like:

orderbar

I've enabled template hints in on the back end and the template file does not contain that button. I've been through several core files... The html looks like the following. How would I turn that into a php button that is applicable to the currently viewed order?

<button  id="id_d808fbd2d533d4e7b8e4a3fcd6274251" title="Back" type="button" class="scalable back" onclick="setLocation('http://test.animalnecessity.com/index.php/admin/sales_order/index/order_id/15852/key/28a65aa166da1664c65971decf3e472c/')" style="">

Could I implement this? Magento - Add Button to Sales Order View Page (Observer/Event) and if so where would I put this code?

I have it set up with the typical module structure as described here: http://alanstorm.com/magento_config. My config.xml in the etc folder has the following

<config>    
    <modules>
        <CaitlinHavener_printOrder>
            <version>0.1.0</version>
        </CaitlinHavener_printOrder>
    </modules>
    <global>
        <events>
            <core_block_abstract_to_html_before>
                <observers>
                <CaitlinHavener_printOrder>
                    <class>CaitlinHavener_printOrder_Model_Observer</class>
                    <method>orderPageButton</method>
                    <type>model</type>
                </CaitlinHavener_printOrder>
                </observers>
            </core_block_abstract_to_html_before>
        </events>
    </global>
</config>

My CaitlinHavener_printOrder.xml the following

<config>    
    <modules>
        <CaitlinHavener_printOrder>
            <active>true</active>
            <codePool>local</codePool>
        </CaitlinHavener_printOrder>
    </modules>
</config>

and Observer.php

<?php
// Order View Page button    
class CaitlinHavener_printOrder_Model_Observer
{
    public function orderPageButton( Varien_Event_Observer $observer )
    {
        if(get_class($block) =='Mage_Adminhtml_Block_Sales_Order_View'
            && $block->getRequest()->getControllerName() == 'sales_order')
        {
            $block->addButton('test_print', array(
                'label'     => 'Test',
                'onclick'   => 'setLocation(\'' . $block->getUrl('html/sales_order/print') . '\')',
                'class'     => 'go'
            ));
        }
    }
}
?>

This is still not working. Any ideas?

Was it helpful?

Solution

The buttons are created in Mage_Adminhtml_Block_Sales_Order_View::__construct with $this->addButton function calls.

As for the events you could use one of them but I can't recall from the top of my head which one (if any) would be apropriate to call.

To list all the events that get triggered you could add logging into Mage::dispatchEvent function with Mage::log( $name );

With that name you could declare a listener in config.xml (under config/global/events tag path):

  <name_that_was_printed_by_the_above_function>
    <observers>
      <YourModuleNamespace_YourModuleName>
        <class>moduleName/observer</class>
        <method>functionName</method>
        <type>model</type>
      </YourModuleNamespace_YourModuleName>
    </observers>
  </name_that_was_printed_by_the_above_function>

and then create a module class Observer.php

class Namespace_ModuleName_Model_Observer
{
    public function functionName( Varien_Event_Observer $observer )
    {
        $block = $observer->getEvent()->getData( 'data_object' ); // this line may vary

        $block->addButton( ...stuff here... // take for reference the answer from the question you linked to
        return $this;
    }
}

But like I said it's possible that none of the observers will suit your needs and you'll have to find another more intrusive solution...

Edit

You'll probbably have to use core_block_abstract_to_html_before and have an if statement to check if it's the right block... The downside is that it gives a call overhead and an if statement overhead for every block so I'm not certain if it's the best solution but it's certainly the least intrusive so I'd probably use it (the 'data_object' should be changed to 'block' in case of this event - event is triggered in Mage_Core_Block_Abstract::toHtml the dispatchEvent line).

Edit

After your question update I've tested your module and like I have warned in the comments the problem is the name of your module - lower case.

app/etc/modules/CaitlinHavener_PrintOrder.xml

<?xml version="1.0" encoding="UTF-8"?>
<config>    
    <modules>
        <CaitlinHavener_PrintOrder>
            <active>true</active>
            <codePool>local</codePool>
        </CaitlinHavener_PrintOrder>
    </modules>
</config>

app/code/local/CaitlinHavener/PrintOrder/etc/config.xml

<?xml version="1.0" encoding="UTF-8"?>
<config>    
    <modules>
        <CaitlinHavener_PrintOrder>
            <version>0.1.0</version>
        </CaitlinHavener_PrintOrder>
    </modules>
    <global>
        <events>
            <core_block_abstract_to_html_before>
                <observers>
                <CaitlinHavener_PrintOrder>
                    <class>CaitlinHavener_PrintOrder_Model_Observer</class>
                    <method>orderPageButton</method>
                    <type>model</type>
                </CaitlinHavener_PrintOrder>
                </observers>
            </core_block_abstract_to_html_before>
        </events>
    </global>
</config>

local/CaitlinHavener/PrintOrder/Model/Observer.php

<?php
// Order View Page button    
class CaitlinHavener_PrintOrder_Model_Observer
{
    public function orderPageButton( Varien_Event_Observer $observer )
    {
      $block = $observer->getEvent()->getData( 'block' );

        if(get_class($block) =='Mage_Adminhtml_Block_Sales_Order_View'
            && $block->getRequest()->getControllerName() == 'sales_order')
        {
            $block->addButton('test_print', array(
                'label'     => 'Test',
                'onclick'   => 'setLocation(\'' . $block->getUrl('html/sales_order/print') . '\')',
                'class'     => 'go'
            ));
        }
    }
}
?>

Be carefull that you correctly name your files (watch for upper case characters) and copy the code and it should work.

OTHER TIPS

A slight improvement to @Domen Vrankar

adminhtml_block_html_before will only dispatch in the admin area while core_block_abstract_to_html_before will dispatch in both admin and front-end

    <events>
        <adminhtml_block_html_before>
            <observers>
            <CaitlinHavener_PrintOrder>
                <class>CaitlinHavener_PrintOrder_Model_Observer</class>
                <method>orderPageButton</method>
                <type>model</type>
            </CaitlinHavener_PrintOrder>
            </observers>
        </adminhtml_block_html_before>
    </events>

If another module rewrite Mage_Adminhtml_Block_Sales_Order_View then get_class($block) will return the new block class eg MagePal_Guest2Customer_Block_Adminhtml_Sales_Order_View therefore your button will no longer display

<?php
// Order View Page button    
class CaitlinHavener_PrintOrder_Model_Observer
{
    public function orderPageButton( Varien_Event_Observer $observer )
    {
      $block = $observer->getEvent()->getData( 'block' );

        if($block->getId() == 'sales_order_view' && $block->getRequest()->getControllerName() == 'sales_order')
        { 
          ....
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top