作为一个开发人员的你,肯定要改动Magento代码去适应你的业务需求,可是在非常多时候我们不希望改动Magento的核心代码,这里有非常多原因,
比如将来还希望升级Magento、还想使用很多其它的Magento代码。假设你正在寻找改动Magento代码的最佳方式,那么此篇文章将会是一个不错的教程。

适合对象:高级开发人员

适合目标:开发人员希望自己定义改动Magento

当前版本号:Magento versions: 1.4.0.1

作者:精东

重写Magento模块(Module)

第一步,你须要创建属于你自己代码的命名空间,比如MagentoNotes,App等,为了方便与大家分享代码,我将空间命名为App。

app/
code/
core/
community/
local/
App/

假如你如今打算改动Mage/Catalog/Block/Breadcrumbs.php这个文件,你能够在你的命名空间,App里加入一个新的模块 “Catalog”。接下来创建块(Block)文件夹,并复制Breadcrumbs.php到你的新文件夹中。这里还须要你创建一个config.xml
配置文件。

app/
code/
core/
community/
local/
App/
Catalog/
Block/
Breadcrumbs.php
etc/
config.xml


改动Breadcrumbs.php的类名为App_Catalog_Block_Breadcrumbs,并继承原类名Mage_Catalog_Block_Breadcrumbs。

如今,你须要激活你的新模块,这样magento才可以知道你的新模块。

创建文件app/etc/modules/App_All.xml,加入例如以下代码。

< ?xml version="1.0"?>
<config>
<modules>
<App_Catalog>
<active>true</active>
<codePool>local</codePool>
</App_Catalog>
</modules>
</config>

以下我们须要一个特殊的标签来复写掉Breadcrumbs,以下我们通过模块的配置文件来实现。

重写Magento区块(Blocks)

编辑文件“app/code/local/App/Catalog/etc/config.xml”

<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<App_Catalog>
<version>0.1.0</version>
</App_Catalog>
</modules>
<global>
<blocks>
<catalog>
<rewrite>
<breadcrumbs>App_Catalog_Block_Breadcrumbs</breadcrumbs>
</rewrite>
</catalog>
</blocks>
</global>
</config>

我们须要加入一个“blocks” 标签,或者在已经存在的“blocks”标签中加入内容。然后在模块名后面加入rewrite标签,在这个样例中模块名是“catalog”。然后我们看 “breadcrumbs”标签,这个标签帮助magento找到我们我们想改动的块。在我们的列子中,breadcrumbs是Magento核心代码
中的类名: app/code/core/Mage/Catalog/Block/Breadcrumbs.php。假设你有很多其它的文件夹层级,能够用下滑线来分隔。比如:

<blocks>
<catalog>
<rewrite>
<category_view>App_Catalog_Block_Category_View</category_view>
</rewrite>
</catalog>
</blocks>

在这个样例中,我们重写了app/code/core/Mage/Catalog/Block/Category/View.php。

在breadcrumbs标签中的值是你的类名,这样Magento就能够获取你的类,由于类名与你的文件夹名一致。用过zend framework的人都知道,自己主动载入auto loader这个东西,它会跟你类名中的下滑线去你的文件夹中须要相应的类文件。记住一点,下滑线代表下一级别的文件夹,假设你的类名与你的文件文件夹名不一 致,那么Magento根本不会理睬你。

举例来说:

1
2
App_Catalog_Block_Breadcrumbs
→ /app/code/local/App/Catalog/Block/Breadcrumbs.php
App_Catalog_Block_Category_View
→ /app/code/local/App/Catalog/Block/Category/View.php

重写Magento控制器(Controller)-正則表達式匹配式

重写Magento控制器我们我们以重写购物车为例。

1、首先在App下创建新的模块,依次创建例如以下文件:

/app/code/local/App/Shopping
/app/code/local/App/Shopping/etc
/app/code/local/App/Shopping/etc/config.xml
/app/code/local/App/Shopping/controllers
/app/code/local/App/Shopping/controllers/CartController.php

2、编辑/app/code/local/App/Shopping/etc/config.xml文件,增加例如以下代码:

