2

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

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

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

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

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

首先,我尝试在正确的结构中将文件复制到 app/code/local 文件夹 - 但它不起作用(我已经使用 Varient.php 用于本地测试系统和 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>

代码/本地/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 ...
    }
}
?>

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

任何帮助真的很棒!

问候,马蒂亚斯

4

2 回答 2

6

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

Mage_Adminhtml_Catalog_ProductController->_initProductSave()

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


“首先,我试图将文件复制到应用程序/代码/本地文件夹中,在正确的结构中......”

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

参考。Mage_Core_Controller_Varien_Router_Standard->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>

前面的配置片段做了两件事:<frontName />节点添加一个模块路由,并且<module />节点 - 连同注册Mage_Adminhtml <codePool />值(“核心”) - 建立一个目录,在该目录中可以找到动作控制器类,在本例中为/[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>

可以看出,上面的配置只是简单的admin/routers/adminhtml/args/在配置XML编译时添加或添加到节点。这是如何解释和用于请求匹配的,与控制器匹配的“正常”过程非常相似。在上面的示例中,该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

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

于 2012-07-01T14:53:02.657 回答
4

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

改变:

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

到:

<MyOne_MyExtension before="Mage_Adminhtml">MyOne_MyExtension</MyOne_MyExtension>
于 2012-07-01T13:27:12.370 回答