php - 扩展Magento的核心类时,我需要更改哪种XML结构才能使更改生效?

标签 php xml magento

我正在使用一个Magento1.3(社区版)安装,我正在尝试扩展其中一个核心类的功能。我直接在开发服务器上更改了核心文件,并在那里实现了功能。现在,following Alan Storm's advice,我将把核心文件还原到stock,并在/app/code/local树中实现我的更改。我一直在阅读Alan Storm的页面和a guide from Josh Pratt,但我不太明白如何将这些例子应用到我的案例中。
问题的核心是-为了扩展/monkey补丁核心类,我需要实现多少完整的magento模块的框架?
我需要创建自己的命名空间吗?
当我命名类时,我应该期望哪些下划线在语法上有意义?
当我编写XML时,哪些标记对应于类层次结构,哪些不对应?
代码的哪些其他部分需要更改才能利用我的更改(如果有的话)?
基本上我不想搞货运崇拜。
我的场景的细节是:我试图改变magento的产品评论功能。此功能的代码位于/app/code/core/Mage/Review/中。当提交新的评论时,我在服务器端验证中添加了一个额外的步骤(我们的商店有垃圾邮件问题,所以我添加了一个额外的表单字段,用css将其隐藏起来,并抛出填充该表单字段的评论;我这样做是因为captchas是次优的ui选择)。我为/app/code/core/Mage/Review/controllers/ProductController.php的mage\u review\u productcontroller->postation()方法和/app/code/core/Mage/Review/Model/Review.php的mage\u review\u model\u review->validate()方法添加了代码。
然后,我隔离了添加的代码,将其放入/app/code/local/Mage/Review/controllers/ProductController.php/app/code/local/Mage/Review/Model/Review.php中,使用alan storm教程中的“类my_review_foo extends mage_review_foo”和“parent::method”建议。不出所料,这打破了产品页。所以我正在研究/app/code/local/Mage/Review/etc/config.xml并试图找出如何让magento使用我的类来扩展核心类。不幸的是,我无法告诉XML的底层逻辑是什么,所以我无法找出如何构造正确的XML来告诉Magento-“无论何时使用核心类,都要使用我的类而不是核心类。”
看起来,对核心类的任何更改最终都需要magento插件的全部功能和环境。是这样吗?我实际上需要做多少来填充我的更改,这样做背后的逻辑是什么?

最佳答案

Magento是关于配置的。最基本的功能模块只包含配置xml,它添加或重写现有的配置xml。也就是说,大多数开发需求需要实现配置,该配置向系统添加离散的新功能和/或更改现有功能。
重写块(相当于mvc中的“view”)有两种方法,helper和model类,它们的工作方式要么是因为include path order(在Magehub类中设置并由Varien_Autoload使用),要么更恰当地说是通过基于配置的重写(在Mage_Core_Model_Config::getGroupedClassName()方法中计算)。有关基于重写的重写指令,请参见下文。
通过设计(作为一种安全特性),这些方法都不适用于控制器;最终,控制器类定义会受到保护,不会被自动加载。接下来是关于如何使用非弃用方法重写操作控制器类的说明(此时为1.3.0到1.6.1.1)。注意,在magento ce 1.3.0之前,重写动作控制器类中的功能的方法是通过配置xml。
要重写控制器定义,必须了解如何在magento中调用控制器类,这是通过路由器类实现的。Magento Core有四个路由器类。路由器位于frontcontroller类(Mage_Review_Model_Review)之间,它们负责匹配请求和更改响应体。frontcontroller将遍历每个类,并对每个类进行计算,以确定是否应处理当前请求。通常这是一个配置+文件路径约定的问题。实际上,magento将frontname与初始目录匹配,然后将请求的其余部分与该目录下的路径和文件匹配。例如,应用程序中产品页的文字路径可能是http://demo.magentocommerce.com/review/product/list/id/51/。在这个url结构中,review是frontname(配置中的一个节点),它被映射到Mage_Core_Controller_Front。从那里,产品映射到该目录下的路径和文件名,即app/code/core/Mage/Review/controllers/,并从那里检查已解析类的listaction方法。看到了吗?review+product+list是frontname、controller类路径和方法“resolution params”。之后的任何内容都作为请求参数传递(例如id=51)。
由于ce 1.3.0,可以简单地将一个action controller类添加到一个目录列表中,路由器将在其中检查可解析路径(有关更多信息,请参见ProductController.php)。这是典型的magento:通过配置xml!顺便说一下,这种技术既可以用于添加新的控制器类路径,也可以用于控制器重写。
控制器重写模块至少需要三个文件:
模块声明文件(在Mage_Core_Controller_Varien_Router_Standard::collectRoutes()目录下以.xml结尾的文件)
aapp/etc/modules/在模块的config.xml目录中
与被重写的类具有相同路径分辨率的控制器文件。在上述示例中的类路径为“product”的情况下,该文件必须命名为etc并位于要添加的控制器目录的顶部,否则它将与类解析参数不匹配。同样,由于同样的原因,被重写的动作也必须与原始动作匹配。
声明文件将包含以下内容:

<?xml version="1.0" ?>
<config>
    <modules>
        <Example_Extension>
            <active>true</true>
            <codePool>local</codePool> <!-- or community -->
        </Example_Extension>
    </modules>
</config>

基于上述ProductController.php<Example_Extension>节点,应用程序将尝试加载<codePool>。在此文件中,如果要重写review模块的productcontroller类,则需要以下内容:
<?xml version="1.0" ?>
<config>
    <frontend>
        <routers>
            <review>
                <args>
                    <modules>
                        <some_unique_node before="Mage_Review">Example_Extension</some_unique_node>
                        <!--
                            This will map to the controllers directory under the
                            app/code/local/Example/Extension/ directory. Had this
                            value been "Example_Extension_Rewrites", the mapping
                            would be to the
                            app/code/local/Example/Extension/controllers/Rewrites/
                            directory. That is just how controller class paths are
                            evaluated: with a "controllers" directory after two levels
                            of folders.
                        -->
                    </modules>
                </args>
            </review>
        </routers>
    </frontend>
</config>

由于属性app/code/local/Example/Extension/etc/config.xml,示例扩展模块的controller s目录将添加在core review模块controller目录之前。因此,如果控制器和操作解析参数在示例扩展模块中匹配,则将使用其类。如果没有,默认的场景就会出现。
最后,要生成的剩余文件是操作控制器类本身。如果目的是从核心功能继承,那么从核心类扩展是有意义的。但是,为了让php加载核心类的定义,必须直接引用核心类,因为php无法通过前面提到的autoloader找到定义。这意味着在重写的类定义之前添加一个before="Mage_Review"
<?php

require_once 'Mage'.DS.'Review'.DS.'controllers'.DS.'ProductController.php';

class Example_Extension_ProductController extends Mage_Review_ProductController
{
    //rewritten and/or new method(s)
}

正如magento中block、helper和model类的情况一样,应用程序希望类具有与它们在文件系统中的位置相关的特定名称。
关于模型(以及块和助手)类重写:只需要添加必要的配置xml和类定义。根据这里的示例,重写require_once需要添加到示例扩展的config.xml中:
<config>
    <!-- ... -->
    <global>
        <models>
            <review>
                <rewrite>
                    <review>Example_Extension_Model_Review</review>
                </rewrite>
            </review>
        </models>
    </global>
</config>

基于此,Mage_Review_Model_Review(或Mage::getModel('review/review'))将在内部映射到Mage::getSingleton('review/review')节点中给定的类名,并返回重写的类实例。由于autoloader是如何工作的(请参见<rewrite>atVarien_Autoload),该类定义将需要位于lib/Varien/Autoload.php处,并且应该位于示例扩展的声明文件中指定的代码池下。
希望这有帮助。欲了解更多信息,请随时查阅其他的职位,以及马金托U。

关于php - 扩展Magento的核心类时,我需要更改哪种XML结构才能使更改生效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8405735/

相关文章:

mysql - AWS RDS + Magento 2

php - 从网站联系表接收电子邮件但没有内容

xml - 关键字 xsl :template may not contain xsl:next-match

javascript - 代码在windows下可以运行,但在linux下不行

php - Magento CE18 : Cannot save new password nor place order using credit card

管理面板中的 Magento 付款方式不见了

php - 在没有 pcntl_fork() 的情况下守护 PHP 脚本

php - Magento 1.4 $_POST ['field_name'] 不工作

php - 以编程方式为特定用户角色禁用税收

c# - 在 xml 文件中查找值的最有效方法?