<?xml version="1.0"?>
<config>
<modules>
<App_Shopping>
<version>0.1.0</version>
</App_Shopping>
</modules>
<global>
<!-- This rewrite rule could be added to the database instead -->
<rewrite>
<!-- This is an identifier for your rewrite that should be unique -->
<!-- THIS IS THE CLASSNAME IN YOUR OWN CONTROLLER -->
<App_Shopping_cart>
<from><![CDATA[#^/checkout/cart/#]]></from>
<!--
- Shopping module matches the router frontname below - checkout_cart
matches the path to your controller Considering the router below,
"/shopping/cart/" will be "translated" to
"/App/Shopping/controllers/CartController.php" (?)
-->
<to>/shopping/cart/</to>
</App_Shopping_cart>
</rewrite>
</global>
<!--
If you want to overload an admin-controller this tag should be <admin>
instead, or <adminhtml> if youre overloading such stuff (?)
-->
<frontend>
<routers>
<App_Shopping>
<!-- should be set to "admin" when overloading admin stuff (?) -->
<use>standard</use>
<args>
<module>App_Shopping</module>
<!-- This is used when "catching" the rewrite above -->
<frontName>shopping</frontName>
</args>
</App_Shopping>
</routers>
</frontend>
</config>

3、改写你自己的控制器

/app/code/local/App/Shopping/controllers/CartController.php

请将以下的代码加入到你的控制器中,我们唯一改动的地方是在index动作中加入一个error_log();

# 控制器不会自己主动载入,所以我们须要包括文件,这里与区块(Block)不一样
require_once 'Mage/Checkout/controllers/CartController.php';
class App_Shopping_CartController extends Mage_Checkout_CartController
{
#覆写indexAction方法
public function indexAction()
{
# Just to make sure
error_log('成功重写购物车!');
parent::indexAction();
}
}

在这段代码中,首先是类名,跟前面讲到的区块(Block)一样,我们自己的类名是App_Shopping_CartController继承原先Mage_Checkout_CartController.在indexAction中我们记录了一段信息。

4、改动App_All.xml,激活我们新的Shopping模块

<?xml version="1.0"?>
<config>
<modules>
<App_Catalog>
<active>true</active>
<codePool>local</codePool>
</App_Catalog>
<App_Shopping>
<active>true</active>
<codePool>local</codePool>
</App_Shopping>
</modules>
</config>

到这里,清空Magento缓存后,你已经能够看到error_log成功记录了我们的信息,打开页面magentonotes.com/checkout
/cart/,显示的是购物车页面,一切正常,但假设你訪问magentonotes.com/shopping/cart/,你会发现是首 页。。。。我们期望的购物车视图还没有出现,怎样解决呢?让我们接下来往下看。

5、改动视图文件app/design/frontend/[myinterface]/[mytheme]/layout/checkout.xml

在layout标签中,加入以下内容:

<app_shopping_cart_index>
<update handle="checkout_cart_index"/>
</app_shopping_cart_index>

注意,这里的大写和小写敏感。

到这里基本大功告成,可是,我建议你学习下正則表達式,由于刚刚的代码中,有这么一段:

1
<from><
![CDATA[#^/checkout/cart/#]]></
from>

这里是使用正則表達式进行匹配的。

另一点,经过尝试,这里是能够支持同模块名覆盖的,比如Magento代码中商品详情页是Mage_Catalog_ProductController::viewAction(),假设我们想重写这个Controller,我们能够这样做:

1) 建立新的文件夹/app/code/local/App/Catalog/controllers/ProductController.php

代码例如以下:

require_once 'Mage/Catalog/controllers/ProductController.php';

/**
* Product controller
*
* @category Mage
* @package Mage_Catalog
*/
class App_Catalog_ProductController extends Mage_Catalog_ProductController
{
/**
* View product action
*/
public function viewAction()
{
echo '覆盖过的....';
parent::viewAction();
}
}

2) 编辑/app/code/local/App/Catalog/etc/config.xml,代码例如以下:

<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<App_Catalog>
<version>0.1.0</version>
</App_Catalog>
</modules>
<global>
<!-- This rewrite rule could be added to the database instead -->
<rewrite>
<!-- This is an identifier for your rewrite that should be unique -->
<!-- THIS IS THE CLASSNAME IN YOUR OWN CONTROLLER -->
<App_Shopping_cart>
<from><![CDATA[#^/catalog/product/#]]></from>
<!--
- Shopping module matches the router frontname below - checkout_cart
matches the path to your controller Considering the router below,
"/shopping/cart/" will be "translated" to
"/App/Shopping/controllers/CartController.php" (?)
-->
<to>/catalog/product/</to>
</App_Shopping_cart>
</rewrite>
<blocks>
<catalog>
<rewrite>
<breadcrumbs>App_Catalog_Block_Breadcrumbs</breadcrumbs>
</rewrite>
</catalog>
</blocks>
</global>
<frontend>
<routers>
<catalog>
<use>standard</use>
<args>
<module>App_Catalog</module>
<frontName>catalog</frontName>
</args>
</catalog>
</routers>
</frontend>
</config>

清空Magento缓存,刷新你的商品详情页,看是不是变了,呵呵。可是这种方法有个弊病,你须要把这个模块的全部Controller都复写掉,不然你会遇到比較大的麻烦。讲到这,我再介绍一种重写方法.

细致看配置文件的写法:

<?xml version="1.0"?>
<config>
<modules>
<App_Mycms>
<version>0.1.0</version>
</App_Mycms>
</modules>
<frontend>
<routers>
<mycms>
<use>standard</use>
<args>
<module>App_Mycms</module>
<frontName>mycms</frontName>
</args>
</mycms>
</routers>
</frontend>
<global>
<routers>
<cms>
<rewrite>
<index>
<to>App_Mycms/index</to>
<override_actions>true</override_actions>
<actions>
<noroute><to>App_Mycms/index/noroute</to></noroute>
</actions>
</index>
</rewrite>
</cms>
</routers>
</global>
</config>

综上所述,三种重写方法都各有千秋,关键看你用在什么地方。另外我们在实践中发现,Magento好像不建议你自己的模块名与现有系统中的模块名一 致,比如Mage_Customer是已有的,它的模块名叫Customer,假设你想复写它,那么最好你再建一个App_Customers之类的。

重写Magento模型和动作助手(Model&Helper)

我们在改写Magento的过程中,为了实现自己的业务逻辑,难免要改它的业务模型。你能够尝试用模块下的配置文件配置你自己的类,继承你想重写的模型或者助手,然后调用自己的类。如今我们以用户模型为例深入解说。

1) 首先创建自己的模块目录

app/code/local/App/Customer
app/code/local/App/Customer/etc/config.xml
app/code/local/App/Customer/Model
app/code/local/App/Customer/Model/Customer.php

2) 改动app/etc/modules/App_All.xml

<App_Customer>
<active>true</active>
<codePool>local</codePool>
</App_Customer>

3) 改动自己的模块配置文件app/code/local/App/Customer/etc/config.xml

<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<App_Customer>
<version>0.1.0</version>
</App_Customer>
</modules> <global>
<models>
<customer>
<rewrite>
<customer>App_Customer_Model_Customer</customer>
</rewrite>
</customer>
</models>
</global>
</config>

4) 如今写你新的Model,在文件app/code/local/App/Customer/Model/Customer.php中新建类App_Customer_Model_Cutomer

