phpimportshopwaredbal

How to replace (not add) properties during Import in Shopware 6?


We are using Shopware 6.3.5 and want to replace properties during import (update) of products.

We specifiy to product ID and the list or property UUIDs (in the column properties)

Currently, those get added to the existing properties in the database.

This seems to be due to the behavior of the upsert call during the import.

How can this be changed?

We tried this:

DI:

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

Method:

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());
    }
}

But this update statement causes a \Shopware\Core\Framework\DataAbstractionLayer\Write\Command\WriteTypeIntendException in \Shopware\Core\Framework\DataAbstractionLayer\Write\Command\WriteCommandQueue::ensureIs

I am also wondering what this WriteCommandQueue does and if it is too lower level what I am trying to do?

Additionally I am wondering if property_ids is the right field to change or actually I have to clear up the product_property table for that import row?

EDIT

Next I tried this

DI:

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

Method:

    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());
        }
    }

But I get a

Shopware\Core\Framework\DataAbstractionLayer\Exception\MappingEntityClassesException with

Mapping definition neither have entities nor collection.


Solution

  • The search method does not work on Mapping Definitions. You can use searchIds to get the ids and call the delete like you have.