西部数码主机 | 阿里云主机| 虚拟主机 | 服务器 | 返回乐道官网
当前位置: 主页 > php教程 > magento教程 >

Magento创建自定义配送方式 Create Shipping Method

时间:2013-12-07 23:54来源:未知 作者:好模板 点击:
Magento创建自定义配送方式并不是很复杂, 不过需要了解在 shipping method 类中所有有用的方法,然后加以利用, 那就变得十分简单了, 我会在这一节中示例不同 cases 情况下所使用的方法

Magento创建自定义配送方式并不是很复杂, 不过需要了解在 shipping method 类中所有有用的方法,然后加以利用, 那就变得十分简单了, 我会在这一节中示例不同 cases 情况下所使用的方法

 

当创建完成后, 配送方式主要会在如下两个地方被显示:

 

后台 – Admin Panel

 

Magento 后台显示配送方式

 

前台 – Frontend

 

Magento 前台显示配送方式

 

为了实现这些, 我们需要对如下三个文件进行修改:

 

config.xml | system.xml | Shipping Module

 

步骤一

 

在我们创建的时候, 需要为我们的配送方式决定一个标识, 在示例中, 我使用唯一标识就是 “excellence”, 接下来创建 system.xml, 这样就可以在后台 configuration 中进行配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<?xml version="1.0" encoding="UTF-8"?>
<config>
    <sections>
        <carriers>
            <groups>
                <excellence translate="label" module="ship">
                    <label>Excellence Shipping Module</label>
                    <frontend_type>text</frontend_type>
                    <sort_order>99</sort_order>
                    <show_in_default>1</show_in_default>
                    <show_in_website>1</show_in_website>
                    <show_in_store>1</show_in_store>
                    <fields>
                        <active translate="label">
                            <label>Enabled</label>
                            <frontend_type>select</frontend_type>
                            <source_model>adminhtml/system_config_source_yesno</source_model>
                            <sort_order>1</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </active>
                        <title translate="label">
                            <label>Title</label>
                            <frontend_type>text</frontend_type>
                            <sort_order>2</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </title>
                        <name translate="label">
                            <label>Method Name</label>
                            <frontend_type>text</frontend_type>
                            <sort_order>2</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </name>
                        <price translate="label">
                            <label>Price</label>
                            <frontend_type>text</frontend_type>
                            <sort_order>3</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>0</show_in_store>
                        </price>
                        <specificerrmsg translate="label">
                            <label>Displayed Error Message</label>
                            <frontend_type>textarea</frontend_type>
                            <sort_order>4</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </specificerrmsg>
                        <sallowspecific translate="label">
                            <label>Ship to Applicable Countries</label>
                            <frontend_type>select</frontend_type>
                            <sort_order>90</sort_order>
                            <frontend_class>shipping-applicable-country</frontend_class>
                            <source_model>adminhtml/system_config_source_shipping_allspecificcountries</source_model>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>0</show_in_store>
                        </sallowspecific>
                        <specificcountry translate="label">
                            <label>Ship to Specific Countries</label>
                            <frontend_type>multiselect</frontend_type>
                            <sort_order>91</sort_order>
                            <source_model>adminhtml/system_config_source_country</source_model>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>0</show_in_store>
                            <can_be_empty>1</can_be_empty>
                        </specificcountry>
                    </fields>
                </excellence>
            </groups>
        </carriers>
    </sections>
</config>

这里需要说明一下的就是, 我们需要将配送方式代码写在如下标签中, 和创建支付方式类似:

1
2
3
<sections>
    <carriers>
        <groups>

从这里你可以看出在 ‘excellence’ 标签中的就是我们配送方式的代码, 这些代码就是用来创建该配送方式是否启用, title, name, 和 price, 当然这些都是每一个配送方式所必须的
这里我们也同时创建了2个额外的标签, sallowspecific 和 specificcountry, 其实这也是需要, 因为有可能该配送方式只对某一些国家开放, 比如说有一个用户选择配送到冰岛, 然而我们的后台配置中并没有包括该国家, 为了达到限制, 我们只需要在我们的 xml 中写入这两个标签,并在后台加以配置就可以了, 不需要做其他额外的工作
还有一个就是 specificerrmsg 标签 – 错误信息, 当配送方式产生错误的时候, 这个标签里的内容就能显示给用户

 

