在这篇博客中,我们将演示如何创建Magento 2模块和如何创建一种运输方式。如果你已经熟悉Magento 1,那所有的例子都是非常清楚的。创建运输方式相当简单,让我们举个例子吧。

首先,您需要创建一个Magento模块。您应该创建的目录结构如下面的截图所示:

创建模块后,您应该使用shell脚本启用模块:

php -f /bin/magento module:enable Magease_Shipping

此外,您可以使用命令检查是否启用了模块(此脚本将打印所有已启用模块的列表):

php -f /bin/magento module:status

让我们从一个处理运输方式的类开始。首先,应该在文件config.xml中定义运输方式,就像在下面的屏幕截图中一样。没有它就无法工作,xml中的主节点是“default”,节点“carrier”的子节点应与货运类 “Magease\Shipping\Model\Carrier\Example中的属性$ _code具有相同的名称

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
    <default>
        <carriers>
            <example>
                <active>1</active>
                <sallowspecific>0</sallowspecific>
                <model>Magease\Shipping\Model\Carrier\Example</model>
                <name>Magease Example Shipping</name>
                <price>15.00</price>
                <title>Magease Example</title>
                <type>I</type>
                <specificerrmsg>This shipping method is not available. To use this shipping method, please contact us.</specificerrmsg>
            </example>
        </carriers>
    </default>
</config>

在我们的config.xml中,您将注意到XML节点“model”,它定义了php类“Magease\Shipping\Model\Carrier\Example”。这是运输方式费用类,在这个类中应该实现所有运费计算的逻辑。

此外,每种运输方式都应该在后台中具有配置选项。您可以通过system.xml文件添加送货方式选项示例如下:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <section id="carriers" translate="label" type="text" sortOrder="320" showInDefault="1" showInWebsite="1" showInStore="1">
            <group id="example" translate="label" type="text" sortOrder="0" showInDefault="1" showInWebsite="1" showInStore="1">
                <label>Magease Example</label>
                <field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="0">
                    <label>Enabled</label>
                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
                </field>
                <field id="name" translate="label" type="text" sortOrder="3" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Method Name</label>
                </field>
                <field id="price" translate="label" type="text" sortOrder="5" showInDefault="1" showInWebsite="1" showInStore="0">
                    <label>Price</label>
                    <validate>validate-number validate-zero-or-greater</validate>
                </field>
                <field id="handling_type" translate="label" type="select" sortOrder="7" showInDefault="1" showInWebsite="1" showInStore="0">
                    <label>Calculate Handling Fee</label>
                    <source_model>Magento\Shipping\Model\Source\HandlingType</source_model>
                </field>
                <field id="handling_fee" translate="label" type="text" sortOrder="8" showInDefault="1" showInWebsite="1" showInStore="0">
                    <label>Handling Fee</label>
                    <validate>validate-number validate-zero-or-greater</validate>
                </field>
                <field id="sort_order" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="0">
                    <label>Sort Order</label>
                </field>
                <field id="title" translate="label" type="text" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Title</label>
                </field>
                <field id="sallowspecific" translate="label" type="select" sortOrder="90" showInDefault="1" showInWebsite="1" showInStore="0">
                    <label>Ship to Applicable Countries</label>
                    <frontend_class>shipping-applicable-country</frontend_class>
                    <source_model>Magento\Shipping\Model\Config\Source\Allspecificcountries</source_model>
                </field>
                <field id="specificcountry" translate="label" type="multiselect" sortOrder="91" showInDefault="1" showInWebsite="1" showInStore="0">
                    <label>Ship to Specific Countries</label>
                    <source_model>Magento\Directory\Model\Config\Source\Country</source_model>
                    <can_be_empty>1</can_be_empty>
                </field>
                <field id="showmethod" translate="label" type="select" sortOrder="92" showInDefault="1" showInWebsite="1" showInStore="0">
                    <label>Show Method if Not Applicable</label>
                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
                </field>
                <field id="specificerrmsg" translate="label" type="textarea" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Displayed Error Message</label>
                </field>
            </group>
        </section>
    </system>
</config>

运输类应如下所示:

<?php
namespace Magease\Shipping\Model\Carrier;
 
use Magento\Quote\Model\Quote\Address\RateRequest;
use Magento\Shipping\Model\Rate\Result;
 
class Example extends \Magento\Shipping\Model\Carrier\AbstractCarrier implements
    \Magento\Shipping\Model\Carrier\CarrierInterface
{
    /**
     * @var string
     */
    protected $_code = 'example';
 
    /**
     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
     * @param \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
     * @param \Psr\Log\LoggerInterface $logger
     * @param \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory
     * @param \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
        \Psr\Log\LoggerInterface $logger,
        \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
        \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
        array $data = []
    ) {
        $this->_rateResultFactory = $rateResultFactory;
        $this->_rateMethodFactory = $rateMethodFactory;
        parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
    }
 
    /**
     * @return array
     */
    public function getAllowedMethods()
    {
        return ['example' => $this->getConfigData('name')];
    }
 
    /**
     * @param RateRequest $request
     * @return bool|Result
     */
    public function collectRates(RateRequest $request)
    {
        if (!$this->getConfigFlag('active')) {
            return false;
        }
 
        /** @var \Magento\Shipping\Model\Rate\Result $result */
        $result = $this->_rateResultFactory->create();
 
        /** @var \Magento\Quote\Model\Quote\Address\RateResult\Method $method */
        $method = $this->_rateMethodFactory->create();
 
        $method->setCarrier('example');
        $method->setCarrierTitle($this->getConfigData('title'));
 
        $method->setMethod('example');
        $method->setMethodTitle($this->getConfigData('name'));
 
        /*you can fetch shipping price from different sources over some APIs, we used price from config.xml - xml node price*/
        $amount = $this->getConfigData('price');
 
        $method->setPrice($amount);
        $method->setCost($amount);
 
        $result->append($method);
 
        return $result;
    }
}

为了正确编写运输方法的php类,你应该尊重一些Magento 2规则。每个Magento 2运输类都应扩展“\Magento\Shipping\Model\Carrier\AbstractCarrier”并实现“\Magento\Shipping\Model\Carrier\CarrierInterface”。

在运输模型中,您至少需要创建两个php方法:“getAllowedMethods”和“collectRates”,抽象类和接口需要此方法。此外,您应该使用值定义属性$_code,在我们的例子中,那就是“example”,它与config.xml和节点结构有关。

Php方法“collectRates”接受参数“ $request ”,它是类“Magento\Quote\Model\Quote\Address\RateRequest”的实例化,此类包含有关购物车/报价,重量,送货地址等项目的所有信息,在此方法中,您可以实现运费计算的所有逻辑。通过此方法,您可以调用其他服务进行运费计算,但这取决于您的集成。

您可以在下面的屏幕截图中看到更多信息。

如果您按照我的写作实施了所有内容,您将能够在结帐时看到送货方式。


很简单的例子,希望对大家有用。