扩展 Magento OnePage 结帐类
我正在通过新模块向 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是 Magento 中类覆盖的教科书示例。您可能知道,Magento 使用一种抽象形式根据代码库中散布的 XML 配置文件的内容来加载类。这意味着我们可以通过调用
Mage::getModel('checkout/type_onepage')
使用默认配置来加载模型Mage_Checkout_Model_Type_Onepage
。一个非常酷的功能是能够修改模型引用checkout/type_onepage
到实际类名称的映射。目录结构
所以您已经完成了艰苦的工作:编辑模板并更改模型方法。接下来,您需要构建一个小模块来执行类重写。根据类的名称,您将需要以下形式的目录结构:
执行重写
重写是在模块配置文件
config.xml
中处理的:< code>标签组只是模块的一些标准引导。
在
部分中,我们定义加载任何模型类时要使用的命名空间。与checkout/type_onepage
非常相似,我们可以通过附加eyw_c/*
来访问/Model
目录中的任何模型。然后,我们打开
Mage_Checkout
模型命名空间
,并重写checkout/type_onepage
类。现在,当 Magento 尝试加载checkout/type_onepage
时,它会查找我们的类。所有其他checkout/*
类将不受影响。它们的类名将以正常方式构造。启用模块
接下来我们需要将 Magento 指向我们创建的新模块。你的尝试几乎是正确的。您应该将其命名为
Eatyourwords_Checkout.xml
并将其放置在/app/etc/modules
中:..就这样完成了。类被覆盖。
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 callingMage::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:
Performing the rewrite
The rewrite is handled in your module configuration file,
config.xml
: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 thecheckout/type_onepage
, we can access any models we have in our/Model
directory by appendingeyw_c/*
.We then open up the
Mage_Checkout
model namespace,<checkout />
, and perform a rewrite of thecheckout/type_onepage
class. Now when Magento attempts to loadcheckout/type_onepage
it will look for our class. All othercheckout/*
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
:..and that's it done. Class overridden.