扩展 Magento OnePage 结帐类

发布于 2024-11-08 19:39:30 字数 6701 浏览 0 评论 0原文

我正在通过新模块向 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) - I仅扩展了 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 [email protected] 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 识别并使用我扩展的替代 save_billing 方法的最后一步。我想我需要添加一个文件 /app/code/local/Clientname/config.xml

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

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

谢谢西蒙

I am adding an additional checkbox field to the Magento checkout for newsletter subscriptions via a new module.

So far I have added the code to my layout file (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>

I have extended the class (app/code/local/Clientname/Checkout/Model/Type/Onepage.php) - I have extended only the savebilling method:

<?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 [email protected] 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();
    }

}

Specifically towards the bottom of the class I have inserted:

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

I have added a file to let Magento know about the module (app/etc/modules/Clientname_Checkout.xml):

<?xml version="1.0"?>

<config>
    <modules>
        <Clientname_Checkout>
            <active>true</active>
            <codePool>local</codePool>
        </Clientname_Checkout>
    </modules>
</config>

However I am now stuck on the final step of how I get Magento to recognise and use the alernative save_billing method I have extended. I think I need to add a file /app/code/local/Clientname/config.xml.

But I don't understand how I set this up so that the new savebilling class is used instead of the original.

Please can somebody help with this final step?

Thanks

Simon

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

双马尾 2024-11-15 19:39:30

这是 Magento 中类覆盖的教科书示例。您可能知道,Magento 使用一种抽象形式根据代码库中散布的 XML 配置文件的内容来加载类。这意味着我们可以通过调用 Mage::getModel('checkout/type_onepage') 使用默认配置来加载模型 Mage_Checkout_Model_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>

< code>标签组只是模块的一些标准引导。

部分中,我们定义加载任何模型类时要使用的命名空间。与 checkout/type_onepage 非常相似,我们可以通过附加 eyw_c/* 来访问 /Model 目录中的任何模型。

然后,我们打开 Mage_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>

..就这样完成了。类被覆盖。

This is a textbook example of class overrides in Magento. As you probably know, Magento uses a form of abstraction to load classes based on the contents of the XML configuration files dotted around the codebase. This means we can load the model Mage_Checkout_Model_Type_Onepage by calling Mage::getModel('checkout/type_onepage'), with the default configuration. A pretty cool feature is the ability to modify the mapping of the model reference, checkout/type_onepage to the actual class name.

Directory Structure

So you've done the hard work: editing the template and changing the model method. Next you need to build a small module to perform the class rewriting. Based on the name of your class, you're going to need a directory structure of the form:

/app
  /etc
    /modules
      /Eatyourwords_Checkout.xml
  /code
    /local
      /Eatyourwords
        /Checkout
          /etc
            /config.xml
          /Model
            /Type
              /Onepage.php

Performing the rewrite

The rewrite is handled in your module configuration file, 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>

The stuff in the <modules /> tag group is just some standard bootstrapping for the module.

In the <models /> section we are defining namespace to be used when loading any of our Model classes. Much like the checkout/type_onepage, we can access any models we have in our /Model directory by appending eyw_c/*.

We then open up the Mage_Checkout model namespace, <checkout />, and perform a rewrite of the checkout/type_onepage class. Now when Magento attempts to load checkout/type_onepage it will look for our class. All other checkout/* classes will be unaffected. The class name for them will be constructed in the normal manner.

Enable the module

Next we need to point Magento to the new module that we've created. Your attempt was almost correct. You should call it Eatyourwords_Checkout.xml and place it in /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>

..and that's it done. Class overridden.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文