在这一章节,我们来了解一下关于 Magento 核心类的重写机制,当重写后,就相当于告诉 Magento 使用我们重写后的类来替代原始的核心类
重写 – 在 Magento 模块开发中占有一席之地, 现在让我们了解下,为什么要重写:
1、当你升级 Magento 版本的时候,很多核心类会被替换成新的,
所以如果你将自己的代码也编写入内,那一旦升级,会被覆盖造成丢失或出错
2、如果将自定义代码编入我们自己的模块文件中,那样就能在 Magento Connect 中被有效的利用
现在让我们进入旅程吧
Blocks
假设我们现在需要在 Mage_Catalog_Block_Product 核心类中添加一些方法或变动,正因为它是一个核心类,所以我们需要重写它,这样核心类就可以不作任何变动,首先我们在 config.xml 里写入以下代码:
|
<blocks>
<catalog>
<rewrite>
<product>
Excellence_Test_Block_Catalog_Product
</product>
</rewrite>
</catalog>
</blocks>
|
现在在我们的 Block 文件夹中新增该类, (这属于我们自定义的模块)
|
Path:
Excellence
/
Test
/
Block
/
Catalog
/
Product
.
php
class
Excellence_Test_Block_Catalog_Product
extends
Mage_Catalog_Block_Product
{
}
|
这样操作的话,无论 Magento 什么时候创建 catalog/product 对象,它将会实例化我们新建的类,而不是核心类, 现在我们可以新增更多方法或者重写现有的方法
|
class
Excellence_Test_Block_Catalog_Product
extends
Mage_Catalog_Block_Product
{
public
function
getPrice
(
)
{
if
(
.
.
some
condition
.
.
)
{
return
.
.
custom
value
.
.
;
}
else
{
return
parent
::
getPrice
(
)
;
}
}
}
|
现在如果你仔细的话, 你会发现我们的类继承的是 Mage_Catalog_Block_Product, 这不是必须的, 但这样做的好处是自动继承了所有父类的方法, 我们就不必一一再去自己定义了
这里我再添加一个示例,关于 Block 内 Grid / From / Tabs 的重写
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<global>
<blocks>
<test>
<class>
Excellence_Test_Block
</class>
</test>
<adminhtml>
<rewrite>
<!-- 重写(Override) Mage_Adminhtml_Block_Customer_Edit_Tabs -->
<customer_edit_tabs>
Excellence_Test_Block_Adminhtml_Customer_Edit_Tabs
</customer_edit_tabs>
<!-- 重写(Override) Mage_Adminhtml_Block_Customer_Group_Grid -->
<customer_group_grid>
Excellence_Test_Block_Adminhtml_Customer_Group_Grid
</customer_group_grid>
<!-- 重写(Override) Mage_Adminhtml_Block_Customer_Group_Edit -->
<customer_group_edit>
Excellence_Test_Block_Adminhtml_Customer_Group_Edit
</customer_group_edit>
<!-- 重写(Override) Mage_Adminhtml_Block_Customer_Group_Edit_Form -->
<customer_group_edit_form>
Excellence_Test_Block_Adminhtml_Customer_Group_Edit_Form
</customer_group_edit_form>
</rewrite>
</adminhtml>
<customer>
<rewrite>
<!-- 重写(Override) Mage_Customer_Block_Form_Edit -->
<form_edit>
Excellence_Test_Block_Form_Edit
</form_edit>
</rewrite>
</customer>
</blocks>
</global>
|
这里只需要注意一点, 有可能由于类名过长的关系造成阅读上的影响,就像如上示例,但注意不能换行,因为一旦换行前面的空格会造成影响,所以标签 <customer_edit_tabs>…</customer_edit_tabs> 必须保持在一行
Models
和 Block 比较相似, 我们可以重写 Models, 假设我们想要重写 Product 类,
例如: Mage_Catalog_Model_Product, 在 config.xml 中写入以下内容
|
<models>
<catalog>
<rewrite>
<product>
Excellence_Test_Model_Product
</product>
</rewrite>
</catalog>
</models>
|
同时,我们新建重写的类
|
class
Excellence_Test_Model_Product
extends
Mage_Catalog_Model_Product
{
public
function
getPrice
(
)
{
if
(
.
.
some
condition
.
.
)
{
return
.
.
some
value
.
.
;
}
else
{
return
parent
::
getPrice
(
)
;
}
}
}
|
Helpers
Helpers 同样也可以被重写, 在 config.xml 中写入
|
<helpers>
<customer>
<rewrite>
<data>
Excellence_Test_Helper_Data
</data>
</rewrite>
</customer>
</helpers>
|
|
class
Excellence_Test_Helper_Data
extends
Mage_Customer_Helper_Data
{
}
|
另外值得注意的是, 我们只可以重写 Magento 能够实例化的类, 但就像 Magento 中一些抽象类, Mage_Catalog_Block_Product_Abstract, 像这种就不能够被重写
Controllers
想要重写一个核心 controller, 这是我们需要做的
|
<global>
<rewrite>
<test_cart>
<!-- 这可以是一个唯一的 ID -->
<from>
<!--[CDATA[#^/checkout/cart/#]]-->
</from>
<!-- 你想被重写的URL-->
<to>
/test/checkout_cart/
</to>
<!-- 重写后的URL -->
</test_cart>
</rewrite>
</global>
|
现在我们就来创建 controller 文件
Path: Excellence/Test/controllers/Checkout/CartController.php
|
require_once
'Mage/Checkout/controllers/CartController.php'
;
class
Excellence_Test_Checkout_CartController
extends
Mage_Checkout_CartController
{
}
|
两点关于 controller 重写和其他重写的不同之处
1、 controller的重写是基于URL的,而不是
class
路径
2、 你需要去
require
被你继承的类