在这篇文章中我将演示如何在Magento中编写自定义的邮寄方式。准确说来分为标准邮寄(standard shipping)和快递邮寄(express shipping)。只有当你购买的产品超过指定重量时才可能邮寄。首先说明下Magento如何处理邮寄以及为完成我们的目标需要些什么。
当寻找可用的邮寄方式是,Magento首先收集所有可用的载体(carriers)。一个“Carrier” 代表一个承运商,就像现实世界中的(例如联邦快递)。每一个载体都被表现在扩展自Mage_Shipping_Model_Carrier_Abstract的类。
在列出接受的载体后,邮寄方式信息(表现为Mage_Shipping_Model_Rate_Request)被送到载体去检索所有可用的费率,结果表现在Mage_Shipping_Model_Rate_Result。
这个过程发生在Mage_Shipping_Model_Shipping::collectRates()的这段代码里:
...
$carriers = Mage::getStoreConfig('carriers', $storeId);
foreach ($carriers as $carrierCode => $carrierConfig) {
$this->collectCarrierRates($carrierCode, $request);
}
...
collectCarrierRates()功能负责确认载体是否可用以及触发你的类中的collectRates()功能。 这大致就是在屏幕后所发生的事。现在,针对上面所讲我们要写一些代码。首先你要做的就是创建一个基于Mage_Shipping的模型。除了标准的模型配置外你还需要将以下代码放入你的config.xml:
<config>
...
<default>
...
<carriers>
<alwayly_shipping>
<active>1</active>
<model>alwayly_shipping/carrier</model>
<title>Alwayly Shipping Carrier</title>
<sort_order>10</sort_order>
<sallowspecific>0</sallowspecific>
<express_max_weight>1</express_max_weight>
</alwayly_shipping>
</carriers>
...
</default>
...
</config>
sallowspecific和express_max_items配置条目,我们稍后解释。我们将从模型条目开始。如你所见,我们的载体表现在 Alwayly_Shipping_Model_Carrier,所以让我们实现在个类吧。前面提到的,载体需要扩展自Mage_Shipping_Model_Carrier_Abstract 并且实现Mage_Shipping_Model_Carrier_Interface来确认Magento能使用它。我们将以下面的代码开始:
class Alwayly_Shipping_Model_Carrier
extends Mage_Shipping_Model_Carrier_Abstract
implements Mage_Shipping_Model_Carrier_Interface
{
protected $_code = 'alwayly_shipping';
接着,getAllowedMethods() 以key-value 形式的数组返回所有可用的方法。这正是我们的接口需要的,我们这么实现:
public function getAllowedMethods()
{
return array(
'standard' => 'Standard delivery',
'express' => 'Express delivery',
);
}
最后,我说过费率被collectRates()收集。这个功能将邮寄信息转换为字段,返回所有可用的费率。它还确定哪些费率可用于给定的要求。
public function collectRates(Mage_Shipping_Model_Rate_Request $request)
{
/** @var Mage_Shipping_Model_Rate_Result $result */
$result = Mage::getModel('shipping/rate_result');
/** @var Alwayly_Shipping_Helper_Data $expressMaxProducts */
$expressMaxWeight = Mage::helper('alwayly_shipping')->getExpressMaxWeight();
$expressAvailable = true;
foreach ($request->getAllItems() as $item) {
if ($item->getWeight() > $expressMaxWeight) {
$expressAvailable = false;
}
}
if ($expressAvailable) {
$result->append($this->_getExpressRate());
}
$result->append($this->_getStandardRate());
return $result;
}
如你所见,代码很明了。购物车里的产品重量都和设定的值做对比,由此来决定是否用快递费率每一种费率都是通过Mage_Shipping_Model_Rate_Result_Method 对象到append()这个我们的结果对象。我们通过alling _getExpressRate()和_getStandardRate()来获取这些费率对象,下面是代码:
protected function _getStandardRate()
{
/** @var Mage_Shipping_Model_Rate_Result_Method $rate */
$rate = Mage::getModel('shipping/rate_result_method');
$rate->setCarrier($this->_code);
$rate->setCarrierTitle($this->getConfigData('title'));
$rate->setMethod('large');
$rate->setMethodTitle('Standard delivery');
$rate->setPrice(1.23);
$rate->setCost(0);
return $rate;
}
功能类已经完成。我们最后通过system.xml文件来添加后台配置。这里是代码的缩略版:
<config>
<sections>
<carriers>
<groups>
<alwayly_shipping translate="label">
...
<fields>
<active translate="label">
...
</active>
<title translate="label">
...
</title>
<sallowspecific translate="label">
...
<frontend_type>select</frontend_type>
<frontend_class>shipping-applicable-country</frontend_class>
<source_model>adminhtml/system_config_source_shipping_allspecificcountries</source_model>
...
</sallowspecific>
<specificcountry translate="label">
...
<frontend_type>multiselect</frontend_type>
<source_model>adminhtml/system_config_source_country</source_model>
...
</specificcountry>
<express_max_weight translate="label">
...
</express_max_weight>
</fields>
</alwayly_shipping>
</groups>
</carriers>
</sections>
</config>
值得注意的是,active, title, sallowspecific 和specificcountry是被Magento自动处理的。所以除了把这些添加到后台外你什么也不用做。这里有两个有趣的选项,第一个是sallowspecific,告诉Magento运营商是否对所有国家可用,或者只针对specificcountry中指定的国家。这样,在支付页面添加邮寄方式的需求就实现了。
声明:这篇文章原文写于2009。
360团队与您同在