如何在Magento管理面板中的订单视图中添加新按钮?

24

如何在订单查看页面附近的“返回”和“编辑”按钮旁添加自定义按钮?

4个回答

41

不要使用核心代码的黑客或重写,只需使用观察者将按钮添加到订单中:

<adminhtml>
    <events>
        <adminhtml_widget_container_html_before>
            <observers>
                <your_module>
                    <class>your_module/observer</class>
                    <type>singleton</type>
                    <method>adminhtmlWidgetContainerHtmlBefore</method>
                </your_module>
            </observers>
        </adminhtml_widget_container_html_before>
    </events>
</adminhtml>

那么只需要在观察者中检查块的类型是否与订单视图匹配:

public function adminhtmlWidgetContainerHtmlBefore($event)
{
    $block = $event->getBlock();

    if ($block instanceof Mage_Adminhtml_Block_Sales_Order_View) {
        $message = Mage::helper('your_module')->__('Are you sure you want to do this?');
        $block->addButton('do_something_crazy', array(
            'label'     => Mage::helper('your_module')->__('Export Order'),
            'onclick'   => "confirmSetLocation('{$message}', '{$block->getUrl('*/yourmodule/crazy')}')",
            'class'     => 'go'
        ));
    }
}

"getUrl" 函数将自动将当前订单 ID 添加到控制器调用中。


1
无需重写类,也不需要更改核心文件——这是一个绝妙的解决方案,我可以确认它至少在1.8版本中有效。 - simonthesorcerer
2
这是一个更好的答案。需要子类化来覆盖 Magento 默认类的答案会导致很多扩展冲突和升级不兼容性问题。如果 Magento 使用观察者方法,通常最好采用该方法。 - Phil M

23

config.xml:

<global>
    <blocks>
         <adminhtml>
            <rewrite>
                <sales_order_view>Namespace_Module_Block_Adminhtml_Sales_Order_View</sales_order_view>
            </rewrite>
        </adminhtml>
    </blocks>
 </global>

名称空间/模块/块/Adminhtml/Sales/Order/View.php:

class Namespace_Module_Block_Adminhtml_Sales_Order_View extends Mage_Adminhtml_Block_Sales_Order_View {
    public function  __construct() {

        parent::__construct();

        $this->_addButton('button_id', array(
            'label'     => Mage::helper('xxx')->__('Some action'),
            'onclick'   => 'jsfunction(this.id)',
            'class'     => 'go'
        ), 0, 100, 'header', 'header');
    }
}

3
“onclick” 方法的一个示例是“confirmSetLocation('{$message}', '{$this->getOkToShipUrl()}')”。 - Jonathan Day
在你的自定义__construct()函数中,需要调用parent::__construct();,否则会出现“无效块类型”异常。 - James
我在实现这个时遇到了一个错误。@james,你所说的parent::__construct是什么意思? - Tom
刚刚明白了,对于其他人,我已经在下面添加了答案。 - Tom
4
请使用观察者模式,而不是将重写添加到如此重要的核心类中。使用这种解决方案可能会导致其他扩展出现问题,而且不必要通过重写来实现这一目的! - Matthias Kleine

2

关于上面有关parent::__constructor的评论,这是对我有效的解决方法:

class Name_Module_Block_Adminhtml_Sales_Order_View extends Mage_Adminhtml_Block_Sales_Order_View {

    public function  __construct() {
        $this->_addButton('testbutton', array(
            'label'     => Mage::helper('Sales')->__('Toms Button'),
            'onclick'   => 'jsfunction(this.id)',
            'class'     => 'go'
        ), 0, 100, 'header', 'header');

        parent::__construct();

    }
}

在函数开头,你应该像这样做:$return = parent::__construct(); 然后执行你的操作,最后返回 $return;。 - Gabriel Queiroz Silva
1
@GabrielQueirozSilva 构造函数没有返回值。这是一个正确的答案。 - Matthias Kleine
@MatthiasKleine 抱歉,我没有注意到这是一个构造函数。 - Gabriel Queiroz Silva

-2
如果你想快速而不拘泥于规范(即编辑核心文件),请打开app/code/core/Mage/Adminhtml/Block/Sales/Order/View.php并添加类似以下的内容:
    $this->_addButton('order_reorder', array(
        'label'     => Mage::helper('sales')->__('Print Labels'),
        'onclick'   => 'window.open(\'/printouts/' . $this->getOrder()->getRealOrderId() . '.pdf\')',
    ));

您可以将其放置在此块之前:

    if ($this->_isAllowedAction('emails') && !$order->isCanceled()) {
        $message = Mage::helper('sales')->__('Are you sure you want to send order email to customer?');
        $this->addButton('send_notification', array(
            'label'     => Mage::helper('sales')->__('Send Email'),
            'onclick'   => "confirmSetLocation('{$message}', '{$this->getEmailUrl()}')",
        ));
    }

如果您选择接受挑战,您需要在本地创建一个覆盖核心文件的文件,并将其发布在此处!


8
最差的回答 - 在任何情况下都不要修改核心文件,永远不要这样做。简单易懂。不要采用快速而肮脏的方式 - 保持代码整洁! - Matthias Kleine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接