EqualsFilter для активного продукта не учитывает наследование

#shopware

#shopware

Вопрос:

Я пытаюсь извлечь продукты из репозитория, которые являются активными. Однако некоторые варианты наследуют статус active от своего родителя, что означает, что они имеют active = NULL в таблице product DB.

EqualsFilter приведет к следующему запросу, не извлекая варианты, наследующие активный статус:

 SELECT `product`.`id` FROM `product` WHERE (`product`.`version_id` = :version) AND `product`.`active` = true
 

Как правильно фильтровать активные продукты?
Это мой текущий код:

 $criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('active', true));
$this->productRepository->search($criteria, Context::createDefaultContext());
 

Это работает, но похоже на ошибку, из-за которой нужно проделать такую большую работу.

             $criteria->addFilter(
            new MultiFilter(
                MultiFilter::CONNECTION_OR,
                [
                    new EqualsFilter('active', true),
                    new MultiFilter(
                        MultiFilter::CONNECTION_AND,
                        [
                            new EqualsFilter('active', null),
                            new EqualsFilter('parent.active', true)
                        ]
                    )
                ]
            )
        );
 

Приведет к этому запросу:

 SELECT `product`.`id` FROM `product` LEFT JOIN `product` `product.parent` ON `product`.`parent_id` = `product.parent`.`id` AND `product`.`version_id` = `product.parent`.`version_id` WHERE (`product`.`version_id` = :version) AND (`product`.`active` = true OR (`product`.`active` IS NULL AND `product.parent`.`active` = true))
 

Обновить

Таким образом, кажется, что если кто-то предоставляет SalesChannelContext, а не контекст по умолчанию, он работает, и запрос равен последнему. В чем причина этого и есть ли обходной путь, когда у вас нет контекста канала продаж?

Ответ №1:

ShopwareCoreFrameworkContext Имеет considerInheritance -флаг. Этот флаг управляет именно тем поведением, которое вы описываете.

По умолчанию для этого флага установлено значение false . Это связано с тем, что при использовании admin-api у вас нет другого способа узнать, поступает ли конкретное значение свойства непосредственно из имеющегося продукта или его родительского. Этот механизм в основном используется в администрировании, где всегда будет выбираться родительский продукт, чтобы различать унаследованные и ненаследованные свойства.

При загрузке продукта через витрину considerInheritance магазина флаг -всегда равен that to true , потому что мы не хотим дополнительно извлекать родительский продукт.

Если вы хотите изменить это поведение, вы можете использовать setConsiderInheritance() метод Контекста. Тогда ваш пример кода будет выглядеть следующим образом:

 $criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('active', true));

$context = Context::createDefaultContext();
$context->setConsiderInheritance(true);

$this->productRepository->search($criteria, $context);
 

Имейте в виду, что в целом вам следует стараться не использовать createDefaultContext() -метод, обратитесь к этой проблеме GitHub для подробного объяснения.