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

Posted

技术标签:

【中文标题】如何在 Shopware 6 中导入期间替换(不添加)属性?【英文标题】:How to replace (not add) properties during Import in Shopware 6? 【发布时间】:2021-08-07 18:34:20 【问题描述】:

我们正在使用 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\WriteCommandQueue::ensureIs中的\Shopware\Core\Framework\DataAbstractionLayer\Write\Command\WriteTypeIntendException

我也想知道这个 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.

【问题讨论】:

【参考方案1】:

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

【讨论】:

【参考方案2】:

根据@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());
        
    

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

【讨论】:

以上是关于如何在 Shopware 6 中导入期间替换(不添加)属性?的主要内容,如果未能解决你的问题,请参考以下文章

在 Shopware 6 中通过 php 创建媒体

Shopware 6 如何在scss中使用配置好的主题原色?

Shopware 6 - 如何在 SW6 的插件系统配置中添加按钮组件

如何在 Shopware 6 中创建 SEO 网址

Shopware 6 如何在监视脚本期间禁用 ESLint?

Shopware 6:如何删除所有演示数据