配送方法 API
WooCommerce 提供了配送方法 API,插件可以使用它来添加自己的费率。本文将引导您完成创建基于核心统一费率方法的新的配送方法,并与配送 API 交互的步骤。
创建一个插件
首先,创建一个标准的 WordPress/WooCommerce 插件 - 请参考我们的 [构建您的第一个扩展](docs/features/shipping/ /docs/extensions/getting-started-extensions/building-your-first-extension) 教程,以开始。您将在该插件文件中定义您的配送方法类,并在 WooCommerce 之外维护它。
检查 WooCommerce 并创建一个函数来存放您的类
在尝试加载我们的类之前,我们需要确保 WooCommerce 已启用,并且我们工作所需的必要类和函数是可用的。一旦我们知道这些是可用的,我们就可以添加一个动作来初始化我们的类,并添加一个过滤器,将我们的方法添加到主要的配送方法列表中。
/**
* 如果 WooCommerce 已启用,则这些类和函数将存在。
*/
if ( class_exists( 'woocommerce' ) && class_exists( 'WC_Shipping_Method' ) && function_exists( 'WC' ) ) {
// 我们添加一个动作来初始化我们的配送方法类,并添加一个过滤器,将我们的配送方法添加到方法列表中。
add_action( 'woocommerce_shipping_init', 'your_shipping_method_init' );
add_filter( 'woocommerce_shipping_methods', 'your_shipping_method_add' );
}
/**
* 您的函数,用于将您的配送方法添加到配送方法列表中。
*/
function your_shipping_method_add( $methods ) {
$methods['your_shipping_method'] = 'WC_Your_Shipping_Method';
return $methods;
}
/**
* 您的函数,用于初始化您的配送方法类。
*/
function your_shipping_method_init() {
// 您的类将放在这里
}
创建您的类
现在,我们创建一个类,将其放置在刚刚创建的函数内部。 最好确保该类不存在,以避免出现意外的致命错误。 该类需要继承 Shipping Method 类,以便我们能够访问 Shipping 和 Settings API。 我们还确保声明必要的属性,然后在构造函数中定义更多选项/属性,最后调用 init 方法。
if ( ! class_exists( 'WC_Your_Shipping_Method' ) ) {
class WC_Your_Shipping_Method extends WC_Shipping_Method {
/**
* 配送类型成本。
*
* @var string
*/
public $cost;
/**
* 配送类型。
*
* @var string
*/
public $type;
/**
* 您的配送类构造函数。
*
* @param int $instance_id 配送类型实例 ID。 每次在配送区域中创建实例时,都会分配一个新的实例 ID。
* @return void
*/
public function __construct( $instance_id = 0 ) {
$this->id = 'your_shipping_method'; // 您的配送类型 ID。 应该唯一。
$this->instance_id = absint( $instance_id );
$this->method_title = __( 'Your Shipping Method', 'your_text_domain' ); // 在管理员界面中显示的标题。
$this->method_description = __( 'Description of your shipping method', 'your_text_domain' ); // 在管理员界面中显示的描述。
$this->supports = array(
'settings', // 提供一个独立的设置选项卡,该选项卡位于 WooCommerce > 设置 > 配送 区域下,用于您的配送类型。
'shipping-zones', // 允许商家将您的配送类型添加到配送区域。
'instance-settings', // 允许一个页面,供商家编辑包含在配送区域中的您的配送类型的实例。
'instance-settings-modal', // 允许一个模态框,供商家编辑包含在配送区域中的您的配送类型的实例。
);
// 配送类型的附加初始化。
$this->init();
}
}
}
定义设置/选项
为了确保在选项更新时,对配送方法添加一个动作,调用 process_admin_options 函数,以便保存管理员/商家选择保存时输入的任何设置。
然后,可以使用 WooCommerce 设置 API 定义选项。 我们有两个额外的 Method,init_form_fields 和 init_instance_form_fields,它们将分别初始化独立设置和实例设置的表单字段。 其他选项,例如标题、税收状态等,通过设置 API 的 get_option Method 进行设置。 这些设置适用于独立的 Page,或者实例设置,具体取决于当前正在 Display 的内容。
/**
* 配送方法选项的附加初始化,在构造函数中通常是不必要的。
*
* @return void
*/
public function init() {
// 如果已定义任何设置,则在管理员界面中保存设置。(使用配送/设置 API)
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
// 初始化独立的设置和实例设置的表单字段。
$this->init_form_fields();
$this->init_instance_form_fields();
// 使用设置 API 获取已保存的选项,用于设置字段。
$this->title = $this->get_option( 'title' );
$this->tax_status = $this->get_option( 'tax_status' );
$this->cost = $this->get_option( 'cost' );
$this->type = $this->get_option( 'type', 'class' );
}
# 设置页面表单字段初始化
/**
* 用于初始化独立设置页面的表单字段,如果需要。
*
* @return void
*/
public function init_form_fields() {
// 将 `form_fields` 属性设置为一个数组,该数组可供设置 API 在页面上显示字段。
$this->form_fields = array(
'title' => array(
'title' => __( '名称', 'your_text_domain' ),
'type' => 'text',
'description' => __( '您的客户将在结账时看到此配送方式的名称。', 'your_text_domain' ),
'default' => __( '您的配送方式', 'your_text_domain' ),
'placeholder' => __( '例如:标准国内', 'your_text_domain' ),
'desc_tip' => true, // 如果希望将描述显示为工具提示,则包含此项。
),
'tax_status' => array(
'title' => __( '税收状态', 'your_text_domain' ),
'type' => 'select',
'class' => 'wc-enhanced-select',
'default' => 'taxable',
'options' => array(
'taxable' => __( '应税', 'your_text_domain' ),
'none' => _x( '免税', '税收状态', 'your_text_domain' ),
),
),
'cost' => array(
'title' => __( '费用', 'your_text_domain' ),
'type' => 'text',
'placeholder' => '',
'description' => __( '请输入费用(不含税)。', 'your_text_domain' ),
'default' => '0',
'desc_tip' => true,
'sanitize_callback' => array( $this, 'sanitize_cost' ),
),
);
}
/**
* 用于初始化独立实例的表单字段。
*
* @return void
*/
private function init_instance_form_fields() {
// 定义一些字符串,这些字符串将多次用于费用描述和链接。
$cost_desc = __( '请输入费用(不含税)。', 'your_text_domain' );
$cost_link = sprintf( '<span id="wc-shipping-advanced-costs-help-text">%s <a target="_blank" href="https://woocommerce.com/document/flat-rate-shipping/#advanced-costs">%s</a>.</span>', __( '按件收取统一费率,或输入费用公式,以按百分比收取费用,或收取最低费用。 了解更多关于', 'your_text_domain' ), __( '高级费用', 'your_text_domain' ) );
}
统一费率配送设置
// 开始定义字段数组。
$fields = array(
'title' => array(
'title' => __( '名称', 'your_text_domain' ),
'type' => 'text',
'description' => __( '您的客户将在结账时看到此配送方式的名称。', 'your_text_domain' ),
'default' => __( '您的配送方式', 'your_text_domain' ),
'placeholder' => __( '例如:标准国内', 'your_text_domain' ),
'desc_tip' => true,
),
'tax_status' => array(
'title' => __( '税收状态', 'your_text_domain' ),
'type' => 'select',
'class' => 'wc-enhanced-select',
'default' => 'taxable',
'options' => array(
'taxable' => __( '应税', 'your_text_domain' ),
'none' => _x( '免税', '税收状态', 'your_text_domain' ),
),
),
'cost' => array(
'title' => __( '费用', 'your_text_domain' ),
'type' => 'text',
'class' => 'wc-shipping-modal-price',
'placeholder' => '',
'description' => $cost_desc,
'default' => '0',
'desc_tip' => true,
'sanitize_callback' => array( $this, 'sanitize_cost' ),
),
);
/**
* 统一费率配送可以按配送类型添加费用,因此这里获取配送类型,并提供字段供商家/管理员使用,以便他们可以指定这些费用。
*/
$shipping_classes = WC()->shipping()->get_shipping_classes();
if ( ! empty( $shipping_classes ) ) {
$fields['class_costs'] = array(
'title' => __( '按配送类型划分的费用', 'your_text_domain' ),
'type' => 'title',
'default' => '',
/* 译者: %s: 链接的 URL */
'description' => sprintf( __( '这些费用可以选择性地根据 <a target="_blank" href="%s">产品配送类型</a> 添加。 了解更多关于 <a target="_blank" href="https://woocommerce.com/document/flat-rate-shipping/#shipping-classes">设置配送类型费用</a> 的信息。', 'your_text_domain' ), admin_url( 'admin.php?page=wc-settings&tab=shipping§ion=classes' ) ),
);
foreach ( $shipping_classes as $shipping_class ) {
if ( ! isset( $shipping_class->term_id ) ) {
continue;
}
$fields[ 'class_cost_' . $shipping_class->term_id ] = array(
/* 译者: %s: 配送类型名称 */
'title' => sprintf( __( '"%s" 配送类型的费用', 'your_text_domain' ), esc_html( $shipping_class->name ) ),
'type' => 'text',
'class' => 'wc-shipping-modal-price',
'placeholder' => __( 'N/A', 'your_text_domain' ),
'description' => $cost_desc,
'default' => $this->get_option( 'class_cost_' . $shipping_class->slug ),
'desc_tip' => true,
'sanitize_callback' => array( $this, 'sanitize_cost' ),
);
}
}
说明:
- 配送类型: Shipping Classes
- 配送类型: Shipping Class
- 设置: Settings
- 状态: Status
- 链接: Link
- 别名: Slug
- 网页: Page
- 占位符: Placeholder
- 译者: Translators
- 类名: Class name
- 客户: Customers
- 统一费率: Flat Rate
- 继续: Continue
- 文档: document
- 配送: Shipping
- 结账: Checkout
- 部分: Section
- 产品: Product
- 字段: Fields
- 选择: Select
# 配送类型配置
本节描述如何配置配送类型。
**使用**以下步骤配置配送类型:
1. **选择**“配送类型”选项。
2. **选择**“添加新类型”按钮。
3. **在**“标题”字段中输入配送类型的名称。
4. **在**“描述”字段中输入配送类型的描述。
5. **选择**“启用”复选框以启用配送类型。
6. **单击**“更新”按钮保存更改。
以下是可用的字段:
* `no_class_cost`: 无配送类型费用。
* `type`: 计算类型。
以下是每个字段的详细信息:
## 字段描述
```php
$fields['no_class_cost'] = array(
'title' => __( 'No shipping class cost', 'your_text_domain' ),
'type' => 'text',
'class' => 'wc-shipping-modal-price',
'placeholder' => __( 'N/A', 'your_text_domain' ),
'description' => $cost_desc,
'default' => '',
'desc_tip' => true,
'sanitize_callback' => array( $this, 'sanitize_cost' ),
);
$fields['type'] = array(
'title' => __( 'Calculation type', 'your_text_domain' ),
'type' => 'select',
'class' => 'wc-enhanced-select',
'default' => 'class',
'options' => array(
'class' => __( 'Per class: Charge shipping for each shipping class individually', 'your_text_domain' ),
'order' => __( 'Per order: Charge shipping for the most expensive shipping class', 'your_text_domain' ),
),
'description' => $cost_link,
);
}
// And finally we set the instance_form_fields property for the Shipping API to use.
$this->instance_form_fields = $fields;
}
no_class_cost: 无配送类型费用。
type: 计算类型。
class: 按配送类型:为每个配送类型单独收取运费。order: 按订单:收取最昂贵的配送类型的运费。
最后,我们设置 instance_form_fields 属性,以便 Shipping API 使用。
## 清理成本
在前面的代码片段中,您可以看到有一个 `sanitize_callback` 用于 `sanitize_cost`,虽然这可能并不总是需要,但始终牢记清理用户输入仍然是一个好习惯。由于成本字段需要是一个文本字段才能允许使用十进制分隔符,因此我们需要确保输入的值是有效的。为此,我们引入了以下方法。
```php
/**
* 清理成本值。
* 当 `sanitize_callback` 方法在 Settings API 中被调用时,此方法会被调用,用于保存商家输入的值。
*
* @param string $value 未清理的值。
* @return string
* @throws Exception 如果成本不是数值。
*/
public function sanitize_cost( $value ) {
// 如果值为空,则将其设置为零。对值运行 WordPress 核心的清理函数,然后移除货币符号,如果存在。
$value = is_null( $value ) ? '0' : $value;
$value = wp_kses_post( trim( wp_unslash( $value ) ) );
$value = str_replace( array( get_woocommerce_currency_symbol(), html_entity_decode( get_woocommerce_currency_symbol() ) ), '', $value );
// 获取当前区域设置以及所有可能的十进制分隔符。
$locale = localeconv();
$decimals = array( wc_get_price_decimal_separator(), $locale['decimal_point'], $locale['mon_decimal_point'], ',' );
// 移除空格,然后移除十进制分隔符,然后移除无效的起始/结束字符。
$value = preg_replace( '/\s+/', '', $value );
$value = str_replace( $decimals, '.', $value );
$value = rtrim( ltrim( $value, "\t\n\r\0\x0B+*/" ), "\t\n\r\0\x0B+-*/" );
// 如果值不是数值,则抛出异常。
if ( ! is_numeric( $value ) ) {
throw new Exception( 'Invalid cost entered.' );
}
return $value;
}
添加运费
运费通过 Shipping API 使用 add_rate 方法添加。以下是可用选项的分解,在下一部分我们将将其应用到实际中。
您的配送方法可以传递任意数量的运费,只需确保每个运费的 ID 都是不同的。 用户可以在结账时选择运费。
$rate = array(
'label' => '', // 运费的标签。
'cost' => '0', // 运费金额,或用于每个商品的运费的费用数组。
'taxes' => '', // 传递一个税费数组,或者不传递任何内容以让系统自动计算,或者传递 'false' 以表示此方法不计算税费。
'calc_tax' => 'per_order' // 按订单计算税费 (per_order) 或按商品计算税费 (per_item)。 按商品计算需要通过 'cost' 传递一个费用数组。
);
// 注册运费
$this->add_rate( $rate );
calculate_shipping() 方法
用于添加费率的方法是 calculate_shipping。当 WooCommerce 在购物车和结账过程中进行配送计算时,会调用此方法。在此处进行插件特定的计算,然后通过配送 API 添加费率。
我们还包含 find_shipping_classes 方法,该方法从每个包裹中的商品获取配送类型。
/**
* 计算配送成本。
*
* @param array $package 购物车中的商品包裹。
*/
public function calculate_shipping( $package = array() ) {
// 获取此实例的费率设置。
$rate = array(
'id' => $this->get_rate_id(), // 从配送 API 获取实例费率 ID。
'label' => $this->title,
'cost' => 0,
'package' => $package,
);
// 计算成本。
$has_costs = false; // 如果设置了成本,则为 true。如果所有成本为空字符串,则为 false。
$cost = $this->get_option( 'cost' );
// 如果设置了成本,则评估成本以确保其有效。
if ( '' !== $cost ) {
$has_costs = true;
$rate['cost'] = $cost;
}
// 统一费率具有为每个配送类型设置成本的能力,因此,这里获取配送类型,并添加相应的成本。
$shipping_classes = WC()->shipping()->get_shipping_classes();
if ( ! empty( $shipping_classes ) ) {
// 检查购物车/包裹中的产品是否已分配了配送类型。
$found_shipping_classes = $this->find_shipping_classes( $package );
$highest_class_cost = 0;
// 如果发现产品已分配了配送类型,则遍历每个配送类型。
foreach ( $found_shipping_classes as $shipping_class => $products ) {
// 同时也处理向后兼容性,即使用别名而不是 ID 的情况。
$shipping_class_term = get_term_by( 'slug', $shipping_class, 'product_shipping_class' );
$class_cost = $shipping_class_term && $shipping_class_term->term_id ? $this->get_option( 'class_cost_' . $shipping_class_term->term_id, $this->get_option( 'class_cost_' . $shipping_class, '' ) ) : $this->get_option( 'no_class_cost', '' );
// 如果未为配送类型分配成本,则跳过该配送类型。
if ( '' === $class_cost ) {
continue;
}
// 我们有一个配送类型成本,因此,评估该类成本以确认其有效。
$has_costs = true;
/**
* 统一费率在配送类型方面有两种选择:按类或按订单。
* 这里检查该设置,以便相应地应用成本。
*/
if ( 'class' === $this->type ) {
$rate['cost'] += $class_cost;
} else {
$highest_class_cost = $class_cost > $highest_class_cost ? $class_cost : $highest_class_cost;
}
}
// 如果成本是按订单计算的,则将最高的类成本应用于基本成本。
if ( 'order' === $this->type && $highest_class_cost ) {
$rate['cost'] += $highest_class_cost;
}
}
配送类型相关功能
以下代码片段展示了与配送类型相关的实现。
if ( $has_costs ) {
$this->add_rate( $rate );
}
/**
* 开发者可以通过以下动作,基于此统一费率添加额外的费率,自 @version 2.4 起。
*
* 之前存在(过于复杂)的选项来添加额外的费率,但这些选项不够用户友好,并且与统一费率配送的最初意图相悖。
*/
do_action( 'woocommerce_' . $this->id . '_shipping_add_rate', $this, $rate );
}
/**
* 查找并返回配送类型以及具有该配送类型的产品。
*
* @param mixed $package 购物车中的项目集合。
* @return array
*/
public function find_shipping_classes( $package ) {
$found_shipping_classes = array();
foreach ( $package['contents'] as $item_id => $values ) {
if ( $values['data']->needs_shipping() ) {
$found_class = $values['data']->get_shipping_class();
if ( ! isset( $found_shipping_classes[ $found_class ] ) ) {
$found_shipping_classes[ $found_class ] = array();
}
$found_shipping_classes[ $found_class ][ $item_id ] = $values;
}
}
return $found_shipping_classes;
}
说明:
Shipping Classes译为配送类型Shipping Class译为配送类型Version 2.4译为版本 2.4Developers译为开发者Flat Rate译为统一费率Version译为版本Contents译为内容Shipping译为配送Product译为产品Option译为选项Rates译为费率Value译为价值Mixed译为混合Class译为类Data译为数据Cart译为购物车Item译为项目Find译为查找Via译为通过
整合所有内容
我们精简后的统一费率配送方法独立插件的代码如下:
<?php
/**
* 插件名称: Your Shipping 插件
* 插件 URI: https://woocommerce.com/
* 描述: Your shipping 方法插件
* 版本: 1.0.0
* 作者:WooCommerce
* 作者 URI: https://woocommerce.com/
* Text Domain: your_text_domain
*/
/**
* 如果 WooCommerce 处于激活状态,则该类将存在。
*/
if ( class_exists( 'woocommerce' ) && class_exists( 'WC_Shipping_Method' ) && function_exists( 'WC' ) ) {
// 我们添加一个动作来初始化我们的配送方法类,并添加一个过滤器来将我们的配送方法添加到方法列表中。
add_action( 'woocommerce_shipping_init', 'your_shipping_method_init' );
add_filter( 'woocommerce_shipping_methods', 'your_shipping_method_add' );
}
/**
* 您的函数,用于将您的配送方法添加到配送方法列表中。
*/
function your_shipping_method_add( $methods ) {
$methods['your_shipping_method'] = 'WC_Your_Shipping_Method';
return $methods;
}
/**
* 您的函数,用于初始化您的配送方法类。
*/
function your_shipping_method_init() {
/**
* 理想情况下,这应该从另一个文件中包含该类,但为了演示目的,我们将在其中包含它。
*/
if ( ! class_exists( 'WC_Your_Shipping_Method' ) ) {
class WC_Your_Shipping_Method extends WC_Shipping_Method {
/**
* 配送方法成本。
*
* @var string
*/
public $cost;
/**
* 配送方法类型。
*
* @var string
*/
public $type;
/**
* 您的配送类型的构造函数。
*
* @param int $instance_id 配送方法实例 ID。每次在配送区域中创建实例时,都会分配一个新的实例 ID。
* @return void
*/
public function __construct( $instance_id = 0 ) {
$this->id = 'your_shipping_method'; // 您的配送方法的 ID。应该唯一。
$this->instance_id = absint( $instance_id );
$this->method_title = __( 'Your Shipping Method', 'your_text_domain' ); // 在管理员界面中显示的标题。
$this->method_description = __( 'Description of your shipping method', 'your_text_domain' ); // 在管理员界面中显示的描述。
$this->supports = array(
'settings', // 提供一个独立的设置选项卡,位于 WooCommerce > 设置 > 配送。
'shipping-zones', // 允许商家将您的配送方法添加到配送区域。
'instance-settings', // 允许一个页面,供商家编辑包含在配送区域中的您的方法的实例。
'instance-settings-modal', // 允许一个模态框,供商家编辑包含在配送区域中的您的方法的实例。
);
// 配送方法的其他初始化。
$this->init();
}
/**
* 额外的选项初始化,这些选项在构造函数中不需要进行初始化。
*
* @return void
*/
public function init() {
// 如果定义了任何设置,则在后台保存设置。(使用配送/设置 API)
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
// 初始化独立的设置,以及实例设置的表单字段。
$this->init_form_fields();
$this->init_instance_form_fields();
// 使用设置 API 获取已保存的选项,用于设置字段。
$this->title = $this->get_option( 'title' );
$this->tax_status = $this->get_option( 'tax_status' );
$this->cost = $this->get_option( 'cost' );
$this->type = $this->get_option( 'type', 'class' );
}
/**
* 计算配送成本。
*
* @param array $package 购物车中的商品包。
*/
public function calculate_shipping( $package = array() ) {
// 获取此实例的费率。
$rate = array(
'id' => $this->get_rate_id(), // 从配送 API 获取实例费率 ID。
'label' => $this->title,
'cost' => 0,
'package' => $package,
);
// 计算成本。
$has_costs = false; // 如果设置了成本,则为 true。如果所有成本为空字符串,则为 false。
$cost = $this->get_option( 'cost' );
// 如果设置了成本,则评估成本以确保其有效。
if ( '' !== $cost ) {
$has_costs = true;
$rate['cost'] = $cost;
}
// 统一费率配送具有为每个配送类型设置成本的能力,因此这里获取配送类型,并添加这些成本。
$shipping_classes = WC()->shipping()->get_shipping_classes();
if ( ! empty( $shipping_classes ) ) {
// 检查购物车/包中的产品是否已分配了配送类型。
$found_shipping_classes = $this->find_shipping_classes( $package );
$highest_class_cost = 0;
// 如果发现产品已分配了配送类型,则遍历每个配送类型。
foreach ( $found_shipping_classes as $shipping_class => $products ) {
// 同时也处理向后兼容性,当使用别名而不是 ID 时。
$shipping_class_term = get_term_by( 'slug', $shipping_class, 'product_shipping_class' );
$class_cost = $shipping_class_term && $shipping_class_term->term_id ? $this->get_option( 'class_cost_' . $shipping_class_term->term_id, $this->get_option( 'class_cost_' . $shipping_class, '' ) ) : $this->get_option( 'no_class_cost', '' );
// 如果未为配送类型分配成本,则跳到下一个类型。
if ( '' === $class_cost ) {
continue;
}
// 我们有一个配送类型成本,因此评估该类成本以确认其有效。
$has_costs = true;
统一费率计算逻辑
/**
- 统一费率有两种选项,当涉及到配送类型时,可以按配送类型计算,也可以按订单计算。
- 这里我们检查该设置,以便相应地应用成本。 */ if ( 'class' === $this->type ) { $rate['cost'] += $class_cost; } else { $highest_class_cost = $class_cost > $highest_class_cost ? $class_cost : $highest_class_cost; }
// 如果成本是按订单计算的,那么我们将最高的配送类型成本应用到基础成本上。 if ( 'order' === $this->type && $highest_class_cost ) { $rate['cost'] += $highest_class_cost; }
if ( $has_costs ) { $this->add_rate( $rate ); }
/**
- 开发者可以通过此操作钩子,基于此统一费率添加额外的费率,自 @version 2.4 起。
- 之前有一些(过于复杂)的选项可以添加额外的费率,但这些选项不方便用户使用,并且违背了统一费率配送的原始意图。 */ do_action( 'woocommerce_' . $this->id . '_shipping_add_rate', $this, $rate );
/**
-
查找并返回配送类型以及具有该配送类型的产品。
-
@param mixed $package 购物车中的商品包。
-
@return array */ public function find_shipping_classes( $package ) { $found_shipping_classes = array();
foreach ( $package['contents'] as $item_id => $values ) { if ( $values['data']->needs_shipping() ) { $found_class = $values['data']->get_shipping_class();
if ( ! isset( $found_shipping_classes[ $found_class ] ) ) {$found_shipping_classes[ $found_class ] = array();}$found_shipping_classes[ $found_class ][ $item_id ] = $values;}}
return $found_shipping_classes; }
/**
-
净化成本值。
-
此方法在
Settings API中调用sanitize_callback方法时被调用,用于保存商家输入的值。 -
@param string $value 未净化的值。
-
@return string
-
@throws Exception 如果成本不是数值。 */ public function sanitize_cost( $value ) { // 如果值为空,则将其设置为零。 将值通过 WordPress 核心的净化函数,然后移除货币符号,如果存在。 $value = is_null( $value ) ? '0' : $value; $value = wp_kses_post( trim( wp_unslash( $value ) ) ); $value = str_replace( array( get_woocommerce_currency_symbol(), html_entity_decode( get_woocommerce_currency_symbol() ) ), '', $value );
// 获取当前区域设置以及所有可能的十进制分隔符。 $locale = localeconv(); $decimals = array( wc_get_price_decimal_separator(), $locale['decimal_point'], $locale['mon_decimal_point'], ',' ); }
设置
本页面描述了如何配置插件的各种设置。
设置
- Settings → 设置
- Status → 状态
- String → 字符串
- Link → 链接
- Page → 网页
- API → API
- Tag → 标签
- Settings Page → 设置页面
- Placeholder → 占位符
- Form fields → 表单字段
- Percentage → 百分比
- characters → 字符
- Customers → 客户
- Flat Rate → 统一费率
- document → 文档
- Property → 属性
- Shipping → 配送
- Checkout → 结账
- Minimum → 最小
- Replace → 替换
// Remove whitespace, then decimals, and then invalid start/end characters.
$value = preg_replace( '/\s+/', '', $value );
$value = str_replace( $decimals, '.', $value );
$value = rtrim( ltrim( $value, "\t\n\r\0\x0B+*/" ), "\t\n\r\0\x0B+-*/" );
// If the value is not numeric, then throw an exception.
if ( ! is_numeric( $value ) ) {
throw new Exception( 'Invalid cost entered.' );
}
return $value;
}
/**
* Our method to initialize our form fields for our stand alone settings page, if needed.
*
* @return void
*/
public function init_form_fields() {
// Set the form_fields property to an array that will be able to be used by the Settings API to show the fields on the page.
$this->form_fields = array(
'title' => array(
'title' => __( 'Name', 'your_text_domain' ),
'type' => 'text',
'description' => __( 'Your customers will see the name of this shipping method during checkout.', 'your_text_domain' ),
'default' => __( 'Your shipping method', 'your_text_domain' ),
'placeholder' => __( 'e.g. Standard national', 'your_text_domain' ),
'desc_tip' => true, // Include this if you would like your description to show as a tooltip.
),
'tax_status' => array(
'title' => __( 'Tax status', 'your_text_domain' ),
'type' => 'select',
'class' => 'wc-enhanced-select',
'default' => 'taxable',
'options' => array(
'taxable' => __( 'Taxable', 'your_text_domain' ),
'none' => _x( 'None', 'Tax status', 'your_text_domain' ),
),
),
'cost' => array(
'title' => __( 'Cost', 'your_text_domain' ),
'type' => 'text',
'placeholder' => '',
'description' => __( 'Enter a cost (excl. tax).', 'your_text_domain' ),
'default' => '0',
'desc_tip' => true,
'sanitize_callback' => array( $this, 'sanitize_cost' ),
),
);
}
/**
* Our method to initialize our form fields for separate instances.
*
* @return void
*/
private function init_instance_form_fields() {
// Define some strings that will be used several times for the cost description and link.
$cost_desc = __( 'Enter a cost (excl. tax).', 'your_text_domain' );
$cost_link = sprintf( '<span id="wc-shipping-advanced-costs-help-text">%s <a target="_blank" href="https://woocommerce.com/document/flat-rate-shipping/#advanced-costs">%s</a>.</span>', __( 'Charge a flat rate per item, or enter a cost formula to charge a percentage based cost or a minimum fee. Learn more about', 'your_text_domain' ), __( 'advanced costs', 'your_text_domain' ) );
设置页面 允许您配置插件的各种选项。
- 名称 (Name): 名称 字段允许您为该配送方法设置一个名称。 您的客户将在结账过程中看到此名称。 占位符:例如,标准国内。
- 税收状态 (Tax status): 税收状态 字段允许您指定该配送方法是否应收取税费。
- 成本 (Cost): 成本 字段允许您输入一个统一费率。
您还可以使用链接访问更多信息。
统一费率配送设置
// 开始定义字段数组。
$fields = array(
'title' => array(
'title' => __( '名称', 'your_text_domain' ),
'type' => 'text',
'description' => __( '您的客户将在结账时看到此配送方式的名称。', 'your_text_domain' ),
'default' => __( '您的配送方式', 'your_text_domain' ),
'placeholder' => __( '例如:标准国内', 'your_text_domain' ),
'desc_tip' => true,
),
'tax_status' => array(
'title' => __( '税收状态', 'your_text_domain' ),
'type' => 'select',
'class' => 'wc-enhanced-select',
'default' => 'taxable',
'options' => array(
'taxable' => __( '应税', 'your_text_domain' ),
'none' => _x( '免税', '税收状态', 'your_text_domain' ),
),
),
'cost' => array(
'title' => __( '费用', 'your_text_domain' ),
'type' => 'text',
'class' => 'wc-shipping-modal-price',
'placeholder' => '',
'description' => $cost_desc,
'default' => '0',
'desc_tip' => true,
'sanitize_callback' => array( $this, 'sanitize_cost' ),
),
);
/**
* 统一费率配送可以按配送类型添加费用,因此这里获取配送类型,并提供字段供商家/管理员使用,以便他们可以指定这些费用。
*/
$shipping_classes = WC()->shipping()->get_shipping_classes();
if ( ! empty( $shipping_classes ) ) {
$fields['class_costs'] = array(
'title' => __( '按配送类型划分的费用', 'your_text_domain' ),
'type' => 'title',
'default' => '',
/* 译: %s: 链接的 URL */
'description' => sprintf( __( '这些费用可以选择性地根据 <a target="_blank" href="%s">产品的配送类型</a> 添加。 了解更多关于 <a target="_blank" href="https://woocommerce.com/document/flat-rate-shipping/#shipping-classes">设置配送类型费用</a> 的信息。', 'your_text_domain' ), admin_url( 'admin.php?page=wc-settings&tab=shipping§ion=classes' ) ),
);
foreach ( $shipping_classes as $shipping_class ) {
if ( ! isset( $shipping_class->term_id ) ) {
continue;
}
$fields[ 'class_cost_' . $shipping_class->term_id ] = array(
/* 译: %s: 配送类型名称 */
'title' => sprintf( __( '"%s" 配送类型的费用', 'your_text_domain' ), esc_html( $shipping_class->name ) ),
'type' => 'text',
'class' => 'wc-shipping-modal-price',
'placeholder' => __( 'N/A', 'your_text_domain' ),
'description' => $cost_desc,
'default' => $this->get_option( 'class_cost_' . $shipping_class->slug ),
'desc_tip' => true,
'sanitize_callback' => array( $this, 'sanitize_cost' ),
);
}
配送类型
设置
状态
链接
别名
网页
占位符
译:
类名
客户
统一费率
继续
document
配送
结账
部分
产品
字段
选择
# 配送类型配置
本页面允许您配置配送类型相关的设置。
**字段说明:**
* `no_class_cost`:
* `title`: "无配送类型费用"
* `type`: 文本
* `class`: `wc-shipping-modal-price`
* `placeholder`: "无"
* `description`: `$cost_desc`
* `default`: ""
* `desc_tip`: `true`
* `sanitize_callback`: `array( $this, 'sanitize_cost' )`
* `type`:
* `title`: "计算类型"
* `type`: `Select`
* `class`: `wc-enhanced-select`
* `default`: `class`
* `options`:
* `class`: "按配送类型:为每个配送类型单独收取配送费用"
* `order`: "按订单:为最贵的配送类型收取配送费用"
* `description`: `$cost_link`
**使用方法:**
1. 请根据您的需求配置各个`字段`。
2. `Select`框中,您可以`选择`合适的`选项`。
3. `Placeholder`占位符提示您输入内容。
**注意事项:**
* `API`接口可能需要特定的配置。
* `Property`的设置会影响`Shipping`的计算结果。
* 如果遇到问题,请参考`链接`中的文档。
* `Order`的计算方式会影响最终的费用。
* `Older`版本的插件可能存在兼容性问题。
* `Class`的定义决定了`Shipping`的分类。
* `and`操作符用于组合条件。
* `For`循环用于重复执行操作。
* `n/a`表示“无”。
* `Tan`表示“褐色”。
* `In`表示“在”。
* `No`表示“否”。
$fields['no_class_cost'] = array( 'title' => __( 'No shipping class cost', 'your_text_domain' ), 'type' => 'text', 'class' => 'wc-shipping-modal-price', 'placeholder' => __( 'N/A', 'your_text_domain' ), 'description' => $cost_desc, 'default' => '', 'desc_tip' => true, 'sanitize_callback' => array( $this, 'sanitize_cost' ), );
$fields['type'] = array(
'title' => __( 'Calculation type', 'your_text_domain' ),
'type' => 'select',
'class' => 'wc-enhanced-select',
'default' => 'class',
'options' => array(
'class' => __( 'Per class: Charge shipping for each shipping class individually', 'your_text_domain' ),
'order' => __( 'Per order: Charge shipping for the most expensive shipping class', 'your_text_domain' ),
),
'description' => $cost_link,
);
}
// And finally we set the instance_form_fields property for the Shipping API to use.
$this->instance_form_fields = $fields;
}
}
}
}