扩展Magento OnePage结帐课程

时间:2011-05-21 07:37:47

标签: 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>

我已经扩展了类(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();
    }

}

特别是在我插入的课程的底部:

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

我添加了一个文件让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>

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

但我不明白我是如何设置它的,因此使用新的savebilling类而不是原始类。

请有人帮忙完成这最后一步吗?

由于

西蒙

1 个答案:

答案 0 :(得分: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

执行重写

重写在模块配置文件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>

<modules />标记组中的内容只是模块的一些标准引导。

<models />部分中,我们定义了在加载任何Model类时使用的 namespace 。与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>

..就是这样。课程被覆盖。

相关问题