如何在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
相关产品推荐
相关产品推荐

