2
votes

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?

2
You are missing $block variable initialization: $block = $observer->getEvent()->getData( 'block' ); // this should be the first line of orderPageButton function. It should work after that :)Domen Vrankar
Btw you should change a few things in index.php. 1) Mage::setIsDeveloperMode(true); <- comment if that surrounds this line 2) ini_set('display_errors', 1); <- uncomment this line; These two cnages will enable logs in var/log/{system, exception}.log; it's easyer to develop that way and there won't be so many bugs in production - it's surprising how many people develop magento stores without that and then when I start working on a project and enable those logs I'm greeted with allot of errors in logs that should be fixed before productionDomen Vrankar
One more thing... printOrder <- Module name should start with an upper case CaitlinHavener_PrintOrder_... It's usualy that way and you can get into some serious trouble with upper case to underscore and back automatic magento conversions on for e.g. Linux OS because of case sensitive file system. In my example I intentionaly wrote correct upper/lower cased words. I don't know if that's a problem in your case since I copied your code to my module and renamed things but just an advice in case you run into such trouble :)Domen Vrankar
Hey thank you for your help! I initialized the variable but I'm still not getting a test print button on the detail order page, nor am I seeing any errors in the log...CaitlinHavener
I wrote the code in my answer below :) Like I warned you the problem was with your module name starting with lower case.Domen Vrankar

2 Answers

2
votes

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.

0
votes

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')
        { 
          ....