步骤二

 

在 config.xml 中的 <config> 标签里写入如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
<default>
    <carriers>
        <excellence>
            <active>1</active>
            <model>ship/carrier_excellence</model>
            <title>Carrier Title</title>
            <name>Method Name</name>
            <price>5.00</price>
            <specificerrmsg>This shipping method is currently unavailable. If you would like to ship using this shipping method, please contact us.</specificerrmsg>
        </excellence>
     </carriers>
</default>

这里的 <default> 标签里的内容就是用来在后台 configuration 中为刚创建的标签设置默认值的, 可以看出基本和刚刚由 system.xml 所创建的一一对应, 唯一需要注意的就是 <model> 标签, 它包含了该配送方式的 model 路径, 这个十分重要, 否则该配送方式不会在前端页面显示

 

现在你可以到 Admin -> System -> Configuration -> Shipping Methods 中看到你刚新建的标签以及初始化的默认值

 

Magento 后台配置


 

步骤三

 

现在我们就要来创建我们配送方式的 model 类文件了, 对应和之前 <model> 标签中所申明的
Excellence_Ship_Model_Carrier_Excellence

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php
 
class Excellence_Ship_Model_Carrier_Excellence
    extends Mage_Shipping_Model_Carrier_Abstract
        implements Mage_Shipping_Model_Carrier_Interface
{
 
    protected $_code 'excellence';
 
    public function collectRates(Mage_Shipping_Model_Rate_Request $request)
    {
        if (!Mage::getStoreConfig('carriers/'.$this->_code.'/active')) {
            return false;
        }
         
        $handling = Mage::getStoreConfig('carriers/'.$this->_code.'/handling');
        $result   = Mage::getModel('shipping/rate_result');
        $show     = true;
        if ($show) {  // 这里这个 if 仅仅是为了演示如何在 shipping methods 中返回成功和错误的
            
            $method = Mage::getModel('shipping/rate_result_method');
            $method->setCarrier($this->_code);
            $method->setMethod($this->_code);
            $method->setCarrierTitle($this->getConfigData('title'));
            $method->setMethodTitle($this->getConfigData('name'));
            $method->setPrice($this->getConfigData('price'));
            $method->setCost($this->getConfigData('price'));
            $result->append($method);
 
        }else{
        
            $error = Mage::getModel('shipping/rate_result_error');
            $error->setCarrier($this->_code);
            $error->setCarrierTitle($this->getConfigData('name'));
            $error->setErrorMessage($this->getConfigData('specificerrmsg'));
            $result->append($error);
        }
        
        return $result;
    }
    
    public function getAllowedMethods()
    {
        return array('excellence'=>$this->getConfigData('name'));
    }
}


 

如上的代码还是比较容易理解的, 不过还是来逐行了解下:

1
public function collectRates(Mage_Shipping_Model_Rate_Request $request)

这个方法需要被执行, 正确来说会被 Magento 自身调用, 用来查找出 shipping rates

1
2
3
if (!Mage::getStoreConfig('carriers/'.$this->_code.'/active')) {
    return false;
}

这个 if 只是来检查该配送方式在后台配置中是否被开启

1
$result = Mage::getModel('shipping/rate_result');

这里我们创建了 result 对象, 它总是在配送方式中的 collectRate 方法里被返回出来

1
2
3
4
5
6
7
8
$method = Mage::getModel('shipping/rate_result_method');
$method->setCarrier($this->_code);
$method->setMethod($this->_code);
$method->setCarrierTitle($this->getConfigData('title'));
$method->setMethodTitle($this->getConfigData('name'));
$method->setPrice($this->getConfigData('price'));
$method->setCost($this->getConfigData('price'));
$result->append($method);

这些就是用来返回出运费价格(shipping price)的

1
2
3
4
5
$error = Mage::getModel('shipping/rate_result_error');
$error->setCarrier($this->_code);
$error->setCarrierTitle($this->getConfigData('name'));
$error->setErrorMessage($this->getConfigData('specificerrmsg'));
$result->append($error);

