扩展Magento OnePage结帐课程

sim*_*ung 4 magento

我正在通过一个新模块向Magento结账添加一个额外的复选框字段以获取新闻通讯订阅.

到目前为止,我已将代码添加到我的布局文件(billing.phtml):

<p>Please untick this box if you do not wish to receive infrequent email updates and newsletters from us. <input type="checkbox" name="billing[is_subscribed]" title="" value="1" id="billing:is_subscribed" class="checkbox" checked="checked" /></p>
Run Code Online (Sandbox Code Playgroud)

我扩展了类(app/code/local/Clientname/Checkout/Model/Type/Onepage.php) - 我只扩展了savebilling方法:

<?php
/**
 * Magento
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Open Software License (OSL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/osl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@magentocommerce.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade Magento to newer
 * versions in the future. If you wish to customize Magento for your
 * needs please refer to http://www.magentocommerce.com for more information.
 *
 * @category    Mage
 * @package     Mage_Checkout
 * @copyright   Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
 * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */

/**
 * One page checkout processing model
 */

class Eatyourwords_Checkout_Model_Type_Onepage extends Mage_Checkout_Model_Type_Onepage
{

    public function saveBilling($data, $customerAddressId)
    {
        if (empty($data)) {
            return array('error' => -1, 'message' => $this->_helper->__('Invalid data.'));
        }

        $address = $this->getQuote()->getBillingAddress();

        if (!empty($customerAddressId)) {
            $customerAddress = Mage::getModel('customer/address')->load($customerAddressId);
            if ($customerAddress->getId()) {
                if ($customerAddress->getCustomerId() != $this->getQuote()->getCustomerId()) {
                    return array('error' => 1,
                        'message' => $this->_helper->__('Customer Address is not valid.')
                    );
                }
                $address->importCustomerAddress($customerAddress);
            }
        } else {
            // process billing address and validate form
            /* @var $addressForm Mage_Customer_Model_Form */
            $addressForm    = Mage::getModel('customer/form');
            $addressForm->setFormCode('customer_address_edit')
                ->setEntity($address)
                ->setEntityType('customer_address')
                ->setIsAjaxRequest(Mage::app()->getRequest()->isAjax());
            // emulate request object
            $addressData    = $addressForm->extractData($addressForm->prepareRequest($data));
            $addressErrors  = $addressForm->validateData($addressData);
            if ($addressErrors !== true) {
                return array('error' => 1, 'message' => $addressErrors);
            }
            $addressForm->compactData($addressData);

            if (!empty($data['save_in_address_book'])) {
                $address->setSaveInAddressBook(1);
            }
        }

        // validate billing address
        if (($validateRes = $address->validate()) !== true) {
            return array('error' => 1, 'message' => $validateRes);
        }

        $address->implodeStreetAddress();

        if (true !== ($result = $this->_validateCustomerData($data))) {
            return $result;
        }

        if (!$this->getQuote()->getCustomerId() && self::METHOD_REGISTER == $this->getQuote()->getCheckoutMethod()) {
            if ($this->_customerEmailExists($address->getEmail(), Mage::app()->getWebsite()->getId())) {
                return array('error' => 1, 'message' => $this->_customerEmailExistsMessage);
            }
        }

        if (!$this->getQuote()->isVirtual()) {
            /**
             * Billing address using otions
             */
            $usingCase = isset($data['use_for_shipping']) ? (int)$data['use_for_shipping'] : 0;

            switch($usingCase) {
                case 0:
                    $shipping = $this->getQuote()->getShippingAddress();
                    $shipping->setSameAsBilling(0);
                    break;
                case 1:
                    $billing = clone $address;
                    $billing->unsAddressId()->unsAddressType();
                    $shipping = $this->getQuote()->getShippingAddress();
                    $shippingMethod = $shipping->getShippingMethod();
                    $shipping->addData($billing->getData())
                        ->setSameAsBilling(1)
                        ->setShippingMethod($shippingMethod)
                        ->setCollectShippingRates(true);
                    $this->getCheckout()->setStepData('shipping', 'complete', true);
                    break;
            }
        }

        $this->getQuote()->collectTotals();

        if (isset($data['is_subscribed'])) {
            $status = Mage::getModel(‘newsletter/subscriber’)->subscribe($data['email']);
        }

        $this->getQuote()->save();

        $this->getCheckout()
            ->setStepData('billing', 'allow', true)
            ->setStepData('billing', 'complete', true)
            ->setStepData('shipping', 'allow', true);

        return array();
    }

}
Run Code Online (Sandbox Code Playgroud)

