Shopware 6:能否在商品Upsert时同步Upsert媒体文件?
商品Upsert时同步媒体文件的实现方案
能否在商品Upsert操作时同步Upsert媒体文件?可以是同一请求中的独立载荷,也可以直接通过商品Upsert实现?我们有大约10000个带图片的商品需要同步,最优策略是仅在商品创建时更新图片(通常图片不会变更),且支持批量处理(如一次处理100个商品)。目前使用
/vienthuong/shopware-php-sdk实现了商品Upsert,但尝试添加cover属性直接设置URL无法生效。
核心实现思路
Shopware同步机制支持同一请求内同时处理商品与媒体文件关联,需按以下顺序执行:
- 先Upsert媒体文件(已存在则跳过,不存在则创建)
- 在商品数据中关联已创建的媒体文件ID
- 通过同步操作的依赖关系确保媒体操作优先完成
具体代码实现
1. 单商品同步示例
在同一个SyncPayload中添加媒体和商品两个同步操作,通过依赖设置保证执行顺序:
$syncService = new SyncService($this->context); $payload = new SyncPayload(); // 1. Upsert媒体文件 $payload->set('media-upsert', new SyncOperator( MediaDefinition::ENTITY_NAME, SyncOperator::UPSERT_OPERATOR, [ [ 'id' => 'media-cover-001', // 自定义唯一媒体ID,用于后续关联 'url' => 'https://image.shutterstock.com/image-photo/stock-photo-woman-with-static-electric-hair-isolated-on-black-background-250nw-2014152446.jpg', 'fileName' => 'product-cover.jpg', 'mimeType' => 'image/jpeg' ] ] )); // 2. Upsert商品并关联封面媒体 $payload->set('product-upsert', new SyncOperator( ProductDefinition::ENTITY_NAME, SyncOperator::UPSERT_OPERATOR, [ [ 'id' => '018cf59aa9d870008000fbc39f0fcef2', 'name' => 'New Product', 'taxId' => '018de63f1b61715aad18389bfaddf6ba', 'price' => [ [ 'currencyId' => 'b7d2554b0ce847cd82f3ac9bd1c0dfca', 'linked' => true, 'gross' => 999.99, 'net' => (999.99 / 1.19), ], ], 'productNumber' => 'FRE832672', 'stock' => 2, // 关联已创建的媒体文件作为封面 'cover' => [ 'mediaId' => 'media-cover-001' ] ] ], // 设置依赖:商品操作需等待媒体操作完成 ['media-upsert'] )); $response = $syncService->sync($payload); var_dump($response);
2. 批量处理优化(一次100个商品)
- 批量生成媒体条目:为每个商品分配唯一媒体ID,一次性添加到
media-upsert操作中 - 批量生成商品条目:每个商品对应关联自身的媒体ID
- 保持依赖关系,确保媒体操作优先执行
- 注意:控制单请求批量数量在100以内,避免触发API载荷上限导致超时
3. 仅创建时同步图片的逻辑
通过判断商品是否存在来控制媒体同步:
- 先调用
ProductDefinition的read方法查询商品ID是否存在 - 若不存在(创建场景):添加媒体操作+商品关联逻辑
- 若已存在(更新场景):仅更新商品基础字段,跳过媒体相关操作
直接设置cover.url无效的原因
Shopware商品的cover字段要求关联已存在的媒体实体,无法直接通过URL自动创建媒体文件。必须先完成媒体实体的Upsert,再通过mediaId关联到商品封面。
内容的提问来源于stack exchange,提问作者Martin Müller
相关产品推荐
相关产品推荐