class App_Customer_Model_Customer extends Mage_Customer_Model_Customer {
// 重写已存在的方法
public function validate() {
// Define new validate rules. From now magento call this validate method instead of existing method
//return $errors;
return true;
} // 你还能够创建新的方法
public function newMethod() {
// function logic
}
}

5) 我们再重写一个类,以加深理解。接下来我们重写Customer Address Model。 跟重写Customer Model一样,我们先编辑模块的配置文件app/code/local/App/Customer/etc/config.xml

<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<App_Customer>
<version>0.1.0</version>
</App_Customer>
</modules> <global>
<models>
<customer>
<rewrite>
<customer>App_Customer_Model_Customer</customer>
<address>App_Customer_Model_Address</address>
</rewrite>
</customer>
</models>
</global>
</config>

上面看出来了么,rewrite标签内的customer和address事实上就是你要覆写的magento model。

接下来创建model class App_Customer_Model_Address,并写你要覆盖和新增的方法

class App_Customer_Model_Address extends Mage_Customer_Model_Address {
// 重写已存在的方法
public function validate() {
// Define new validate rules. From now magento call this validate method instead of existing method
//return $errors;
return true;
} // 你还能够创建新的方法
public function newMethod() {
// function logic
}
}

6)我再讲下怎样覆盖Magento的模型资源,这里以复写Address Entity Model class为例,我们先来改动模块的配置文件app/code/local/App/Customer/etc/config.xml。

<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<App_Customer>
<version>0.1.0</version>
</App_Customer>
</modules> <global>
<models>
<customer>
<rewrite>
<customer>App_Customer_Model_Customer</customer>
<address>App_Customer_Model_Address</address>
</rewrite>
</customer>
<customer_entity>
<rewrite>
<address>App_Customer_Model_Entity_Address</address>
</rewrite>
</customer_entity>
</models>
</global>
</config>

接下来创建类文件

class App_Customer_Model_Entity_Address extends Mage_Customer_Model_Entity_Address {
protected function _afterSave(Varien_Object $address) {
// Write your code
}
}