很明显,这些就是用来返回错误信息的

 

Model 类文件创建完毕后, 该配送方式应该就可以工作了, 你也可以在 checkout 和 cart 页面中看到

 

不同 cases 情况下所使用的方法

 

如下我所写的内容只适用在 collectRates 方法中, 下面我会分别列出不同的情况, 你可以根据自己的需求加以利用, 不过价格最后需要被放在 $result 变量中, 和上面示例中一样

 

运费价格基于目的地国家,州和邮政编码

1
2
3
4
5
6
7
8
9
10
11
//Case1: 运费价格基于目的地国家,州和邮政编码
        echo $destCountry $request->getDestCountryId().': Dest Country<br>';
        echo $destRegion  $request->getDestRegionId().': Dest Region<br>';
        echo $destRegionCode $request->getDestRegionCode().': Dest Region Code<br>';
        print_r($destStreet $request->getDestStreet()); echo ': Dest Street<br>';
        echo $destCity $request->getDestCity().': Dest City<br>';
        echo $destPostcode $request->getDestPostcode().': Dest Postcode<br>';
        echo $country_id $request->getCountryId().': Package Source Country ID<br>';
        echo $region_id $request->getRegionId().': Package Source Region ID<br>';
        echo $city $request->getCity().': Package Source City<br>';
        echo $postcode $request->getPostcode().': Package Source Post Code<br>';

可以根据自己业务逻辑的需求添加 if 条件来得出最后的价格

 

运费价格基于订单的价格或重量

1
2
3
4
5
6
//Case2: 运费价格基于订单的价格或重量
        echo $packageValue $request->getPackageValue().': Dest Package Value<br>';
        echo $packageValueDiscout $request->getPackageValueWithDiscount().': Dest Package Value After Discount<br>';
        echo $packageWeight $request->getPackageWeight().': Package Weight<br>';
        echo $packageQty $request->getPackageQty().': Package Quantity <br>';
        echo $packageCurrency $request->getPackageCurrency().': Package Currency <br>';

运费价格基于尺寸(Dimension)

1
2
3
4
//Case3: 运费价格基于尺寸
        echo $packageheight $request->getPackageHeight() .': Package height <br>';
        echo $request->getPackageWeight().': Package Width <br>';
        echo $request->getPackageDepth().': Package Depth <br>';

运费价格基于产品属性

 

