【问题标题】:Magento: Overload Adminhtml/Productcontroller’s saveAction method won’t work …?Magento:重载 Adminhtml/Productcontroller 的 saveAction 方法不起作用……?
【发布时间】:2012-07-02 03:37:57
【问题描述】:

我想从 core/Mage/Adminhtml/controllers/Catalog/ProductController.php 重载 saveAction 方法,但它不起作用 - 我现在已经搜索并尝试了整整一天:(

背景:我想在保存产品之前更改自定义属性的值。我发现 _initProductSave 设置了属性,我认为,在 init_ProductSave 之后更改它们将是一个好点(如果有人知道更好的地方,请告诉我)...

任何人都可以帮助我... :)

Magento 版本: 社区版版本 1.7.0.1 没有扩展,没有安装主题,我只是安装这个版本完全空白......

版本 1:通过复制到本地/Mage 文件夹覆盖控制器

首先,我尝试在正确的结构中将文件复制到 app/code/local 文件夹 - 但它不起作用(我已经使用 Varient.php for local testsystem 和 stores.php用于纠正价格错误 - 两者都有效......)

版本 2:用扩展覆盖控制器

我的扩展如下所示:

文件结构:

code/local/MyOne/MyExtension/controllers/Catalog/ProductController.php 
code/local/MyOne/MyExtension/etc/config.xml 
etc/modules/MyOne_MyExtension.xml

文件如下所示: MyOne_MyExtension.xml:

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

code/local/MyOne/MyExtension/etc/config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <MyOne_MyExtension>
            <version>1.0.0</version>
        </MyOne_MyExtension>
    </modules>
    <admin>
        <routers>
            <adminhtml>
                <args>
                    <modules>
                        <MyOne_MyExtension before="Mage_Adminhtml">MyOne_MyExtension_Catalog_ProductController</MyOne_MyExtension>
                    </modules>
                </args>
            </adminhtml>
        </routers>
    </admin>
</config>

最后一个,code/local/MyOne/MyExtension/controllers/Catalog/ProductController.php:

<?php
require_once 'Mage/Adminhtml/controllers/Catalog/ProductController.php';

class MyOne_MyExtension_Catalog_ProductController extends Mage_Adminhtml_Catalog_ProductController
{
    public function saveAction()
    {
        // do my stuff
        die('reached method');
        // after pressing on save, there should no be a white screen ...
    }
}
?>

我已经用谷歌搜索并阅读了这么多,我没有看到错误...

任何帮助都会很棒!!!

您好, 马蒂亚斯

【问题讨论】:

    标签: magento controller product overwrite adminhtml


    【解决方案1】:

    由于 Magento 只需要知道模块名称即可找到匹配控制器的路径,

    变化:

    <MyOne_MyExtension before="Mage_Adminhtml">MyOne_MyExtension_Catalog_ProductController</MyOne_MyExtension>
    

    到:

    <MyOne_MyExtension before="Mage_Adminhtml">MyOne_MyExtension</MyOne_MyExtension>
    

    【讨论】:

    • 经过测试 - 这个解决方案有效......我做错了什么的完整解释如下所述。非常感谢您的帮助!
    • 本例代码正确,但解释不正确。
    • 这是对的,根据代码,它可以工作,根据解释,你的答案是正确的 :) [对不起,丹尼尔 ;)]
    【解决方案2】:

    注意:鉴于目标方法...

    Mage_Adminhtml_Catalog_ProductController->_initProductSave()
    

    ...最好的做法是排除使用 adminhtml 范围的观察者来消费 catalog_product_save_before 事件。


    “首先我尝试将文件复制到 app/code/local 文件夹中,在正确的结构中......”

    这不是一种不常见的开发人员方法,但它永远不会奏效。 Magento 动作控制器类由自动加载器加载。它们由它们的真实文件系统路径显式加载。因此,所谓的“include path hack”并不适用。

    参考。 Mage_Core_Controller_Varien_Router_Standard-&gt;getControllerFileName().

    您的第二种方法 - 使用适当的自定义扩展执行重写 - 是正确的方法。您只需要了解 Magento 如何查找动作控制器目录并将动作控制器类与请求 URL 匹配。

    在其 config.xml 中,Mage_Adminhtml 模块配置了 Admin 路由器,该路由器负责匹配所有与 admin 相关的请求:

    <admin>
        <routers>
            <adminhtml>
                <use>admin</use>
                <args>
                    <module>Mage_Adminhtml</module>
                    <frontName>admin</frontName>
                </args>
            </adminhtml>
        </routers>
    </admin>
    

    前面的配置sn-p做了两件事:&lt;frontName /&gt;节点添加了一个模块路由,&lt;module /&gt;节点——连同注册的Mage_Adminhtml&lt;codePool /&gt;值(“core”)——建立一个目录可以在其中找到动作控制器类,在本例中为/[basepath]/app/code/core/Mage/Adminhtml/controllers/

    模块操作控制器通过将其他候选匹配目录添加到现有模块路由来重写工作。这都是从配置中解析出来的:

    <admin>
        <routers>
            <adminhtml>
                <args>
                    <modules>
                        <MyOne_MyExtension before="Mage_Adminhtml">MyOne_MyExtension_Catalog_ProductController</MyOne_MyExtension>
                    </modules>
                </args>
            </adminhtml>
        </routers>
    </admin>
    

    可以看出,上面的配置只是简单的在配置XML编译时添加或添加到admin/routers/adminhtml/args/节点。这是如何解释和用于请求匹配的,与控制器匹配的“正常”过程非常相似。在上面的示例中,MyOne_MyExtension 模块有效地将目录添加到 Adminhtml 模块的目录列表中。假设在localcodePool中,上面的例子指向目录

    /[basepath]/app/code/local/MyOne/MyExtension/controllers/Catalog/ProductController/
    

    如果有一个动作控制器类,这将起作用

    /[basepath]/app/code/local/MyOne/MyExtension/controllers/Catalog/ProductController/Catalog/ProductController.php
    

    在一个名为

    的类中包含一个_initProductSave()方法
    MyOne_MyExtension_Catalog_ProductController_Catalog_ProductController
    

    希望这种解释足以说明基于配置的控制器重写工作在目录级别,而不是通过指定特定的类(这是块、帮助程序和模型重写的工作方式)。因为此配置添加了一个目录,所以它不必导致重写,因为它可以用于简单地为给定模块添加新操作。最终,只有当其他控制器类在“原始”控制器类之前匹配时,才会发生动作控制器重写。

    【讨论】:

    • 这个也是正确的... :) 非常感谢!!! (拯救了我的一天;))@benmarks:丹尼尔的解决方案也是您很好解释的结果,对吧?
    • 当然我读到了观察者的最佳实践,我明天也会测试那个:)
    猜你喜欢
    • 2013-02-03
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 2015-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多