怎样改动、扩展并重写Magento代码的更多相关文章

  1. 深入理解Magento-第九章-修改、扩展、重写Magento代码

    (博主提示:本章应该不是原作者的第九章,仅作补充和参考) 作为一个开发者的你,肯定要修改Magento代码去适应你的业务需求,但是在很多时候我们不希望修改Magento的核心代码,这里有很多原因,例如 ...

  2. 利用扩展方法重写JSON序列化和反序列化

    利用.NET 3.5以后的扩展方法重写JSON序列化和反序列化,在代码可读性和可维护性上更加加强了. 首先是不使用扩展方法的写法 定义部分: /// <summary>  /// JSON ...

  3. Magento代码之订单创建流程

    Magento代码之订单创建流程         直接看代码吧.下面的代码是如何通过程序创建一个完美订单.        <?php        require_once 'app/Mage. ...

  4. 学习笔记: 反射应用、原理,完成扩展,emit动态代码

    using Ruanmou.DB.Interface; using Ruanmou.DB.MySql; using Ruanmou.DB.SqlServer; using Ruanmou.Model; ...

  5. [UE4]使用UnrealVS扩展快速编译C++代码

    一.如果UE4 编辑器已经打开,则VS中的重新生成项目将不能使用,一定要关了UE4 编辑器才可以.一般不是有VS自身的编译UE4的C++代码 二.epic提供了UnrealVS扩展,可以快速编译C++ ...

  6. asp获取文件名和扩展名的函数代码

    <% '获取文件名(不含扩展名) Function getFilename(text)text = Left(text,inStrRev(text,".")-1)getFil ...

  7. 使用扩展方法重写.NET底层架构

    我们在开发B/S架构的项目时,用到的都是.NET底层各种命名空间提供的操作类,利用扩展类可以重新写出一套真正属于你自己的框架. PS:扫描下方二维码或点击链接,加入QQ群

  8. 纹理特征描述之自相关函数法 纹理粗糙性与自相关函数的扩展成正比 matlab代码实现

    图像中通常采用自相关函数作为纹理测度 自相关函数的定义为: ​ 调用自定义函数 zxcor()对砖墙面和大理石面纹理进行分析: 自定义函数 zxcor(): function [epsilon,eta ...

  9. PHP扩展--vld查看opcode代码

    vld安装 wget http://pecl.php.net/get/vld-0.13.0.tgz tar zxvf vld-0.13.0.tgz cd vld-0.13.0 /usr/local/p ...

随机推荐

  1. Cocostudio学习笔记(4) LoadingBar+ TextField

    这同时录制两个控件的使用方法:LoadingBar和 TextField. -------------------------------------------------------------- ...

  2. FlexPaper二次开发问题及搜索高亮显示

    原文:FlexPaper二次开发问题及搜索高亮显示 最近有个需求,做一个IT知识库,类似于文库,说到文库肯定会用到在线浏览文档了,所有在网上翻阅了一下类似豆丁的在线浏览器插件的资料,将其进行了二次开发 ...

  3. Cordova探险系列(三)

    自从3.0之后.Cordova默认是关闭全部关于设备原生特性功能的,所以我们要通过加入插件来启动原生特性. 这里以Accelerometer(加速度感应器)为例,来学习怎样使用设备原生特性. 1.加入 ...

  4. 重新想象 Windows 8 Store Apps (29) - 图片处理

    原文:重新想象 Windows 8 Store Apps (29) - 图片处理 [源码下载] 重新想象 Windows 8 Store Apps (29) - 图片处理 作者:webabcd介绍重新 ...

  5. 【原创】leetCodeOj --- Excel Sheet Column Title 解题报告

    题目地址: https://oj.leetcode.com/problems/excel-sheet-column-title/ 题目内容: Given a positive integer, ret ...

  6. basename, dirname 在C语言中的使用

    basename作用是得到特定的路径中的最后一个'/',后面的内容 如/usr/bin,得到的内容就是bin 如果/sdcard/miui_recovery/backup 得到的内容就是backup ...

  7. Java Swing 树状组件JTree的使用方法(转)

    树中特定的节点可以由 TreePath(封装节点及其所有祖先的对象)标识,或由其显示行(其中显示区域中的每一行都显示一个节点)标识.展开 节点是一个非叶节点(由返回 false 的 TreeModel ...

  8. CodeForces 22D Segments 排序水问题

    主题链接:点击打开链接 升序右键点.采取正确的点 删边暴力 #include <cstdio> #include <cstring> #include <algorith ...

  9. eclipse在maven项目交付svn忽略简介

    文章来源:http://blog.csdn.net/chaijunkun/article/details/34805385,转载请注明. 不时因为它将有关鲍恩梳理,它会做出相应的内容不变.文. ecl ...

  10. hdu3182 状态压缩水题

    题意是这种     给你n个汉堡     每一个汉堡有它的价值   做每一个汉堡都得花费相应的能量      如今告诉你最大能量 让你求获得的最大的价值(有些汉堡必须有还有一些汉堡做好为前提) 给你的 ...