特别是我插入的类的底部:

if (isset($data['is_subscribed'])) {
            $status = Mage::getModel(‘newsletter/subscriber’)->subscribe($data['email']);
        }
Run Code Online (Sandbox Code Playgroud)

我添加了一个文件让Magento知道模块(app/etc/modules/Clientname_Checkout.xml):

<?xml version="1.0"?>

<config>
    <modules>
        <Clientname_Checkout>
            <active>true</active>
            <codePool>local</codePool>
        </Clientname_Checkout>
    </modules>
</config>
Run Code Online (Sandbox Code Playgroud)

然而,我现在停留在最后一步,我如何让Magento识别并使用我扩展的alernative save_billing方法.我想我需要添加一个文件/app/code/local/Clientname/config.xml.

但我不明白我是如何设置的,以便使用新的savebilling类而不是原始类.

有人可以帮助完成这最后一步吗?

谢谢

西蒙

Nic*_*ick 6

这是Magento中类重写的教科书示例.您可能知道,Magento使用一种抽象形式,根据代码库周围的XML配置文件的内容加载类.这意味着我们可以Mage_Checkout_Model_Type_Onepage通过Mage::getModel('checkout/type_onepage')使用默认配置调用来加载模型.一个非常酷的功能是能够修改模型引用的映射checkout/type_onepage到实际的类名.

目录结构

所以你已经完成了艰苦的工作:编辑模板并更改模型方法.接下来,您需要构建一个小模块来执行类重写.根据您的类的名称,您将需要一个表单的目录结构:

/app
  /etc
    /modules
      /Eatyourwords_Checkout.xml
  /code
    /local
      /Eatyourwords
        /Checkout
          /etc
            /config.xml
          /Model
            /Type
              /Onepage.php
Run Code Online (Sandbox Code Playgroud)

执行重写

重写在模块配置文件中处理config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <eyw_c>
            <version>1.0</version>
        </eyw_c>
    </modules>
    <global>
        <models>
            <eyw_c>Eatyourwords_Checkout_Model</eyw_c>
            <checkout>
                <rewrite>
                    <type_onepage>Eatyourwords_Checkout_Model_Type_Onepage</type_onepage>
                </rewrite>
            </checkout>
        </models>
    </global>
</config>
Run Code Online (Sandbox Code Playgroud)

中东西<modules />标签组是只为模块的一些标准的引导.

在本<models />节中,我们定义了在加载任何Model类时使用的命名空间.很像checkout/type_onepage,我们可以/Model通过追加访问我们目录中的任何模型eyw_c/*.

然后我们打开Mage_Checkout模型命名空间<checkout />,并执行checkout/type_onepage该类的重写.现在,当Magento试图加载checkout/type_onepage它时,将寻找我们的课程.所有其他checkout/*课程不受影响.它们的类名将以正常方式构造.

启用该模块

接下来,我们需要将Magento指向我们创建的新模块.你的尝试几乎是正确的.您应该将其调用Eatyourwords_Checkout.xml并放入/app/etc/modules:

<?xml version="1.0"?>
<config>
    <modules>
        <Eatyourwords_Checkout>
            <active>true</active>
            <codePool>local</codePool>
            <depends>
                <Mage_Checkout />
            </depends>
        </Eatyourwords_Checkout>
    </modules>
</config>
Run Code Online (Sandbox Code Playgroud)

..就是这样.班级被覆盖.