在 Shopware 6 中导入期间如何替换不添加属性?

问题描述

我们使用的是 Shopware 6.3.5,希望在产品导入(更新)过程中替换属性。

我们指定产品 ID 和列表或属性 UUID(在 properties 列中)

目前,这些被添加到数据库中的现有属性中。

这似乎是由于导入过程中 upsert 调用的行为所致。

如何改变这种情况?

我们试过这个:

DI:

<argument type="service" id="product.repository"/>

方法:

class ImportSubscriber implements EventSubscriberInterface
{
    private EntityRepositoryInterface $productRepository;

    public function __construct(EntityRepositoryInterface $productRepository)
    {
        $this->productRepository = $productRepository;
    }

    public static function getSubscribedEvents(): array
    {
        return [
            ImportExportBeforeImportRecordEvent::class => 'onImportExportBeforeImportRecord'
        ];
    }

    public function onImportExportBeforeImportRecord(ImportExportBeforeImportRecordEvent $event)
    {
        $this->productRepository->update([
            [
                'id' => $event->getRecord()['id'],'property_ids' => null,]
        ],$event->getContext());
    }
}

但是这个更新语句会导致 \Shopware\Core\Framework\DataAbstractionLayer\Write\Command\WriteTypeIntendException 中的 \Shopware\Core\Framework\DataAbstractionLayer\Write\Command\WriteCommandQueue::ensureIs

我还想知道这个 WriteCommandQueue 是做什么的,如果它的级别太低,我想要做什么?

此外,我想知道 property_ids 是否是要更改的正确字段,还是实际上我必须清除该导入行的 product_property 表?

编辑

接下来我尝试了这个

DI:

<argument type="service" id="product_property.repository"/>

方法:

    public function onImportExportBeforeImportRecord(ImportExportBeforeImportRecordEvent $event)
    {
        $existing = $this->productPropertryRepository->search(
            (new Criteria())->addFilter(new EqualsFilter('productId',$event->getRecord()['id'])),$event->getContext()
        );
        $entities = $existing->getEntities();
        foreach($entities as $entity) {
            $this->productPropertryRepository->delete([
                [
                    'productId' => $event->getRecord()['id'],'optionId' => $entity->get('optionId')
                ]
            ],$event->getContext());
        }
    }

但是我得到了一个

Shopware\Core\Framework\DataAbstractionLayer\Exception\MappingEntityClassesException

Mapping definition neither have entities nor collection.

解决方法

搜索方法不适用于映射定义。您可以使用 searchIds 获取 ID 并像您一样调用删除。

,

基于@Shyim 的回答,这是有效的:

    public function onImportExportBeforeImportRecord(ImportExportBeforeImportRecordEvent $event)
    {
        $existing = $this->productPropertyRepository->searchIds(
            (new Criteria())->addFilter(new EqualsFilter('productId',$event->getRecord()['id'])),$event->getContext()
        );

        foreach($existing->getIds() as $id) {
            if (in_array($id['property_group_option_id'],($event->getRecord()['properties'] ?? [] ))) {
                continue;
            }

            $this->productPropertyRepository->delete([
                [
                    'productId' => $event->getRecord()['id'],'optionId' => $id['property_group_option_id']
                ]
            ],$event->getContext());
        }
    }

注意:这会删除所有当前属性,更复杂的解决方案可能是仅删除特定属性(例如通过在导入中提供名称列表),或者使用包含应清除或保留的属性的正/负列表。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...