假如你想让每个产品都有自己不同的运费价格, 为此, 我们需要创建一个产品属性叫: ‘shipping_price’’, 在每一个产品编辑页面填写该产品自己的运费价格, 这样我们就可以在配送方法中通过这个 ‘shipping_price’ 来计算出总运费价格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//Case4: 运费价格基于产品属性
        if ($request->getAllItems()) {
            foreach ($request->getAllItems() as $item) {
                if ($item->getProduct()->isVirtual() || $item->getParentItem()) {
                    continue;
                }
 
                if ($item->getHasChildren() && $item->isShipSeparately()) {
                    foreach ($item->getChildren() as $child) {
                        if ($child->getFreeShipping() && !$child->getProduct()->isVirtual()) {
                            $product_id $child->getProductId();
                            $productObj = Mage::getModel('catalog/product')->load($product_id);
                            $ship_price $productObj->getData('shipping_price'); //获取产品运费属性
                            $price += (float)$ship_price;
                        }
                    }
                else {
                    $product_id $item->getProductId();
                    $productObj = Mage::getModel('catalog/product')->load($product_id);
                    $ship_price $productObj->getData('shipping_price'); //获取产品运费属性
                    $price += (float)$ship_price;
                }
            }
        }

运费价格基于产品属性选项

 

假说说网站上有个产品含有多个尺寸, 在页面中提供下拉框来供用户选择, 小号(small)运费为 15, 中号(medium)运费为: 20, 大号(large)运费为: 25

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
//Case5: 运费价格基于产品属性选项
        if ($request->getAllItems()) {
            foreach ($request->getAllItems() as $item) {
                if ($item->getProduct()->isVirtual() || $item->getParentItem()) {
                    continue;
                }
                if ($item->getHasChildren() && $item->isShipSeparately()) {
                    foreach ($item->getChildren() as $child) {
                        if ($child->getFreeShipping() && !$child->getProduct()->isVirtual()) {
                            $product_id $child->getProductId();
                            $value $item->getOptionByCode('info_buyRequest')->getValue();
                            $params = unserialize($value);
                            $attributeObj = Mage::getModel('eav/config')->getAttribute(Mage_Catalog_Model_Product::ENTITY,'shirt_size'); // our configurable attribute
                            $attribute_id $attributeObj->getAttributeId();
                            $attribute_selected $params['super_attribute'][$attribute_id];
 
                            $label '';
                            foreach($attributeObj->getSource()->getAllOptions(false) as $option){
                                if($option['value'] == $attribute_selected){
                                    $label =  $option['label'];
                                }
                            }
                            if($label 'Small'){
                                $price += 15;
                            else if($label 'Medium'){
                                $price += 20;
                            else if($label 'Large'){
                                $price += 22;
                            }
                        }
                    }
                else {
                    $product_id $item->getProductId();
                    $value $item->getOptionByCode('info_buyRequest')->getValue();
                    $params = unserialize($value);
                    $attributeObj = Mage::getModel('eav/config')->getAttribute(Mage_Catalog_Model_Product::ENTITY,'shirt_size'); // our configurable attribute
                    $attribute_id $attributeObj->getAttributeId();
                    $attribute_selected $params['super_attribute'][$attribute_id];
 
                    $label '';
                    foreach($attributeObj->getSource()->getAllOptions(false) as $option){
                        if($option['value'] == $attribute_selected){
                            $label =  $option['label'];
                        }
                    }
                    if($label 'Small'){
                        $price += 15;
                    else if($label 'Medium'){
                        $price += 20;
                    else if($label 'Large'){
                        $price += 22;
                    }
                }
            }
        }

运费价格基于产品自定义选项

 

假如说网站上有某些产品, 拥有下拉框选项: 快递(Express) 和 邮局普递(Normal), 当用户选择快递(Express)时, 运费价格就是 50, 而邮局普递(Normal)价格则是 10

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//运费价格基于产品自定义选项
        if ($request->getAllItems()) {
            foreach ($request->getAllItems() as $item) {
                if ($item->getProduct()->isVirtual() || $item->getParentItem()) {
                    continue;
                }
                if ($item->getHasChildren() && $item->isShipSeparately()) {
                    foreach ($item->getChildren() as $child) {
                        if ($child->getFreeShipping() && !$child->getProduct()->isVirtual()) {
                            $product_id $child->getProductId();
                            $value $item->getOptionByCode('info_buyRequest')->getValue();
                            $params = unserialize($value);
                            $options_select $params['options'];
 
                            $product = Mage::getModel('catalog/product')->load($product_id);
                            $options $product->getOptions();
                            foreach ($options as $option) {
                                if ($option->getGroupByType() == Mage_Catalog_Model_Product_Option::OPTION_GROUP_SELECT) {
                                    $option_id =  $option->getId();
                                    foreach ($option->getValues() as $value) {
                                        if($value->getId() == $options_select[$option_id]){
                                            if($value->getTitle() == 'Express'){
                                                $price += 50;
                                            }else if($value->getTitle() == 'Normal'){
                                                $price += 10;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                else {
                    $product_id $item->getProductId();
                    $value $item->getOptionByCode('info_buyRequest')->getValue();
                    $params = unserialize($value);
                    $options_select $params['options'];
 
                    $product = Mage::getModel('catalog/product')->load($product_id);
                    $options $product->getOptions();
                    foreach ($options as $option) {
                        if ($option->getGroupByType() == Mage_Catalog_Model_Product_Option::OPTION_GROUP_SELECT) {
                            $option_id =  $option->getId();
                            foreach ($option->getValues() as $value) {
                                if($value->getId() == $options_select[$option_id]){
                                    if($value->getTitle() == 'Express'){
                                        $price += 50;
                                    }else if($value->getTitle() == 'Normal'){
                                        $price += 10;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

 

(责任编辑:好模板)
顶一下
(2)
50%
踩一下
(2)
50%
------分隔线----------------------------