如何让WooCommerce配送扩展按区域而非国家限制可用范围
解决方案
WooCommerce 原生WC_Shipping_Method类仅内置国家级别的可用性限制,直接给$this->states赋值不会生效,因为该类本身没有识别这个属性的逻辑。你可以通过重写配送类的is_available方法实现自定义粒度的可用性校验,对站点其他配送方式无任何影响。
第一步:修改构造函数,定义允许的区域列表
在原构造函数中新增允许的省/州配置,其他原有逻辑保持不变:
public function __construct() { $this->id = 'tiki_lite'; $this->method_title = __('Tiki Local Delivery'); $this->method_description = __('Custom local delivery method for Tiki Lite'); // 原有国家限制配置 $this->availability = 'including'; $this->countries = array( 'ZA', 'ES', 'US', 'GB' ); // 新增允许的省/州配置,格式:国家代码 => 允许的州代码数组 $this->allowed_states = [ 'ZA' => ['GP'], // 南非仅允许豪登省 // 可按需添加其他国家的允许州 'US' => ['CA', 'NY'] // 示例:美国仅允许加利福尼亚州、纽约州 ]; // 可继续新增允许的城市、邮政编码等配置,按需扩展 $this->allowed_cities = [ 'ZA' => [ 'GP' => ['约翰内斯堡', '比勒陀利亚'] ] ]; $this->init(); $this->enabled = isset($this->settings['enabled']) ? $this->settings['enabled'] : 'yes'; $this->title = isset($this->settings['title']) ? $this->settings['title'] : __('Tiki Local Delivery', 'tiki_lite'); }
第二步:重写is_available方法,添加自定义校验逻辑
在你的配送类中新增以下方法,优先级高于原生校验,会自动在计算配送选项时触发:
public function is_available( $package ) { // 先执行原生国家校验,国家不符合直接返回不可用 if ( ! parent::is_available( $package ) ) { return false; } // 获取用户收货地址的国家、州代码 $shipping_country = $package['destination']['country']; $shipping_state = $package['destination']['state']; // 校验省/州:如果当前国家配置了允许的州列表,就校验州是否在允许范围内 if ( isset( $this->allowed_states[ $shipping_country ] ) ) { if ( ! in_array( $shipping_state, $this->allowed_states[ $shipping_country ] ) ) { return false; } } // 按需扩展:城市校验 $shipping_city = $package['destination']['city']; if ( isset( $this->allowed_cities[ $shipping_country ][ $shipping_state ] ) ) { if ( ! in_array( $shipping_city, $this->allowed_cities[ $shipping_country ][ $shipping_state ] ) ) { return false; } } // 按需扩展:邮政编码、配送分区校验逻辑也可在此处添加 // 所有校验都通过则返回可用 return true; }
逻辑说明
- 所有校验仅作用于你开发的
tiki_lite配送方式,不会影响站点其他配送功能、也不会修改全局的省/州列表 - 可根据业务需求灵活扩展校验维度,包括邮政编码、自定义配送分区等,所有用户收货地址信息都可以从
$package['destination']数组中获取 - 如果后续需要让管理员可以在后台配置允许的省/州,只需要在
init_form_fields方法中添加对应配置项,把上面硬编码的allowed_states替换成从配置中读取即可。
内容的提问来源于stack exchange,提问作者Wylie
相关产品推荐
相关产品推荐

