zoukankan      html  css  js  c++  java
  • 怎样改动、扩展并重写Magento代码

    作为一个开发人员的你,肯定要改动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
        }
    }


  • 相关阅读:
    Vim配置及使用技巧
    终端提示符的配置
    Archlinux下i3wm与urxvt的配置
    Linux压缩命令
    Archlinux无线联网教程
    Archlinux安装和使用技巧
    Linux下硬盘分区
    Linux挂载
    Android中pullToRefresh使用
    SVN服务器搭建和使用教程
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4185367.html
Copyright © 2011-2022 走看看