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

如何在Shopware 6中为Cart添加关联字段关联自定义Shop实体

解决Shopware 6购物车关联自定义Shop实体的问题

Shopware 6的购物车(Cart)并非传统的实体结构,无法直接通过EntityExtension扩展,得用购物车专属的扩展机制,具体步骤如下:

1. 创建购物车扩展类

定义一个继承自CartExtension的类,用来存储自定义Shop实体的关联信息:

<?php

namespace YourPlugin\Core\Checkout\Cart;

use Shopware\Core\Checkout\Cart\CartExtension;
use YourPlugin\Core\Content\Shop\ShopEntity;

class ShopCartExtension extends CartExtension
{
    protected ?ShopEntity $shop = null;

    public function getShop(): ?ShopEntity
    {
        return $this->shop;
    }

    public function setShop(?ShopEntity $shop): void
    {
        $this->shop = $shop;
    }

    // 返回扩展的唯一标识,需全局唯一
    public function getName(): string
    {
        return 'your_shop_extension';
    }
}

2. 扩展购物车持久化逻辑

要让关联的Shop实体数据随购物车一起保存、读取,需要装饰CartPersister:

2.1 编写CartPersister装饰器

<?php

namespace YourPlugin\Core\Checkout\Cart;

use Shopware\Core\Checkout\Cart\Cart;
use Shopware\Core\Checkout\Cart\CartPersisterInterface;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;

class ShopCartPersisterDecorator implements CartPersisterInterface
{
    private CartPersisterInterface $originalPersister;
    private EntityRepository $shopRepository;

    public function __construct(CartPersisterInterface $originalPersister, EntityRepository $shopRepository)
    {
        $this->originalPersister = $originalPersister;
        $this->shopRepository = $shopRepository;
    }

    public function save(Cart $cart, Context $context): void
    {
        // 先保存原始购物车数据
        $this->originalPersister->save($cart, $context);
        
        // 提取扩展并将关联的shopId存入购物车自定义字段
        $extension = $cart->getExtension('your_shop_extension');
        if ($extension instanceof ShopCartExtension && $extension->getShop()) {
            $cart->setCustomField('linked_shop_id', $extension->getShop()->getId());
            $this->originalPersister->save($cart, $context);
        }
    }

    public function load(string $token, Context $context): Cart
    {
        $cart = $this->originalPersister->load($token, $context);
        
        // 从自定义字段读取shopId,加载关联实体并添加到购物车扩展
        $shopId = $cart->getCustomField('linked_shop_id');
        if ($shopId) {
            $criteria = new Criteria([$shopId]);
            $shop = $this->shopRepository->search($criteria, $context)->first();
            
            if ($shop) {
                $extension = new ShopCartExtension();
                $extension->setShop($shop);
                $cart->addExtension('your_shop_extension', $extension);
            }
        }
        
        return $cart;
    }

    public function delete(string $token, Context $context): void
    {
        $this->originalPersister->delete($token, $context);
    }

    public function merge(string $fromToken, string $toToken, Context $context): void
    {
        $this->originalPersister->merge($fromToken, $toToken, $context);
        
        // 合并购物车时,可根据业务需求保留来源购物车的Shop关联
        $fromCart = $this->load($fromToken, $context);
        $fromExtension = $fromCart->getExtension('your_shop_extension');
        
        if ($fromExtension instanceof ShopCartExtension && $fromExtension->getShop()) {
            $toCart = $this->load($toToken, $context);
            $toCart->addExtension('your_shop_extension', $fromExtension);
            $this->save($toCart, $context);
        }
    }
}

2.2 注册装饰器

在插件的services.xml中注册这个装饰器,替换成你的自定义Shop实体仓库ID:

<service id="YourPlugin\Core\Checkout\Cart\ShopCartPersisterDecorator" decorates="Shopware\Core\Checkout\Cart\CartPersister">
    <argument type="service" id="Shopware\Core\Checkout\Cart\CartPersister" />
    <argument type="service" id="your_plugin.shop.repository" />
</service>

3. 业务逻辑中使用扩展

在控制器、订阅器等场景中,给购物车关联Shop实体:

// 获取当前购物车
$cart = $this->cartService->getCart($context->getSource()->getToken(), $context);

// 加载目标Shop实体
$shop = $this->shopRepository->search(new Criteria(['your-target-shop-id']), $context)->first();

// 添加扩展到购物车
$extension = new ShopCartExtension();
$extension->setShop($shop);
$cart->addExtension('your_shop_extension', $extension);

// 保存购物车
$this->cartPersister->save($cart, $context);

补充说明

  • 如果需要更规范的关联关系,也可以自定义cart_shop关联表,编写对应的EntityDefinition和Migration来维护数据
  • 若要在前端展示关联的Shop信息,可通过扩展购物车API响应,将关联字段添加到API返回结构中

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 19:05:43