如何覆盖final类声明的PrestaShop服务?以CarrierForOrderChoiceProvider为例
PrestaShop中final服务类的覆盖方案选择
问题背景
PrestaShop 1.7.3引入了服务覆盖功能,但对于被声明为final的服务类(比如CarrierForOrderChoiceProvider),无法通过常规方式进行覆盖。
实际业务场景中,部分订单来自亚马逊等第三方购物车,这类订单在PrestaShop数据库中没有对应的Cart对象。而CarrierForOrderChoiceProvider服务依赖Cart对象获取id_address_delivery、id_customer等数据,导致第三方来源的订单因无关联Cart对象,出现Carrier列表为空的问题。
当前可行的代码修改方案是将原逻辑:
$cart = Cart::getCartByOrderId($options['order_id']); $groups = Customer::getGroupsStatic((int) $cart->id_customer); $address = new Address((int) $cart->id_address_delivery);
替换为:
$order = new Order((int)$options['order_id']); $groups = Customer::getGroupsStatic((int) $order->id_customer); $address = new Address((int) $order->id_address_delivery);
方案对比与选择
方案1:提交PR仅移除final关键字
该方案仅解除类的final限制,允许商家通过模块自行覆盖服务以适配特定场景。
- 优点:不对核心业务逻辑做修改,保留官方原有逻辑的完整性,给商家提供自定义扩展的灵活性。
- 缺点:仅解决了覆盖的可能性,未直接修复第三方订单的问题,商家需自行开发模块实现适配,增加使用成本。
方案2:提交PR替换为依赖Order对象的逻辑
该方案直接修改核心逻辑,从Order对象获取所需数据,从根源上解决第三方订单无Cart对象导致的Carrier列表为空问题。
- 优点:直接修复实际业务问题,所有商家均可受益,无需额外开发模块。
- 缺点:修改了核心业务逻辑,需确保
Order对象始终包含所需的id_customer和id_address_delivery字段,要考虑旧版本数据或异常订单的兼容性问题。
结论
优先选择方案2。该方案直接解决了实际存在的业务痛点,让所有有第三方订单接入需求的商家直接受益,无需额外开发。提交方案2的PR时,建议增加兼容性判断:如果能通过订单获取到Cart对象则优先使用,否则再从Order对象取数据,进一步提升逻辑的健壮性。
内容的提问来源于stack exchange,提问作者Adib Aroui
相关产品推荐
相关产品推荐

