zoukankan      html  css  js  c++  java
  • 【转载】如何修改、扩展并重写Magento代码

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

    重写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,添加如下代码。

    1 < ?xml version="1.0"?>
    2 <config>
    3      <modules>
    4         <App_Catalog>
    5             <active>true</active>
    6             <codePool>local</codePool>
    7         </App_Catalog>
    8      </modules>
    9 </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。如果你有更多的目录层级,可以用下滑线来分隔。例如:

    1 <blocks>
    2     <catalog>
    3         <rewrite>
    4                 <category_view>App_Catalog_Block_Category_View</category_view>
    5         </rewrite>
    6     </catalog>
    7 </blocks>

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

    在breadcrumbs标签中的值是你的类名,这样Magento就可以获取你的类,因为类名与你的目录名一致。用过zend framework的人都知道,自动加载auto loader这个东西,它会跟你类名中的下滑线去你的目录中需要对应的类文件。记住一点,下滑线代表下一级别的文件夹,如果你的类名与你的文件目录名不一 致,那么Magento根本不会理睬你。
    举例来说:

    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下创建新的模块,依次创建如下文件:

    1 /app/code/local/App/Shopping
    2 /app/code/local/App/Shopping/etc
    3 /app/code/local/App/Shopping/etc/config.xml
    4 /app/code/local/App/Shopping/controllers
    5 /app/code/local/App/Shopping/controllers/CartController.php

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

     1 <?xml version="1.0"?>
     2 <config>
     3     <modules>
     4         <App_Shopping>
     5             <version>0.1.0</version>
     6         </App_Shopping>
     7     </modules>
     8     <global>
     9         <!-- This rewrite rule could be added to the database instead -->
    10         <rewrite>
    11             <!-- This is an identifier for your rewrite that should be unique -->
    12             <!-- THIS IS THE CLASSNAME IN YOUR OWN CONTROLLER -->
    13             <App_Shopping_cart>
    14                 <from><![CDATA[#^/checkout/cart/#]]></from>
    15                 <!--
    16                     - Shopping module matches the router frontname below - checkout_cart
    17                     matches the path to your controller Considering the router below,
    18                     "/shopping/cart/" will be "translated" to
    19                     "/App/Shopping/controllers/CartController.php" (?)
    20                 -->
    21                 <to>/shopping/cart/</to>
    22             </App_Shopping_cart>
    23         </rewrite>
    24     </global>
    25     <!--
    26         If you want to overload an admin-controller this tag should be <admin>
    27         instead, or <adminhtml> if youre overloading such stuff (?)
    28     -->
    29     <frontend>
    30         <routers>
    31             <App_Shopping>
    32                 <!-- should be set to "admin" when overloading admin stuff (?) -->
    33                 <use>standard</use>
    34                 <args>
    35                     <module>App_Shopping</module>
    36                     <!-- This is used when "catching" the rewrite above -->
    37                     <frontName>shopping</frontName>
    38                 </args>
    39             </App_Shopping>
    40         </routers>
    41     </frontend>
    42 </config>

    3、改写你自己的控制器
    /app/code/local/App/Shopping/controllers/CartController.php
    请将下面的代码添加到你的控制器中,我们唯一修改的地方是在index动作中添加一个error_log();

     1 # 控制器不会自动加载,所以我们需要包含文件,这里与区块(Block)不一样
     2 require_once 'Mage/Checkout/controllers/CartController.php';
     3 class App_Shopping_CartController extends Mage_Checkout_CartController
     4 {
     5     #覆写indexAction方法
     6     public function indexAction()
     7     {
     8         # Just to make sure
     9         error_log('成功重写购物车!');
    10         parent::indexAction();
    11     }
    12 }

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

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

     1 <?xml version="1.0"?>
     2 <config>
     3      <modules>
     4         <App_Catalog>
     5             <active>true</active>
     6             <codePool>local</codePool>
     7         </App_Catalog>
     8         <App_Shopping>
     9             <active>true</active>
    10             <codePool>local</codePool>
    11         </App_Shopping>
    12      </modules>
    13 </config>

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

    5、修改视图文件app/design/frontend/[myinterface]/[mytheme]/layout/checkout.xml
    在layout标签中,添加下面内容:

    1 <app_shopping_cart_index>
    2     <update handle="checkout_cart_index"/>
    3 </app_shopping_cart_index>

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

    到这里基本大功告成,但是,我建议你学习下正则表达式,因为刚刚的代码中,有这么一段:

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

    这里是使用正则表达式进行匹配的。

    还有一点,经过尝试,这里是可以支持同模块名覆盖的,例如Magento代码中商品详情页是Mage_Catalog_ProductController::viewAction(),如果我们想重写这个Controller,我们可以这样做:
    1) 建立新的目录/app/code/local/App/Catalog/controllers/ProductController.php
    代码如下:

     1 require_once 'Mage/Catalog/controllers/ProductController.php';
     2  
     3 /**
     4  * Product controller
     5  *
     6  * @category   Mage
     7  * @package    Mage_Catalog
     8  */
     9 class App_Catalog_ProductController extends Mage_Catalog_ProductController
    10 {
    11     /**
    12      * View product action
    13      */
    14     public function viewAction()
    15     {
    16         echo '覆盖过的....';
    17         parent::viewAction();
    18     }
    19 }
    2) 编辑/app/code/local/App/Catalog/etc/config.xml,代码如下:
     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <config>
     3     <modules>
     4         <App_Catalog>
     5             <version>0.1.0</version>
     6         </App_Catalog>
     7     </modules>
     8     <global>
     9         <!-- This rewrite rule could be added to the database instead -->
    10         <rewrite>
    11             <!-- This is an identifier for your rewrite that should be unique -->
    12             <!-- THIS IS THE CLASSNAME IN YOUR OWN CONTROLLER -->
    13             <App_Shopping_cart>
    14                 <from><![CDATA[#^/catalog/product/#]]></from>
    15                 <!--
    16                     - Shopping module matches the router frontname below - checkout_cart
    17                     matches the path to your controller Considering the router below,
    18                     "/shopping/cart/" will be "translated" to
    19                     "/App/Shopping/controllers/CartController.php" (?)
    20                 -->
    21                 <to>/catalog/product/</to>
    22             </App_Shopping_cart>
    23         </rewrite>
    24         <blocks>
    25             <catalog>
    26                 <rewrite>
    27                         <breadcrumbs>App_Catalog_Block_Breadcrumbs</breadcrumbs>
    28                 </rewrite>
    29             </catalog>
    30         </blocks>
    31     </global>
    32     <frontend>
    33         <routers>
    34             <catalog>
    35                 <use>standard</use>
    36                 <args>
    37                     <module>App_Catalog</module>
    38                     <frontName>catalog</frontName>
    39                 </args>
    40             </catalog>
    41         </routers>
    42     </frontend>
    43 </config>

    清空Magento缓存,刷新你的商品详情页,看是不是变了,呵呵。但是这个方法有个弊病,你需要把这个模块的所有Controller都复写掉,不然你会遇到比较大的麻烦。说到这,我再介绍一种重写方法.
    仔细看配置文件的写法:

     1 <?xml version="1.0"?>
     2 <config>
     3      <modules>
     4         <App_Mycms>
     5             <version>0.1.0</version>
     6         </App_Mycms>
     7     </modules>
     8     <frontend>
     9         <routers>
    10             <mycms>
    11                 <use>standard</use>
    12                 <args>
    13                     <module>App_Mycms</module>
    14                     <frontName>mycms</frontName>
    15                 </args>
    16             </mycms>
    17         </routers>
    18     </frontend>
    19     <global>
    20         <routers>
    21             <cms>
    22                 <rewrite>
    23                     <index>
    24                         <to>App_Mycms/index</to>
    25                         <override_actions>true</override_actions>
    26                         <actions>
    27                            <noroute><to>App_Mycms/index/noroute</to></noroute>
    28                         </actions>
    29                     </index>
    30                 </rewrite>
    31             </cms>
    32         </routers>
    33     </global>
    34 </config>

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

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

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

    1) 首先创建自己的模块文件夹

    1 app/code/local/App/Customer
    2 app/code/local/App/Customer/etc/config.xml
    3 app/code/local/App/Customer/Model
    4 app/code/local/App/Customer/Model/Customer.php

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

    1 <App_Customer>
    2     <active>true</active>
    3     <codePool>local</codePool>
    4 </App_Customer>

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

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <config>
     3     <modules>
     4         <App_Customer>
     5             <version>0.1.0</version>
     6         </App_Customer>
     7     </modules>
     8  
     9     <global>
    10         <models>
    11             <customer>
    12                 <rewrite>
    13                     <customer>App_Customer_Model_Customer</customer>
    14                 </rewrite>
    15             </customer>
    16         </models>
    17     </global>
    18 </config>

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

     1 class App_Customer_Model_Customer extends Mage_Customer_Model_Customer {
     2     // 重写已存在的方法
     3     public function validate() {
     4         // Define new validate rules. From now magento call this validate method instead of existing method
     5         //return $errors;
     6         return true;
     7     }
     8  
     9     // 你还可以创建新的方法
    10     public function newMethod() {
    11         // function logic
    12     }
    13 }

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

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <config>
     3     <modules>
     4         <App_Customer>
     5             <version>0.1.0</version>
     6         </App_Customer>
     7     </modules>
     8  
     9     <global>
    10         <models>
    11             <customer>
    12                 <rewrite>
    13                     <customer>App_Customer_Model_Customer</customer>
    14                     <address>App_Customer_Model_Address</address>
    15                 </rewrite>
    16             </customer>
    17         </models>
    18     </global>
    19 </config>

    上面看出来了么,rewrite标签内的customer和address其实就是你要覆写的magento model。
    接下来创建model class App_Customer_Model_Address,并写你要覆盖和新增的方法

     1 class App_Customer_Model_Address extends Mage_Customer_Model_Address {
     2     // 重写已存在的方法
     3     public function validate() {
     4         // Define new validate rules. From now magento call this validate method instead of existing method
     5         //return $errors;
     6         return true;
     7     }
     8  
     9     // 你还可以创建新的方法
    10     public function newMethod() {
    11         // function logic
    12     }
    13 }

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

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <config>
     3     <modules>
     4         <App_Customer>
     5             <version>0.1.0</version>
     6         </App_Customer>
     7     </modules>
     8  
     9     <global>
    10         <models>
    11             <customer>
    12                 <rewrite>
    13                     <customer>App_Customer_Model_Customer</customer>
    14                     <address>App_Customer_Model_Address</address>
    15                 </rewrite>
    16             </customer>
    17             <customer_entity>
    18                 <rewrite>
    19                     <address>App_Customer_Model_Entity_Address</address>
    20                 </rewrite>
    21             </customer_entity>
    22         </models>
    23     </global>
    24 </config>

    接下来创建类文件

    1 class App_Customer_Model_Entity_Address extends Mage_Customer_Model_Entity_Address {
    2     protected function _afterSave(Varien_Object $address) {
    3         // Write your code
    4     }
    5 }
  • 相关阅读:
    20145202 《信息安全系统设计基础》第7周学习总结(2)
    20145202 《信息安全系统设计基础》第7周学习总结(1)
    20145202 《信息安全系统设计基础》第6周学习总结(2)
    Y86模拟器的安装
    20145202 《信息安全系统设计基础》第6周学习总结(1)
    20145202 《信息安全系统设计基础》第5周学习总结(2)
    20145202 《信息安全系统设计基础》第5周学习总结(1)
    20145202 《信息安全系统设计基础》git安装
    20145202 《信息安全系统设计基础》第3周学习总结
    20145202 《信息安全系统设计基础》第2周学习总结
  • 原文地址:https://www.cnblogs.com/lyg1990/p/3338811.html
Copyright © 2011-2022 走看看