You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

咨询Nested Line Items的PHP代码层面进阶技术信息

Shopware 购物车捆绑包(Nested Line Items)PHP进阶实现指引

核心实现步骤

1. 定义自定义捆绑包订单项类型

直接基于官方的ContainerLineItem扩展,创建专属的捆绑包类型,便于后续识别和处理:

use Shopware\Core\Checkout\Cart\LineItem\ContainerLineItem;

class BundleLineItem extends ContainerLineItem
{
    public const TYPE = 'bundle';

    public function __construct(string $id, array $childLineItems = [])
    {
        parent::__construct(self::TYPE, $id);
        // 批量添加子产品项到捆绑包
        foreach ($childLineItems as $item) {
            $this->addChild($item);
        }
    }
}

2. 向购物车添加捆绑包

在业务服务或控制器中,创建捆绑包实例并关联子产品,再加入购物车:

use Shopware\Core\Checkout\Cart\Cart;
use Shopware\Core\Checkout\Cart\LineItem\ProductLineItem;

public function addBundleToCart(Cart $cart): void
{
    // 初始化子产品订单项
    $product1 = new ProductLineItem('prod-1', 'product', 'your-product-uuid-1', 1);
    $product2 = new ProductLineItem('prod-2', 'product', 'your-product-uuid-2', 1);

    // 创建捆绑包并设置显示名称
    $bundle = new BundleLineItem('custom-bundle-001', [$product1, $product2]);
    $bundle->setLabel('夏季护肤套装');

    // 将捆绑包加入购物车
    $cart->add($bundle);
}

3. 实现捆绑包整体移除逻辑

通过监听购物车变更事件,确保移除捆绑包时自动清理所有子项:

use Shopware\Core\Checkout\Cart\Event\CartChangedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class BundleCartSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            CartChangedEvent::class => 'handleBundleRemoval',
        ];
    }

    public function handleBundleRemoval(CartChangedEvent $event): void
    {
        $cart = $event->getCart();
        $removedLineItemIds = $cart->getLineItems()->getRemovedIds();

        foreach ($removedLineItemIds as $itemId) {
            $lineItem = $cart->getLineItems()->get($itemId);
            // 判断是否为自定义捆绑包类型
            if ($lineItem instanceof BundleLineItem) {
                // 遍历移除所有子项
                foreach ($lineItem->getChildren() as $childItem) {
                    $cart->getLineItems()->remove($childItem->getId());
                }
            }
        }
    }
}

4. 订单后台展示捆绑包结构

通过覆盖后台订单详情模板,实现捆绑包的分组展示:
在插件目录下创建src/Resources/views/admin/order/detail/index.html.twig,添加以下内容:

{% block sw_order_detail_items %}
    {% for lineItem in order.lineItems %}
        {% if lineItem.type == 'bundle' %}
            <div class="sw-order-detail-items__bundle-group">
                <h3 class="sw-order-detail-items__bundle-title">{{ lineItem.label }}</h3>
                {% for childItem in lineItem.children %}
                    <div class="sw-order-detail-items__bundle-child">
                        {{ childItem.label }} × {{ childItem.quantity }}
                    </div>
                {% endfor %}
            </div>
        {% else %}
            {{ parent() }}
        {% endif %}
    {% endfor %}
{% endblock %}

注:Shopware默认会持久化ContainerLineItem的子项关联,无需额外处理订单数据存储,只需调整前端展示逻辑即可。

5. 进阶优化点

  • 价格自定义:若需要捆绑包专属定价,可通过CartProcessor修改BundleLineItem的价格,将子项价格设为0避免重复计算
  • 库存逻辑:默认子产品库存单独扣减,若需捆绑包整体管控库存,需自定义StockUpdater实现
  • 前端交互:在Storefront购物车页面添加"移除整个捆绑包"按钮,触发对应ID的移除请求,配合后端逻辑完成操作

内容的提问来源于stack exchange,提问作者Jacky Raimond

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 02:42:54